/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * 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/. */
// 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.
// 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.
// Sometimes, system libraries call malloc_zone_* functions with the wrong // zone (e.g. CoreFoundation does). In that case, we need to find the real // one. We can't call libSystem's realloc directly because we're exporting // realloc from libmozglue and we'd pick that one, so we manually find the // right zone and realloc with it.
malloc_zone_t* real_zone = malloc_zone_from_ptr(ptr); // The system allocator crashes voluntarily by default when a pointer can't // be traced back to a zone. Do the same.
MOZ_RELEASE_ASSERT(real_zone);
MOZ_RELEASE_ASSERT(real_zone != zone); return malloc_zone_realloc(real_zone, ptr, size);
}
staticvoid other_zone_free(malloc_zone_t* original_zone, void* ptr) { // Sometimes, system libraries call malloc_zone_* functions with the wrong // zone (e.g. CoreFoundation does). In that case, we need to find the real // one. We can't call libSystem's free directly because we're exporting // free from libmozglue and we'd pick that one, so we manually find the // right zone and free with it. if (!ptr) { return;
}
malloc_zone_t* zone = malloc_zone_from_ptr(ptr); // The system allocator crashes voluntarily by default when a pointer can't // be traced back to a zone. Do the same.
MOZ_RELEASE_ASSERT(zone);
MOZ_RELEASE_ASSERT(zone != original_zone); return malloc_zone_free(zone, ptr);
}
// On Darwin the postfork handler is called in both the parent and the child. externvoid _malloc_prefork(void); externvoid _malloc_postfork(void);
staticvoid zone_force_lock(malloc_zone_t* zone) { // /!\ This calls into mozjemalloc. It works because we're linked in the // same library.
_malloc_prefork();
}
staticvoid zone_force_unlock(malloc_zone_t* zone) { // /!\ This calls into mozjemalloc. It works because we're linked in the // same library.
_malloc_postfork();
}
staticvoid zone_statistics(malloc_zone_t* zone, malloc_statistics_t* stats) { // 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;
stats->size_allocated = 0;
}
static boolean_t zone_locked(malloc_zone_t* zone) { // Pretend no lock is being held returnfalse;
}
staticvoid 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.
zone_force_unlock(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.
num_zones = 0;
} if (num_zones) { return zones[0];
} return malloc_default_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();
// There is a problem related to the above with the system nano zone, which // is hard to work around from here, and that is instead worked around by // disabling the nano zone through an environment variable // (MallocNanoZone=0). In Firefox, we do that through // browser/app/macbuild/Contents/Info.plist.in.
// 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.
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.
malloc_zone_unregister(purgeable_zone);
malloc_zone_register(purgeable_zone);
default_zone = get_default_zone();
} while (default_zone != &zone);
}
¤ Dauer der Verarbeitung: 0.27 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.