diff --git a/memory/build/malloc_decls.h b/memory/build/malloc_decls.h index a82f4a133996..8683e9e8e4cd 100644 --- a/memory/build/malloc_decls.h +++ b/memory/build/malloc_decls.h @@ -4,13 +4,11 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -/* - * Helper header to declare all the supported malloc functions. - * MALLOC_DECL arguments are: - * - function name - * - return type - * - argument types - */ +// Helper header to declare all the supported malloc functions. +// MALLOC_DECL arguments are: +// - function name +// - return type +// - argument types #ifndef malloc_decls_h # define malloc_decls_h @@ -32,7 +30,7 @@ MALLOC_FUNCS_MALLOC | MALLOC_FUNCS_JEMALLOC | \ MALLOC_FUNCS_ARENA) -#endif /* malloc_decls_h */ +#endif // malloc_decls_h #ifndef MALLOC_FUNCS # define MALLOC_FUNCS (MALLOC_FUNCS_MALLOC | MALLOC_FUNCS_JEMALLOC | \ @@ -62,77 +60,65 @@ MALLOC_DECL(malloc_good_size, size_t, size_t) # endif # if MALLOC_FUNCS & MALLOC_FUNCS_JEMALLOC MALLOC_DECL(jemalloc_stats, void, jemalloc_stats_t *) -/* - * On some operating systems (Mac), we use madvise(MADV_FREE) to hand pages - * back to the operating system. On Mac, the operating system doesn't take - * this memory back immediately; instead, the OS takes it back only when the - * machine is running out of physical memory. - * - * This is great from the standpoint of efficiency, but it makes measuring our - * actual RSS difficult, because pages which we've MADV_FREE'd shouldn't count - * against our RSS. - * - * This function explicitly purges any MADV_FREE'd pages from physical memory, - * causing our reported RSS match the amount of memory we're actually using. - * - * Note that this call is expensive in two ways. First, it may be slow to - * execute, because it may make a number of slow syscalls to free memory. This - * function holds the big jemalloc locks, so basically all threads are blocked - * while this function runs. - * - * This function is also expensive in that the next time we go to access a page - * which we've just explicitly decommitted, the operating system has to attach - * to it a physical page! If we hadn't run this function, the OS would have - * less work to do. - * - * If MALLOC_DOUBLE_PURGE is not defined, this function does nothing. - */ + +// On some operating systems (Mac), we use madvise(MADV_FREE) to hand pages +// back to the operating system. On Mac, the operating system doesn't take +// this memory back immediately; instead, the OS takes it back only when the +// machine is running out of physical memory. +// +// This is great from the standpoint of efficiency, but it makes measuring our +// actual RSS difficult, because pages which we've MADV_FREE'd shouldn't count +// against our RSS. +// +// This function explicitly purges any MADV_FREE'd pages from physical memory, +// causing our reported RSS match the amount of memory we're actually using. +// +// Note that this call is expensive in two ways. First, it may be slow to +// execute, because it may make a number of slow syscalls to free memory. This +// function holds the big jemalloc locks, so basically all threads are blocked +// while this function runs. +// +// This function is also expensive in that the next time we go to access a page +// which we've just explicitly decommitted, the operating system has to attach +// to it a physical page! If we hadn't run this function, the OS would have +// less work to do. +// +// If MALLOC_DOUBLE_PURGE is not defined, this function does nothing. MALLOC_DECL(jemalloc_purge_freed_pages, void) -/* - * Free all unused dirty pages in all arenas. Calling this function will slow - * down subsequent allocations so it is recommended to use it only when - * memory needs to be reclaimed at all costs (see bug 805855). This function - * provides functionality similar to mallctl("arenas.purge") in jemalloc 3. - */ +// Free all unused dirty pages in all arenas. Calling this function will slow +// down subsequent allocations so it is recommended to use it only when +// memory needs to be reclaimed at all costs (see bug 805855). This function +// provides functionality similar to mallctl("arenas.purge") in jemalloc 3. MALLOC_DECL(jemalloc_free_dirty_pages, void) -/* - * Opt in or out of a thread local arena (bool argument is whether to opt-in - * (true) or out (false)). - */ +// Opt in or out of a thread local arena (bool argument is whether to opt-in +// (true) or out (false)). MALLOC_DECL(jemalloc_thread_local_arena, void, bool) -/* - * Provide information about any allocation enclosing the given address. - */ +// Provide information about any allocation enclosing the given address. MALLOC_DECL(jemalloc_ptr_info, void, const void*, jemalloc_ptr_info_t*) # endif # if MALLOC_FUNCS & MALLOC_FUNCS_ARENA_BASE -/* - * Creates a separate arena, and returns its id, valid to use with moz_arena_* - * functions. - */ + +// Creates a separate arena, and returns its id, valid to use with moz_arena_* +// functions. MALLOC_DECL(moz_create_arena, arena_id_t) -/* - * Dispose of the given arena. Subsequent uses of the arena will fail. - */ +// Dispose of the given arena. Subsequent uses of the arena will fail. MALLOC_DECL(moz_dispose_arena, void, arena_id_t) # endif # if MALLOC_FUNCS & MALLOC_FUNCS_ARENA_ALLOC -/* - * Same as the functions without the moz_arena_ prefix, but using arenas - * created with moz_create_arena. - * The contract, even if not enforced at runtime in some configurations, - * is that moz_arena_realloc and moz_arena_free will crash if the wrong - * arena id is given. All functions will crash if the arena id is invalid. - * Although discouraged, plain realloc and free can still be used on - * pointers allocated with these functions. Realloc will properly keep - * new pointers in the same arena as the original. - */ +// Same as the functions without the moz_arena_ prefix, but using arenas +// created with moz_create_arena. +// The contract, even if not enforced at runtime in some configurations, +// is that moz_arena_realloc and moz_arena_free will crash if the wrong +// arena id is given. All functions will crash if the arena id is invalid. +// Although discouraged, plain realloc and free can still be used on +// pointers allocated with these functions. Realloc will properly keep +// new pointers in the same arena as the original. MALLOC_DECL(moz_arena_malloc, void*, arena_id_t, size_t) MALLOC_DECL(moz_arena_calloc, void*, arena_id_t, size_t, size_t) MALLOC_DECL(moz_arena_realloc, void*, arena_id_t, void*, size_t) @@ -140,7 +126,7 @@ MALLOC_DECL(moz_arena_free, void, arena_id_t, void*) MALLOC_DECL(moz_arena_memalign, void*, arena_id_t, size_t, size_t) # endif -#endif /* MALLOC_DECL */ +#endif // MALLOC_DECL #undef MALLOC_DECL #undef MALLOC_FUNCS diff --git a/memory/build/mozjemalloc.h b/memory/build/mozjemalloc.h index b592f43eddb7..7574dc94b073 100644 --- a/memory/build/mozjemalloc.h +++ b/memory/build/mozjemalloc.h @@ -10,10 +10,10 @@ #include "mozjemalloc_types.h" #include "mozilla/MacroArgs.h" -/* Macro helpers */ +// Macro helpers #define MACRO_CALL(a, b) a b -/* Can't use macros recursively, so we need another one doing the same as above. */ +// Can't use macros recursively, so we need another one doing the same as above. #define MACRO_CALL2(a, b) a b #define ARGS_HELPER(name, ...) MACRO_CALL2( \ @@ -31,10 +31,9 @@ #ifdef MOZ_MEMORY -/* Generic interface exposing the whole public allocator API - * This facilitates the implementation of things like replace-malloc. - * Note: compilers are expected to be able to optimize out `this`. - */ +// Generic interface exposing the whole public allocator API +// This facilitates the implementation of things like replace-malloc. +// Note: compilers are expected to be able to optimize out `this`. template struct Allocator: public T { #define MALLOC_DECL(name, return_type, ...) \ @@ -42,12 +41,12 @@ struct Allocator: public T { #include "malloc_decls.h" }; -/* The MozJemalloc allocator */ +// The MozJemalloc allocator struct MozJemallocBase {}; typedef Allocator MozJemalloc; #ifdef MOZ_REPLACE_MALLOC -/* The replace-malloc allocator */ +// The replace-malloc allocator struct ReplaceMallocBase {}; typedef Allocator ReplaceMalloc; @@ -56,10 +55,10 @@ typedef ReplaceMalloc DefaultMalloc; typedef MozJemalloc DefaultMalloc; #endif -#endif /* MOZ_MEMORY */ +#endif // MOZ_MEMORY -/* Dummy implementation of the moz_arena_* API, falling back to a given - * implementation of the base allocator. */ +// Dummy implementation of the moz_arena_* API, falling back to a given +// implementation of the base allocator. template struct DummyArenaAllocator { static arena_id_t moz_create_arena(void) { return 0; } diff --git a/memory/build/mozjemalloc_types.h b/memory/build/mozjemalloc_types.h index 4f9447857974..2b4b84733797 100644 --- a/memory/build/mozjemalloc_types.h +++ b/memory/build/mozjemalloc_types.h @@ -4,40 +4,39 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -/* Portions of this file were originally under the following license: - * - * Copyright (C) 2006-2008 Jason Evans . - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice(s), this list of conditions and the following disclaimer as - * the first lines of this file unmodified other than the possible - * addition of one or more copyright notices. - * 2. Redistributions in binary form must reproduce the above copyright - * notice(s), this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ +// Portions of this file were originally under the following license: +// +// Copyright (C) 2006-2008 Jason Evans . +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// 1. Redistributions of source code must retain the above copyright +// notice(s), this list of conditions and the following disclaimer as +// the first lines of this file unmodified other than the possible +// addition of one or more copyright notices. +// 2. Redistributions in binary form must reproduce the above copyright +// notice(s), this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the +// distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef _JEMALLOC_TYPES_H_ #define _JEMALLOC_TYPES_H_ -/* grab size_t */ +// grab size_t #ifdef _MSC_VER #include #else @@ -57,38 +56,32 @@ typedef MALLOC_USABLE_SIZE_CONST_PTR void* usable_ptr_t; typedef size_t arena_id_t; -/* - * jemalloc_stats() is not a stable interface. When using jemalloc_stats_t, be - * sure that the compiled results of jemalloc.c are in sync with this header - * file. - */ +// jemalloc_stats() is not a stable interface. When using jemalloc_stats_t, be +// sure that the compiled results of jemalloc.c are in sync with this header +// file. typedef struct { - /* - * Run-time configuration settings. - */ - bool opt_junk; /* Fill allocated memory with kAllocJunk? */ - bool opt_zero; /* Fill allocated memory with 0x0? */ - size_t narenas; /* Number of arenas. */ - size_t quantum; /* Allocation quantum. */ - size_t small_max; /* Max quantum-spaced allocation size. */ - size_t large_max; /* Max sub-chunksize allocation size. */ - size_t chunksize; /* Size of each virtual memory mapping. */ - size_t page_size; /* Size of pages. */ - size_t dirty_max; /* Max dirty pages per arena. */ + // Run-time configuration settings. + bool opt_junk; // Fill allocated memory with kAllocJunk? + bool opt_zero; // Fill allocated memory with 0x0? + size_t narenas; // Number of arenas. + size_t quantum; // Allocation quantum. + size_t small_max; // Max quantum-spaced allocation size. + size_t large_max; // Max sub-chunksize allocation size. + size_t chunksize; // Size of each virtual memory mapping. + size_t page_size; // Size of pages. + size_t dirty_max; // Max dirty pages per arena. - /* - * Current memory usage statistics. - */ - size_t mapped; /* Bytes mapped (not necessarily committed). */ - size_t allocated; /* Bytes allocated (committed, in use by application). */ - size_t waste; /* Bytes committed, not in use by the - application, and not intentionally left - unused (i.e., not dirty). */ - size_t page_cache; /* Committed, unused pages kept around as a - cache. (jemalloc calls these "dirty".) */ - size_t bookkeeping; /* Committed bytes used internally by the - allocator. */ - size_t bin_unused; /* Bytes committed to a bin but currently unused. */ + // Current memory usage statistics. + size_t mapped; // Bytes mapped (not necessarily committed). + size_t allocated; // Bytes allocated (committed, in use by application). + size_t waste; // Bytes committed, not in use by the + // application, and not intentionally left + // unused (i.e., not dirty). + size_t page_cache; // Committed, unused pages kept around as a + // cache. (jemalloc calls these "dirty".) + size_t bookkeeping; // Committed bytes used internally by the + // allocator. + size_t bin_unused; // Bytes committed to a bin but currently unused. } jemalloc_stats_t; enum PtrInfoTag { @@ -115,13 +108,11 @@ enum PtrInfoTag { TagFreedPageZeroed, }; -/* - * The information in jemalloc_ptr_info_t could be represented in a variety of - * ways. The chosen representation has the following properties. - * - The number of fields is minimized. - * - The 'tag' field unambiguously defines the meaning of the subsequent fields. - * Helper functions are used to group together related categories of tags. - */ +// The information in jemalloc_ptr_info_t could be represented in a variety of +// ways. The chosen representation has the following properties. +// - The number of fields is minimized. +// - The 'tag' field unambiguously defines the meaning of the subsequent fields. +// Helper functions are used to group together related categories of tags. typedef struct { enum PtrInfoTag tag; void* addr; // meaning depends on tag; see above @@ -156,7 +147,7 @@ jemalloc_ptr_is_freed_page(jemalloc_ptr_info_t* info) } #ifdef __cplusplus -} /* extern "C" */ +} // extern "C" #endif -#endif /* _JEMALLOC_TYPES_H_ */ +#endif // _JEMALLOC_TYPES_H_ diff --git a/memory/build/mozmemory.h b/memory/build/mozmemory.h index 5bd056ec5df1..9417c3c08744 100644 --- a/memory/build/mozmemory.h +++ b/memory/build/mozmemory.h @@ -7,16 +7,14 @@ #ifndef mozmemory_h #define mozmemory_h -/* - * This header is meant to be used when the following functions are - * necessary: - * - malloc_good_size (used to be called je_malloc_usable_in_advance) - * - jemalloc_stats - * - jemalloc_purge_freed_pages - * - jemalloc_free_dirty_pages - * - jemalloc_thread_local_arena - * - jemalloc_ptr_info - */ +// This header is meant to be used when the following functions are +// necessary: +// - malloc_good_size (used to be called je_malloc_usable_in_advance) +// - jemalloc_stats +// - jemalloc_purge_freed_pages +// - jemalloc_free_dirty_pages +// - jemalloc_thread_local_arena +// - jemalloc_ptr_info #ifdef MALLOC_H #include MALLOC_H @@ -27,17 +25,14 @@ #include "mozjemalloc_types.h" #ifdef MOZ_MEMORY -/* - * On OSX, malloc/malloc.h contains the declaration for malloc_good_size, - * which will call back in jemalloc, through the zone allocator so just use it. - */ +// On OSX, malloc/malloc.h contains the declaration for malloc_good_size, +// which will call back in jemalloc, through the zone allocator so just use it. #ifndef XP_DARWIN MOZ_MEMORY_API size_t malloc_good_size_impl(size_t size); -/* Note: the MOZ_GLUE_IN_PROGRAM ifdef below is there to avoid -Werror turning - * the protective if into errors. MOZ_GLUE_IN_PROGRAM is what triggers MFBT_API - * to use weak imports. */ - +// Note: the MOZ_GLUE_IN_PROGRAM ifdef below is there to avoid -Werror turning +// the protective if into errors. MOZ_GLUE_IN_PROGRAM is what triggers MFBT_API +// to use weak imports. static inline size_t _malloc_good_size(size_t size) { # if defined(MOZ_GLUE_IN_PROGRAM) && !defined(IMPL_MFBT) if (!malloc_good_size) @@ -61,4 +56,4 @@ static inline size_t _malloc_good_size(size_t size) { #define MALLOC_FUNCS MALLOC_FUNCS_ARENA #include "malloc_decls.h" -#endif /* mozmemory_h */ +#endif // mozmemory_h diff --git a/memory/build/mozmemory_wrap.cpp b/memory/build/mozmemory_wrap.cpp index 770eddd53573..a387ef123363 100644 --- a/memory/build/mozmemory_wrap.cpp +++ b/memory/build/mozmemory_wrap.cpp @@ -8,8 +8,8 @@ #include "mozmemory_wrap.h" #include "mozilla/Types.h" -/* Declare malloc implementation functions with the right return and - * argument types. */ +// Declare malloc implementation functions with the right return and +// argument types. #define MALLOC_DECL(name, return_type, ...) \ MOZ_MEMORY_API return_type name ## _impl(__VA_ARGS__); #define MALLOC_FUNCS MALLOC_FUNCS_MALLOC @@ -67,8 +67,8 @@ operator delete[](void* ptr, std::nothrow_t const&) } #endif -/* strndup and strdup may be defined as macros in string.h, which would - * clash with the definitions below. */ +// strndup and strdup may be defined as macros in string.h, which would +// clash with the definitions below. #undef strndup #undef strdup @@ -147,10 +147,8 @@ asprintf_impl(char **str, const char *fmt, ...) #ifdef XP_WIN #include -/* - * We also need to provide our own impl of wcsdup so that we don't ask - * the CRT for memory from its heap (which will then be unfreeable). - */ +// We also need to provide our own impl of wcsdup so that we don't ask +// the CRT for memory from its heap (which will then be unfreeable). MOZ_MEMORY_API wchar_t* wcsdup_impl(const wchar_t* src) { @@ -166,4 +164,4 @@ _aligned_malloc(size_t size, size_t alignment) { return memalign_impl(alignment, size); } -#endif /* XP_WIN */ +#endif // XP_WIN diff --git a/memory/build/mozmemory_wrap.h b/memory/build/mozmemory_wrap.h index 1d2bac686cab..1b48c3e08e6c 100644 --- a/memory/build/mozmemory_wrap.h +++ b/memory/build/mozmemory_wrap.h @@ -7,91 +7,89 @@ #ifndef mozmemory_wrap_h #define mozmemory_wrap_h -/* - * This header contains #defines which tweak the names of various memory - * allocation functions. - * - * There are several types of functions related to memory allocation - * that are meant to be used publicly by the Gecko codebase: - * - * - malloc implementation functions: - * - malloc - * - posix_memalign - * - aligned_alloc - * - calloc - * - realloc - * - free - * - memalign - * - valloc - * - malloc_usable_size - * - malloc_good_size - * Some of these functions are specific to some systems, but for - * convenience, they are treated as being cross-platform, and available - * as such. - * - * - duplication functions: - * - strndup - * - strdup - * - wcsdup (Windows only) - * - * - jemalloc specific functions: - * - jemalloc_stats - * - jemalloc_purge_freed_pages - * - jemalloc_free_dirty_pages - * - jemalloc_thread_local_arena - * - jemalloc_ptr_info - * (these functions are native to mozjemalloc) - * - * These functions are all exported as part of libmozglue (see - * $(topsrcdir)/mozglue/build/Makefile.in), with a few implementation - * peculiarities: - * - * - On Windows, the malloc implementation functions are all prefixed with - * "je_", the duplication functions are prefixed with "wrap_", and jemalloc - * specific functions are left unprefixed. All these functions are however - * aliased when exporting them, such that the resulting mozglue.dll exports - * them unprefixed (see $(topsrcdir)/mozglue/build/mozglue.def.in). The - * prefixed malloc implementation and duplication functions are not - * exported. - * - * - On MacOSX, the system libc has a zone allocator, which allows us to - * hook custom malloc implementation functions without exporting them. - * However, since we want things in Firefox to skip the system zone - * allocator, the malloc implementation functions are all exported - * unprefixed, as well as duplication functions. - * Jemalloc-specific functions are also left unprefixed. - * - * - On Android all functions are left unprefixed. Additionally, - * C++ allocation functions (operator new/delete) are also exported and - * unprefixed. - * - * - On other systems (mostly Linux), all functions are left unprefixed. - * - * Only Android adds C++ allocation functions. - * - * Proper exporting of the various functions is done with the MOZ_MEMORY_API - * and MOZ_JEMALLOC_API macros. MOZ_MEMORY_API is meant to be used for malloc - * implementation and duplication functions, while MOZ_JEMALLOC_API is - * dedicated to jemalloc specific functions. - * - * - * All these functions are meant to be called with no prefix from Gecko code. - * In most cases, this is because that's how they are available at runtime. - * However, on Android, this relies on faulty.lib (the custom dynamic linker) - * resolving mozglue symbols before libc symbols, which is guaranteed by the - * way faulty.lib works (it respects the DT_NEEDED order, and libc always - * appears after mozglue ; which we double check when building anyways) - * - * - * Within libmozglue (when MOZ_MEMORY_IMPL is defined), all the functions - * should be suffixed with "_impl" both for declarations and use. - * That is, the implementation declaration for e.g. strdup would look like: - * char* strdup_impl(const char *) - * That implementation would call malloc by using "malloc_impl". - */ +// This header contains #defines which tweak the names of various memory +// allocation functions. +// +// There are several types of functions related to memory allocation +// that are meant to be used publicly by the Gecko codebase: +// +// - malloc implementation functions: +// - malloc +// - posix_memalign +// - aligned_alloc +// - calloc +// - realloc +// - free +// - memalign +// - valloc +// - malloc_usable_size +// - malloc_good_size +// Some of these functions are specific to some systems, but for +// convenience, they are treated as being cross-platform, and available +// as such. +// +// - duplication functions: +// - strndup +// - strdup +// - wcsdup (Windows only) +// +// - jemalloc specific functions: +// - jemalloc_stats +// - jemalloc_purge_freed_pages +// - jemalloc_free_dirty_pages +// - jemalloc_thread_local_arena +// - jemalloc_ptr_info +// (these functions are native to mozjemalloc) +// +// These functions are all exported as part of libmozglue (see +// $(topsrcdir)/mozglue/build/Makefile.in), with a few implementation +// peculiarities: +// +// - On Windows, the malloc implementation functions are all prefixed with +// "je_", the duplication functions are prefixed with "wrap_", and jemalloc +// specific functions are left unprefixed. All these functions are however +// aliased when exporting them, such that the resulting mozglue.dll exports +// them unprefixed (see $(topsrcdir)/mozglue/build/mozglue.def.in). The +// prefixed malloc implementation and duplication functions are not +// exported. +// +// - On MacOSX, the system libc has a zone allocator, which allows us to +// hook custom malloc implementation functions without exporting them. +// However, since we want things in Firefox to skip the system zone +// allocator, the malloc implementation functions are all exported +// unprefixed, as well as duplication functions. +// Jemalloc-specific functions are also left unprefixed. +// +// - On Android all functions are left unprefixed. Additionally, +// C++ allocation functions (operator new/delete) are also exported and +// unprefixed. +// +// - On other systems (mostly Linux), all functions are left unprefixed. +// +// Only Android adds C++ allocation functions. +// +// Proper exporting of the various functions is done with the MOZ_MEMORY_API +// and MOZ_JEMALLOC_API macros. MOZ_MEMORY_API is meant to be used for malloc +// implementation and duplication functions, while MOZ_JEMALLOC_API is +// dedicated to jemalloc specific functions. +// +// +// All these functions are meant to be called with no prefix from Gecko code. +// In most cases, this is because that's how they are available at runtime. +// However, on Android, this relies on faulty.lib (the custom dynamic linker) +// resolving mozglue symbols before libc symbols, which is guaranteed by the +// way faulty.lib works (it respects the DT_NEEDED order, and libc always +// appears after mozglue ; which we double check when building anyways) +// +// +// Within libmozglue (when MOZ_MEMORY_IMPL is defined), all the functions +// should be suffixed with "_impl" both for declarations and use. +// That is, the implementation declaration for e.g. strdup would look like: +// char* strdup_impl(const char *) +// That implementation would call malloc by using "malloc_impl". #if defined(MOZ_MEMORY_IMPL) && !defined(IMPL_MFBT) -# ifdef MFBT_API /* mozilla/Types.h was already included */ +# ifdef MFBT_API // mozilla/Types.h was already included # error mozmemory_wrap.h has to be included before mozilla/Types.h when MOZ_MEMORY_IMPL is set and IMPL_MFBT is not. # endif # define IMPL_MFBT @@ -141,7 +139,7 @@ # define mozmem_dup_impl(a) a #endif -/* Malloc implementation functions */ +// Malloc implementation functions #define malloc_impl mozmem_malloc_impl(malloc) #define posix_memalign_impl mozmem_malloc_impl(posix_memalign) #define aligned_alloc_impl mozmem_malloc_impl(aligned_alloc) @@ -153,20 +151,19 @@ #define malloc_usable_size_impl mozmem_malloc_impl(malloc_usable_size) #define malloc_good_size_impl mozmem_malloc_impl(malloc_good_size) -/* Duplication functions */ +// Duplication functions #define strndup_impl mozmem_dup_impl(strndup) #define strdup_impl mozmem_dup_impl(strdup) #ifdef XP_WIN # define wcsdup_impl mozmem_dup_impl(wcsdup) #endif -/* String functions */ +// String functions #ifdef ANDROID -/* Bug 801571 and Bug 879668, libstagefright uses vasprintf, causing malloc()/ - * free() to be mismatched between bionic and mozglue implementation. - */ +// Bug 801571 and Bug 879668, libstagefright uses vasprintf, causing malloc()/ +// free() to be mismatched between bionic and mozglue implementation. #define vasprintf_impl mozmem_dup_impl(vasprintf) #define asprintf_impl mozmem_dup_impl(asprintf) #endif -#endif /* mozmemory_wrap_h */ +#endif // mozmemory_wrap_h diff --git a/memory/build/rb.h b/memory/build/rb.h index 4567a7ae8068..21101c9da0a4 100644 --- a/memory/build/rb.h +++ b/memory/build/rb.h @@ -4,65 +4,64 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -/* - * Portions of this file were originally under the following license: - * - * Copyright (C) 2008 Jason Evans . - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice(s), this list of conditions and the following disclaimer - * unmodified other than the allowable addition of one or more - * copyright notices. - * 2. Redistributions in binary form must reproduce the above copyright - * notice(s), this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************** - * - * C++ template implementation of left-leaning red-black trees. - * - * All operations are done non-recursively. Parent pointers are not used, and - * color bits are stored in the least significant bit of right-child pointers, - * thus making node linkage as compact as is possible for red-black trees. - * - * The RedBlackTree template expects two type arguments: the type of the nodes, - * containing a RedBlackTreeNode, and a trait providing two methods: - * - a GetTreeNode method that returns a reference to the RedBlackTreeNode - * corresponding to a given node with the following signature: - * static RedBlackTreeNode& GetTreeNode(T*) - * - a Compare function with the following signature: - * static int Compare(T* aNode, T* aOther) - * ^^^^^ - * or aKey - * - * Interpretation of comparision function return values: - * - * -1 : aNode < aOther - * 0 : aNode == aOther - * 1 : aNode > aOther - * - * In all cases, the aNode or aKey argument is the first argument to the - * comparison function, which makes it possible to write comparison functions - * that treat the first argument specially. - * - ******************************************************************************/ +// Portions of this file were originally under the following license: +// +// Copyright (C) 2008 Jason Evans . +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// 1. Redistributions of source code must retain the above copyright +// notice(s), this list of conditions and the following disclaimer +// unmodified other than the allowable addition of one or more +// copyright notices. +// 2. Redistributions in binary form must reproduce the above copyright +// notice(s), this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the +// distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// **************************************************************************** +// +// C++ template implementation of left-leaning red-black trees. +// +// All operations are done non-recursively. Parent pointers are not used, and +// color bits are stored in the least significant bit of right-child pointers, +// thus making node linkage as compact as is possible for red-black trees. +// +// The RedBlackTree template expects two type arguments: the type of the nodes, +// containing a RedBlackTreeNode, and a trait providing two methods: +// - a GetTreeNode method that returns a reference to the RedBlackTreeNode +// corresponding to a given node with the following signature: +// static RedBlackTreeNode& GetTreeNode(T*) +// - a Compare function with the following signature: +// static int Compare(T* aNode, T* aOther) +// ^^^^^ +// or aKey +// +// Interpretation of comparision function return values: +// +// -1 : aNode < aOther +// 0 : aNode == aOther +// 1 : aNode > aOther +// +// In all cases, the aNode or aKey argument is the first argument to the +// comparison function, which makes it possible to write comparison functions +// that treat the first argument specially. +// +// *************************************************************************** #ifndef RB_H_ #define RB_H_ @@ -76,12 +75,12 @@ enum NodeColor Red = 1, }; -/* Node structure. */ +// Node structure. template class RedBlackTreeNode { T* mLeft; - /* The lowest bit is the color */ + // The lowest bit is the color T* mRightAndColor; public: @@ -129,7 +128,7 @@ public: } }; -/* Tree structure. */ +// Tree structure. template class RedBlackTree { @@ -161,8 +160,8 @@ public: return Search(reinterpret_cast(aKey)); } - /* Find a match if it exists. Otherwise, find the next greater node, if one - * exists */ + // Find a match if it exists. Otherwise, find the next greater node, if one + // exists. T* SearchOrNext(T* aKey) { return SearchOrNext(reinterpret_cast(aKey)); @@ -178,8 +177,8 @@ public: return Remove(reinterpret_cast(aNode)); } - /* Helper class to avoid having all the tree traversal code further below - * have to use Trait::GetTreeNode, adding visual noise. */ + // Helper class to avoid having all the tree traversal code further below + // have to use Trait::GetTreeNode, adding visual noise. struct TreeNode : public T { TreeNode* Left() @@ -339,29 +338,29 @@ private: rbp_i_p->SetRight(nullptr); rbp_i_p->SetColor(NodeColor::Black); rbp_i_c = mRoot; - /* Iteratively search down the tree for the insertion point, - * splitting 4-nodes as they are encountered. At the end of each - * iteration, rbp_i_g->rbp_i_p->rbp_i_c is a 3-level path down - * the tree, assuming a sufficiently deep tree. */ + // Iteratively search down the tree for the insertion point, + // splitting 4-nodes as they are encountered. At the end of each + // iteration, rbp_i_g->rbp_i_p->rbp_i_c is a 3-level path down + // the tree, assuming a sufficiently deep tree. while (rbp_i_c) { rbp_i_t = rbp_i_c->Left(); rbp_i_u = rbp_i_t ? rbp_i_t->Left() : nullptr; if (rbp_i_t && rbp_i_u && rbp_i_t->IsRed() && rbp_i_u->IsRed()) { - /* rbp_i_c is the top of a logical 4-node, so split it. - * This iteration does not move down the tree, due to the - * disruptiveness of node splitting. - * - * Rotate right. */ + // rbp_i_c is the top of a logical 4-node, so split it. + // This iteration does not move down the tree, due to the + // disruptiveness of node splitting. + // + // Rotate right. rbp_i_t = RotateRight(rbp_i_c); - /* Pass red links up one level. */ + // Pass red links up one level. rbp_i_u = rbp_i_t->Left(); rbp_i_u->SetColor(NodeColor::Black); if (rbp_i_p->Left() == rbp_i_c) { rbp_i_p->SetLeft(rbp_i_t); rbp_i_c = rbp_i_t; } else { - /* rbp_i_c was the right child of rbp_i_p, so rotate - * left in order to maintain the left-leaning invariant. */ + // rbp_i_c was the right child of rbp_i_p, so rotate + // left in order to maintain the left-leaning invariant. MOZ_ASSERT(rbp_i_p->Right() == rbp_i_c); rbp_i_p->SetRight(rbp_i_t); rbp_i_u = LeanLeft(rbp_i_p); @@ -392,7 +391,7 @@ private: rbp_i_c = rbp_i_c->Right(); } } - /* rbp_i_p now refers to the node under which to insert. */ + // rbp_i_p now refers to the node under which to insert. aNode->SetLeft(nullptr); aNode->SetRight(nullptr); aNode->SetColor(NodeColor::Red); @@ -407,7 +406,7 @@ private: } else { rbp_i_p->SetLeft(aNode); } - /* Update the root and make sure that it is black. */ + // Update the root and make sure that it is black. mRoot = rbp_i_s.addr()->Left(); mRoot->SetColor(NodeColor::Black); } @@ -425,24 +424,24 @@ private: rbp_r_p->SetColor(NodeColor::Black); rbp_r_c = mRoot; rbp_r_xp = nullptr; - /* Iterate down the tree, but always transform 2-nodes to 3- or - * 4-nodes in order to maintain the invariant that the current - * node is not a 2-node. This allows simple deletion once a leaf - * is reached. Handle the root specially though, since there may - * be no way to convert it from a 2-node to a 3-node. */ + // Iterate down the tree, but always transform 2-nodes to 3- or + // 4-nodes in order to maintain the invariant that the current + // node is not a 2-node. This allows simple deletion once a leaf + // is reached. Handle the root specially though, since there may + // be no way to convert it from a 2-node to a 3-node. rbp_r_cmp = Trait::Compare(aNode, rbp_r_c); if (rbp_r_cmp < 0) { rbp_r_t = rbp_r_c->Left(); rbp_r_u = rbp_r_t ? rbp_r_t->Left() : nullptr; if ((!rbp_r_t || rbp_r_t->IsBlack()) && (!rbp_r_u || rbp_r_u->IsBlack())) { - /* Apply standard transform to prepare for left move. */ + // Apply standard transform to prepare for left move. rbp_r_t = MoveRedLeft(rbp_r_c); rbp_r_t->SetColor(NodeColor::Black); rbp_r_p->SetLeft(rbp_r_t); rbp_r_c = rbp_r_t; } else { - /* Move left. */ + // Move left. rbp_r_p = rbp_r_c; rbp_r_c = rbp_r_c->Left(); } @@ -450,7 +449,7 @@ private: if (rbp_r_cmp == 0) { MOZ_ASSERT(aNode == rbp_r_c); if (!rbp_r_c->Right()) { - /* Delete root node (which is also a leaf node). */ + // Delete root node (which is also a leaf node). if (rbp_r_c->Left()) { rbp_r_t = LeanRight(rbp_r_c); rbp_r_t->SetRight(nullptr); @@ -459,12 +458,12 @@ private: } rbp_r_p->SetLeft(rbp_r_t); } else { - /* This is the node we want to delete, but we will - * instead swap it with its successor and delete the - * successor. Record enough information to do the - * swap later. rbp_r_xp is the aNode's parent. */ + // This is the node we want to delete, but we will + // instead swap it with its successor and delete the + // successor. Record enough information to do the + // swap later. rbp_r_xp is the aNode's parent. rbp_r_xp = rbp_r_p; - rbp_r_cmp = 1; /* Note that deletion is incomplete. */ + rbp_r_cmp = 1; // Note that deletion is incomplete. } } if (rbp_r_cmp == 1) { @@ -472,10 +471,10 @@ private: rbp_r_c->Right()->Left()->IsBlack())) { rbp_r_t = rbp_r_c->Left(); if (rbp_r_t->IsRed()) { - /* Standard transform. */ + // Standard transform. rbp_r_t = MoveRedRight(rbp_r_c); } else { - /* Root-specific transform. */ + // Root-specific transform. rbp_r_c->SetColor(NodeColor::Red); rbp_r_u = rbp_r_t->Left(); if (rbp_r_u && rbp_r_u->IsRed()) { @@ -491,7 +490,7 @@ private: rbp_r_p->SetLeft(rbp_r_t); rbp_r_c = rbp_r_t; } else { - /* Move right. */ + // Move right. rbp_r_p = rbp_r_c; rbp_r_c = rbp_r_c->Right(); } @@ -504,9 +503,9 @@ private: if (rbp_r_cmp < 0) { rbp_r_t = rbp_r_c->Left(); if (!rbp_r_t) { - /* rbp_r_c now refers to the successor node to - * relocate, and rbp_r_xp/aNode refer to the - * context for the relocation. */ + // rbp_r_c now refers to the successor node to + // relocate, and rbp_r_xp/aNode refer to the + // context for the relocation. if (rbp_r_xp->Left() == aNode) { rbp_r_xp->SetLeft(rbp_r_c); } else { @@ -538,12 +537,12 @@ private: rbp_r_c = rbp_r_c->Left(); } } else { - /* Check whether to delete this node (it has to be - * the correct node and a leaf node). */ + // Check whether to delete this node (it has to be + // the correct node and a leaf node). if (rbp_r_cmp == 0) { MOZ_ASSERT(aNode == rbp_r_c); if (!rbp_r_c->Right()) { - /* Delete leaf node. */ + // Delete leaf node. if (rbp_r_c->Left()) { rbp_r_t = LeanRight(rbp_r_c); rbp_r_t->SetRight(nullptr); @@ -557,11 +556,11 @@ private: } break; } - /* This is the node we want to delete, but we - * will instead swap it with its successor - * and delete the successor. Record enough - * information to do the swap later. - * rbp_r_xp is aNode's parent. */ + // This is the node we want to delete, but we + // will instead swap it with its successor + // and delete the successor. Record enough + // information to do the swap later. + // rbp_r_xp is aNode's parent. rbp_r_xp = rbp_r_p; } rbp_r_t = rbp_r_c->Right(); @@ -581,7 +580,7 @@ private: } } } - /* Update root. */ + // Update root. mRoot = rbp_r_s.addr()->Left(); } @@ -687,32 +686,29 @@ private: return node; } - /* - * The iterator simulates recursion via an array of pointers that store the - * current path. This is critical to performance, since a series of calls to - * rb_{next,prev}() would require time proportional to (n lg n), whereas this - * implementation only requires time proportional to (n). - * - * Since the iterator caches a path down the tree, any tree modification may - * cause the cached path to become invalid. Don't modify the tree during an - * iteration. - */ + // The iterator simulates recursion via an array of pointers that store the + // current path. This is critical to performance, since a series of calls to + // rb_{next,prev}() would require time proportional to (n lg n), whereas this + // implementation only requires time proportional to (n). + // + // Since the iterator caches a path down the tree, any tree modification may + // cause the cached path to become invalid. Don't modify the tree during an + // iteration. - /* - * Size the path arrays such that they are always large enough, even if a - * tree consumes all of memory. Since each node must contain a minimum of - * two pointers, there can never be more nodes than: - * - * 1 << ((sizeof(void*)<<3) - (log2(sizeof(void*))+1)) - * - * Since the depth of a tree is limited to 3*lg(#nodes), the maximum depth - * is: - * - * (3 * ((sizeof(void*)<<3) - (log2(sizeof(void*))+1))) - * - * This works out to a maximum depth of 87 and 180 for 32- and 64-bit - * systems, respectively (approximately 348 and 1440 bytes, respectively). - */ + + // Size the path arrays such that they are always large enough, even if a + // tree consumes all of memory. Since each node must contain a minimum of + // two pointers, there can never be more nodes than: + // + // 1 << ((sizeof(void*)<<3) - (log2(sizeof(void*))+1)) + // + // Since the depth of a tree is limited to 3*lg(#nodes), the maximum depth + // is: + // + // (3 * ((sizeof(void*)<<3) - (log2(sizeof(void*))+1))) + // + // This works out to a maximum depth of 87 and 180 for 32- and 64-bit + // systems, respectively (approximately 348 and 1440 bytes, respectively). public: class Iterator { @@ -723,7 +719,7 @@ public: explicit Iterator(RedBlackTree* aTree) : mDepth(0) { - /* Initialize the path to contain the left spine. */ + // Initialize the path to contain the left spine. if (aTree->mRoot) { TreeNode* node; mPath[mDepth++] = aTree->mRoot; @@ -773,14 +769,14 @@ public: { TreeNode* node; if ((node = mPath[mDepth - 1]->Right())) { - /* The successor is the left-most node in the right subtree. */ + // The successor is the left-most node in the right subtree. mPath[mDepth++] = node; while ((node = mPath[mDepth - 1]->Left())) { mPath[mDepth++] = node; } } else { - /* The successor is above the current node. Unwind until a - * left-leaning edge is removed from the path, of the path is empty. */ + // The successor is above the current node. Unwind until a + // left-leaning edge is removed from the path, of the path is empty. for (mDepth--; mDepth > 0; mDepth--) { if (mPath[mDepth - 1]->Left() == mPath[mDepth]) { break; @@ -794,4 +790,4 @@ public: Iterator iter() { return Iterator(this); } }; -#endif /* RB_H_ */ +#endif // RB_H_ diff --git a/memory/build/replace_malloc.h b/memory/build/replace_malloc.h index e6e6b8303dfe..5729da2a4a9a 100644 --- a/memory/build/replace_malloc.h +++ b/memory/build/replace_malloc.h @@ -7,58 +7,56 @@ #ifndef replace_malloc_h #define replace_malloc_h -/* - * The replace_malloc facility allows an external library to replace or - * supplement the jemalloc implementation. - * - * The external library may be hooked by setting one of the following - * environment variables to the library path: - * - LD_PRELOAD on Linux, - * - DYLD_INSERT_LIBRARIES on OSX, - * - MOZ_REPLACE_MALLOC_LIB on Windows and Android. - * - * An initialization function is called before any malloc replacement - * function, and has the following declaration: - * - * void replace_init(const malloc_table_t *) - * - * The const malloc_table_t pointer given to that function is a table - * containing pointers to the original jemalloc implementation, so that - * replacement functions can call them back if they need to. The pointer - * itself can safely be kept around (no need to copy the table itself). - * - * The functions to be implemented in the external library are of the form: - * - * void *replace_malloc(size_t size) - * { - * // Fiddle with the size if necessary. - * // orig->malloc doesn't have to be called if the external library - * // provides its own allocator, but in this case it will have to - * // implement all functions. - * void *ptr = orig->malloc(size); - * // Do whatever you want with the ptr. - * return ptr; - * } - * - * where "orig" is the pointer obtained from replace_init. - * - * See malloc_decls.h for a list of functions that can be replaced this - * way. The implementations are all in the form: - * return_type replace_name(arguments [,...]) - * - * They don't all need to be provided. - * - * Building a replace-malloc library is like rocket science. It can end up - * with things blowing up, especially when trying to use complex types, and - * even more especially when these types come from XPCOM or other parts of the - * Mozilla codebase. - * It is recommended to add the following to a replace-malloc implementation's - * moz.build: - * DISABLE_STL_WRAPPING = True # Avoid STL wrapping - * - * If your replace-malloc implementation lives under memory/replace, these - * are taken care of by memory/replace/defs.mk. - */ +// The replace_malloc facility allows an external library to replace or +// supplement the jemalloc implementation. +// +// The external library may be hooked by setting one of the following +// environment variables to the library path: +// - LD_PRELOAD on Linux, +// - DYLD_INSERT_LIBRARIES on OSX, +// - MOZ_REPLACE_MALLOC_LIB on Windows and Android. +// +// An initialization function is called before any malloc replacement +// function, and has the following declaration: +// +// void replace_init(const malloc_table_t *) +// +// The const malloc_table_t pointer given to that function is a table +// containing pointers to the original jemalloc implementation, so that +// replacement functions can call them back if they need to. The pointer +// itself can safely be kept around (no need to copy the table itself). +// +// The functions to be implemented in the external library are of the form: +// +// void *replace_malloc(size_t size) +// { +// // Fiddle with the size if necessary. +// // orig->malloc doesn't have to be called if the external library +// // provides its own allocator, but in this case it will have to +// // implement all functions. +// void *ptr = orig->malloc(size); +// // Do whatever you want with the ptr. +// return ptr; +// } +// +// where "orig" is the pointer obtained from replace_init. +// +// See malloc_decls.h for a list of functions that can be replaced this +// way. The implementations are all in the form: +// return_type replace_name(arguments [,...]) +// +// They don't all need to be provided. +// +// Building a replace-malloc library is like rocket science. It can end up +// with things blowing up, especially when trying to use complex types, and +// even more especially when these types come from XPCOM or other parts of the +// Mozilla codebase. +// It is recommended to add the following to a replace-malloc implementation's +// moz.build: +// DISABLE_STL_WRAPPING = True # Avoid STL wrapping +// +// If your replace-malloc implementation lives under memory/replace, these +// are taken care of by memory/replace/defs.mk. #ifdef replace_malloc_bridge_h #error Do not include replace_malloc_bridge.h before replace_malloc.h. \ @@ -69,16 +67,16 @@ #include "replace_malloc_bridge.h" -/* Implementing a replace-malloc library is incompatible with using mozalloc. */ +// Implementing a replace-malloc library is incompatible with using mozalloc. #define MOZ_NO_MOZALLOC 1 #include "mozilla/Types.h" MOZ_BEGIN_EXTERN_C -/* MOZ_NO_REPLACE_FUNC_DECL and MOZ_REPLACE_WEAK are only defined in - * replace_malloc.c. Normally including this header will add function - * definitions. */ +// MOZ_NO_REPLACE_FUNC_DECL and MOZ_REPLACE_WEAK are only defined in +// replace_malloc.c. Normally including this header will add function +// definitions. #ifndef MOZ_NO_REPLACE_FUNC_DECL # ifndef MOZ_REPLACE_WEAK @@ -91,8 +89,8 @@ MOZ_BEGIN_EXTERN_C # define MALLOC_FUNCS MALLOC_FUNCS_ALL # include "malloc_decls.h" -#endif /* MOZ_NO_REPLACE_FUNC_DECL */ +#endif // MOZ_NO_REPLACE_FUNC_DECL MOZ_END_EXTERN_C -#endif /* replace_malloc_h */ +#endif // replace_malloc_h diff --git a/memory/build/replace_malloc_bridge.h b/memory/build/replace_malloc_bridge.h index 1c40dc15abb3..36bf516159c2 100644 --- a/memory/build/replace_malloc_bridge.h +++ b/memory/build/replace_malloc_bridge.h @@ -7,44 +7,42 @@ #ifndef replace_malloc_bridge_h #define replace_malloc_bridge_h -/* - * The replace-malloc bridge allows bidirectional method calls between - * a program and the replace-malloc library that has been loaded for it. - * In Firefox, this is used to allow method calls between code in libxul - * and code in the replace-malloc library, without libxul needing to link - * against that library or vice-versa. - * - * Subsystems can add methods for their own need. Replace-malloc libraries - * can decide to implement those methods or not. - * - * Replace-malloc libraries can provide such a bridge by implementing - * a ReplaceMallocBridge-derived class, and a replace_get_bridge function - * returning an instance of that class. The default methods in - * ReplaceMallocBridge are expected to return values that callers would - * understand as "the bridge doesn't implement this method", so that a - * replace-malloc library doesn't have to implement all methods. - * - * The ReplaceMallocBridge class contains definitions for methods for - * all replace-malloc libraries. Each library picks the methods it wants - * to reply to in its ReplaceMallocBridge-derived class instance. - * All methods of ReplaceMallocBridge must be virtual. Similarly, - * anything passed as an argument to those methods must be plain data, or - * an instance of a class with only virtual methods. - * - * Binary compatibility is expected to be maintained, such that a newer - * Firefox can be used with an old replace-malloc library, or an old - * Firefox can be used with a newer replace-malloc library. As such, only - * new virtual methods should be added to ReplaceMallocBridge, and - * each change should have a corresponding bump of the mVersion value. - * At the same time, each virtual method should have a corresponding - * wrapper calling the virtual method on the instance from - * ReplaceMallocBridge::Get(), giving it the version the virtual method - * was added. - * - * Parts that are not relevant to the replace-malloc library end of the - * bridge are hidden when REPLACE_MALLOC_IMPL is not defined, which is - * the case when including replace_malloc.h. - */ +// The replace-malloc bridge allows bidirectional method calls between +// a program and the replace-malloc library that has been loaded for it. +// In Firefox, this is used to allow method calls between code in libxul +// and code in the replace-malloc library, without libxul needing to link +// against that library or vice-versa. +// +// Subsystems can add methods for their own need. Replace-malloc libraries +// can decide to implement those methods or not. +// +// Replace-malloc libraries can provide such a bridge by implementing +// a ReplaceMallocBridge-derived class, and a replace_get_bridge function +// returning an instance of that class. The default methods in +// ReplaceMallocBridge are expected to return values that callers would +// understand as "the bridge doesn't implement this method", so that a +// replace-malloc library doesn't have to implement all methods. +// +// The ReplaceMallocBridge class contains definitions for methods for +// all replace-malloc libraries. Each library picks the methods it wants +// to reply to in its ReplaceMallocBridge-derived class instance. +// All methods of ReplaceMallocBridge must be virtual. Similarly, +// anything passed as an argument to those methods must be plain data, or +// an instance of a class with only virtual methods. +// +// Binary compatibility is expected to be maintained, such that a newer +// Firefox can be used with an old replace-malloc library, or an old +// Firefox can be used with a newer replace-malloc library. As such, only +// new virtual methods should be added to ReplaceMallocBridge, and +// each change should have a corresponding bump of the mVersion value. +// At the same time, each virtual method should have a corresponding +// wrapper calling the virtual method on the instance from +// ReplaceMallocBridge::Get(), giving it the version the virtual method +// was added. +// +// Parts that are not relevant to the replace-malloc library end of the +// bridge are hidden when REPLACE_MALLOC_IMPL is not defined, which is +// the case when including replace_malloc.h. struct ReplaceMallocBridge; @@ -53,13 +51,13 @@ struct ReplaceMallocBridge; MOZ_BEGIN_EXTERN_C #ifndef REPLACE_MALLOC_IMPL -/* Returns the replace-malloc bridge if there is one to be returned. */ +// Returns the replace-malloc bridge if there is one to be returned. MFBT_API ReplaceMallocBridge* get_bridge(); #endif -/* Table of malloc functions. - * e.g. void* (*malloc)(size_t), etc. - */ +// Table of malloc functions. +// e.g. void* (*malloc)(size_t), etc. + #define MALLOC_DECL(name, return_type, ...) \ typedef return_type(name ## _impl_t)(__VA_ARGS__); @@ -76,18 +74,17 @@ MOZ_END_EXTERN_C #ifdef __cplusplus -/* Table of malloc hook functions. - * Those functions are called with the arguments and results of malloc - * functions after they are called. - * e.g. void* (*malloc_hook)(void*, size_t), etc. - * They can either return the result they're given, or alter it before - * returning it. - * The hooks corresponding to functions, like free(void*), that return no - * value, don't take an extra argument. - * The table must at least contain a pointer for malloc_hook and free_hook - * functions. They will be used as fallback if no pointer is given for - * other allocation functions, like calloc_hook. - */ +// Table of malloc hook functions. +// Those functions are called with the arguments and results of malloc +// functions after they are called. +// e.g. void* (*malloc_hook)(void*, size_t), etc. +// They can either return the result they're given, or alter it before +// returning it. +// The hooks corresponding to functions, like free(void*), that return no +// value, don't take an extra argument. +// The table must at least contain a pointer for malloc_hook and free_hook +// functions. They will be used as fallback if no pointer is given for +// other allocation functions, like calloc_hook. namespace mozilla { namespace detail { template @@ -110,8 +107,8 @@ struct AllocHookType typedef struct { #include "malloc_decls.h" - /* Like free_hook, but called before realloc_hook. free_hook is called - * instead of not given. */ + // Like free_hook, but called before realloc_hook. free_hook is called + // instead of not given. void (*realloc_hook_before)(void* aPtr); } malloc_hook_table_t; @@ -120,8 +117,8 @@ namespace dmd { struct DMDFuncs; } // namespace dmd -/* Callbacks to register debug file handles for Poison IO interpose. - * See Mozilla(|Un)RegisterDebugHandle in xpcom/build/PoisonIOInterposer.h */ +// Callbacks to register debug file handles for Poison IO interpose. +// See Mozilla(|Un)RegisterDebugHandle in xpcom/build/PoisonIOInterposer.h struct DebugFdRegistry { virtual void RegisterHandle(intptr_t aFd); @@ -135,35 +132,35 @@ struct ReplaceMallocBridge { ReplaceMallocBridge() : mVersion(3) {} - /* This method was added in version 1 of the bridge. */ + // This method was added in version 1 of the bridge. virtual mozilla::dmd::DMDFuncs* GetDMDFuncs() { return nullptr; } - /* Send a DebugFdRegistry instance to the replace-malloc library so that - * it can register/unregister file descriptors whenever needed. The - * instance is valid until the process dies. - * This method was added in version 2 of the bridge. */ + // Send a DebugFdRegistry instance to the replace-malloc library so that + // it can register/unregister file descriptors whenever needed. The + // instance is valid until the process dies. + // This method was added in version 2 of the bridge. virtual void InitDebugFd(mozilla::DebugFdRegistry&) {} - /* Register a list of malloc functions and hook functions to the - * replace-malloc library so that it can choose to dispatch to them - * when needed. The details of what is dispatched when is left to the - * replace-malloc library. - * Passing a nullptr for either table will unregister a previously - * registered table under the same name. - * Returns nullptr if registration failed. - * If registration succeeded, a table of "pure" malloc functions is - * returned. Those "pure" malloc functions won't call hooks. - * /!\ Do not rely on registration/unregistration to be instantaneous. - * Functions from a previously registered table may still be called for - * a brief time after RegisterHook returns. - * This method was added in version 3 of the bridge. */ + // Register a list of malloc functions and hook functions to the + // replace-malloc library so that it can choose to dispatch to them + // when needed. The details of what is dispatched when is left to the + // replace-malloc library. + // Passing a nullptr for either table will unregister a previously + // registered table under the same name. + // Returns nullptr if registration failed. + // If registration succeeded, a table of "pure" malloc functions is + // returned. Those "pure" malloc functions won't call hooks. + // /!\ Do not rely on registration/unregistration to be instantaneous. + // Functions from a previously registered table may still be called for + // a brief time after RegisterHook returns. + // This method was added in version 3 of the bridge. virtual const malloc_table_t* RegisterHook(const char* aName, const malloc_table_t* aTable, const malloc_hook_table_t* aHookTable) { return nullptr; } #ifndef REPLACE_MALLOC_IMPL - /* Returns the replace-malloc bridge if its version is at least the - * requested one. */ + // Returns the replace-malloc bridge if its version is at least the + // requested one. static ReplaceMallocBridge* Get(int aMinimumVersion) { static ReplaceMallocBridge* sSingleton = get_bridge(); return (sSingleton && sSingleton->mVersion >= aMinimumVersion) @@ -176,16 +173,16 @@ protected: }; #ifndef REPLACE_MALLOC_IMPL -/* Class containing wrappers for calls to ReplaceMallocBridge methods. - * Those wrappers need to be static methods in a class because compilers - * complain about unused static global functions, and linkers complain - * about multiple definitions of non-static global functions. - * Using a separate class from ReplaceMallocBridge allows the function - * names to be identical. */ +// Class containing wrappers for calls to ReplaceMallocBridge methods. +// Those wrappers need to be static methods in a class because compilers +// complain about unused static global functions, and linkers complain +// about multiple definitions of non-static global functions. +// Using a separate class from ReplaceMallocBridge allows the function +// names to be identical. struct ReplaceMalloc { - /* Don't call this method from performance critical code. Use - * mozilla::dmd::DMDFuncs::Get() instead, it has less overhead. */ + // Don't call this method from performance critical code. Use + // mozilla::dmd::DMDFuncs::Get() instead, it has less overhead. static mozilla::dmd::DMDFuncs* GetDMDFuncs() { auto singleton = ReplaceMallocBridge::Get(/* minimumVersion */ 1); @@ -211,6 +208,6 @@ struct ReplaceMalloc }; #endif -#endif /* __cplusplus */ +#endif // __cplusplus -#endif /* replace_malloc_bridge_h */ +#endif // replace_malloc_bridge_h diff --git a/memory/build/zone.c b/memory/build/zone.c index 1279c859037f..d81f3c8765e4 100644 --- a/memory/build/zone.c +++ b/memory/build/zone.c @@ -10,10 +10,9 @@ #include #include "mozilla/Assertions.h" -/* - * Malloc implementation functions are MOZ_MEMORY_API, and jemalloc - * specific functions MOZ_JEMALLOC_API; see mozmemory_wrap.h - */ +// Malloc implementation functions are MOZ_MEMORY_API, and jemalloc +// specific functions MOZ_JEMALLOC_API; see mozmemory_wrap.h + #define MALLOC_DECL(name, return_type, ...) \ MOZ_MEMORY_API return_type name ## _impl(__VA_ARGS__); #define MALLOC_FUNCS MALLOC_FUNCS_MALLOC @@ -24,11 +23,10 @@ #define MALLOC_FUNCS MALLOC_FUNCS_JEMALLOC #include "malloc_decls.h" -/* - * Definitions of the following structs in malloc/malloc.h might be too old - * for the built binary to run on newer versions of OSX. So use the newest - * possible version of those structs. - */ +// Definitions of the following structs in malloc/malloc.h might be too old +// for the built binary to run on newer versions of OSX. So use the newest +// possible version of those structs. + typedef struct _malloc_zone_t { void *reserved1; void *reserved2; @@ -102,13 +100,11 @@ extern void malloc_zone_free(malloc_zone_t* zone, void* ptr); extern void* malloc_zone_realloc(malloc_zone_t* zone, void* ptr, size_t size); -/* - * The following is a OSX zone allocator implementation. - * /!\ WARNING. It assumes the underlying malloc implementation's - * malloc_usable_size returns 0 when the given pointer is not owned by - * the allocator. Sadly, OSX does call zone_size with pointers not - * owned by the allocator. - */ +// The following is a OSX zone allocator implementation. +// /!\ WARNING. It assumes the underlying malloc implementation's +// malloc_usable_size returns 0 when the given pointer is not owned by +// the allocator. Sadly, OSX does call zone_size with pointers not +// owned by the allocator. static size_t zone_size(malloc_zone_t *zone, const void *ptr) @@ -206,7 +202,7 @@ zone_valloc(malloc_zone_t *zone, size_t size) static void zone_destroy(malloc_zone_t *zone) { - /* This function should never be called. */ + // This function should never be called. MOZ_CRASH(); } @@ -279,23 +275,23 @@ extern void _malloc_postfork_child(void); static void zone_force_lock(malloc_zone_t *zone) { - /* /!\ This calls into mozjemalloc. It works because we're linked in the - * same library. */ + // /!\ This calls into mozjemalloc. It works because we're linked in the + // same library. _malloc_prefork(); } static void zone_force_unlock(malloc_zone_t *zone) { - /* /!\ This calls into mozjemalloc. It works because we're linked in the - * same library. */ + // /!\ This calls into mozjemalloc. It works because we're linked in the + // same library. _malloc_postfork_child(); } static void zone_statistics(malloc_zone_t *zone, malloc_statistics_t *stats) { - /* We make no effort to actually fill the values */ + // We make no effort to actually fill the values stats->blocks_in_use = 0; stats->size_in_use = 0; stats->max_size_in_use = 0; @@ -305,15 +301,15 @@ zone_statistics(malloc_zone_t *zone, malloc_statistics_t *stats) static boolean_t zone_locked(malloc_zone_t *zone) { - /* Pretend no lock is being held */ + // Pretend no lock is being held return false; } static void zone_reinit_lock(malloc_zone_t *zone) { - /* As of OSX 10.12, this function is only used when force_unlock would - * be used if the zone version were < 9. So just use force_unlock. */ + // As of OSX 10.12, this function is only used when force_unlock would + // be used if the zone version were < 9. So just use force_unlock. zone_force_unlock(zone); } @@ -325,19 +321,17 @@ static malloc_zone_t *get_default_zone() malloc_zone_t **zones = NULL; unsigned int num_zones = 0; - /* - * On OSX 10.12, malloc_default_zone returns a special zone that is not - * present in the list of registered zones. That zone uses a "lite zone" - * if one is present (apparently enabled when malloc stack logging is - * enabled), or the first registered zone otherwise. In practice this - * means unless malloc stack logging is enabled, the first registered - * zone is the default. - * So get the list of zones to get the first one, instead of relying on - * malloc_default_zone. - */ + // On OSX 10.12, malloc_default_zone returns a special zone that is not + // present in the list of registered zones. That zone uses a "lite zone" + // if one is present (apparently enabled when malloc stack logging is + // enabled), or the first registered zone otherwise. In practice this + // means unless malloc stack logging is enabled, the first registered + // zone is the default. + // So get the list of zones to get the first one, instead of relying on + // malloc_default_zone. if (KERN_SUCCESS != malloc_get_all_zones(0, NULL, (vm_address_t**) &zones, &num_zones)) { - /* Reset the value in case the failure happened after it was set. */ + // Reset the value in case the failure happened after it was set. num_zones = 0; } if (num_zones) { @@ -391,42 +385,37 @@ register_zone(void) #endif zone_introspect.reinit_lock = zone_reinit_lock; - /* - * The default purgeable zone is created lazily by OSX's libc. It uses - * the default zone when it is created for "small" allocations - * (< 15 KiB), but assumes the default zone is a scalable_zone. This - * obviously fails when the default zone is the jemalloc zone, so - * malloc_default_purgeable_zone is called beforehand so that the - * default purgeable zone is created when the default zone is still - * a scalable_zone. - */ + // The default purgeable zone is created lazily by OSX's libc. It uses + // the default zone when it is created for "small" allocations + // (< 15 KiB), but assumes the default zone is a scalable_zone. This + // obviously fails when the default zone is the jemalloc zone, so + // malloc_default_purgeable_zone is called beforehand so that the + // default purgeable zone is created when the default zone is still + // a scalable_zone. malloc_zone_t *purgeable_zone = malloc_default_purgeable_zone(); - /* Register the custom zone. At this point it won't be the default. */ + // Register the custom zone. At this point it won't be the default. malloc_zone_register(&zone); do { - /* - * Unregister and reregister the default zone. On OSX >= 10.6, - * unregistering takes the last registered zone and places it at the - * location of the specified zone. Unregistering the default zone thus - * makes the last registered one the default. On OSX < 10.6, - * unregistering shifts all registered zones. The first registered zone - * then becomes the default. - */ + // Unregister and reregister the default zone. On OSX >= 10.6, + // unregistering takes the last registered zone and places it at the + // location of the specified zone. Unregistering the default zone thus + // makes the last registered one the default. On OSX < 10.6, + // unregistering shifts all registered zones. The first registered zone + // then becomes the default. malloc_zone_unregister(default_zone); malloc_zone_register(default_zone); - /* - * On OSX 10.6, having the default purgeable zone appear before the default - * zone makes some things crash because it thinks it owns the default - * zone allocated pointers. We thus unregister/re-register it in order to - * ensure it's always after the default zone. On OSX < 10.6, as - * unregistering shifts registered zones, this simply removes the purgeable - * zone from the list and adds it back at the end, after the default zone. - * On OSX >= 10.6, unregistering replaces the purgeable zone with the last - * registered zone above, i.e the default zone. Registering it again then - * puts it at the end, obviously after the default zone. - */ + + // On OSX 10.6, having the default purgeable zone appear before the default + // zone makes some things crash because it thinks it owns the default + // zone allocated pointers. We thus unregister/re-register it in order to + // ensure it's always after the default zone. On OSX < 10.6, as + // unregistering shifts registered zones, this simply removes the purgeable + // zone from the list and adds it back at the end, after the default zone. + // On OSX >= 10.6, unregistering replaces the purgeable zone with the last + // registered zone above, i.e the default zone. Registering it again then + // puts it at the end, obviously after the default zone. malloc_zone_unregister(purgeable_zone); malloc_zone_register(purgeable_zone); default_zone = get_default_zone();