// This cuts over-provision and is a trade-off between testing the over-provisioning code paths // vs checking overflows in the regular paths. if (usable_size_out != nullptr) { if (kUseObjSizeForUsable) {
*usable_size_out = num_bytes;
} else {
*usable_size_out = usable_size - 2 * kMemoryToolRedZoneBytes;
}
}
// Left redzone.
MEMORY_TOOL_MAKE_NOACCESS(obj_with_rdz, kMemoryToolRedZoneBytes);
// Make requested memory readable. // (If the allocator assumes memory is zeroed out, we might get UNDEFINED warnings, so make // everything DEFINED initially.)
mirror::Object* result = reinterpret_cast<mirror::Object*>( reinterpret_cast<uint8_t*>(obj_with_rdz) + kMemoryToolRedZoneBytes);
MEMORY_TOOL_MAKE_DEFINED(result, num_bytes);
// Right redzone. Assumes that if bytes_allocated > usable_size, then the difference is // management data at the upper end, and for simplicity we will not protect that. // At the moment, this fits RosAlloc (no management data in a slot, usable_size == alloc_size) // and DlMalloc (allocation_size = (usable_size == num_bytes) + 4, 4 is management)
MEMORY_TOOL_MAKE_NOACCESS(reinterpret_cast<uint8_t*>(result) + num_bytes,
usable_size - (num_bytes + kMemoryToolRedZoneBytes));
// Unprotect the allocation. // Use the obj-size-for-usable flag to determine whether usable_size is the more important one, // e.g., whether there's data in the allocation_size (and usable_size can't be trusted). if (kUseObjSizeForUsable) {
MEMORY_TOOL_MAKE_UNDEFINED(obj_with_rdz, allocation_size);
} else {
MEMORY_TOOL_MAKE_UNDEFINED(obj_with_rdz, usable_size + 2 * kMemoryToolRedZoneBytes);
}
template <typename S,
size_t kMemoryToolRedZoneBytes, bool kAdjustForRedzoneInAllocSize, bool kUseObjSizeForUsable>
size_t MemoryToolMallocSpace<S,
kMemoryToolRedZoneBytes,
kAdjustForRedzoneInAllocSize,
kUseObjSizeForUsable>::FreeList(
Thread* self, size_t num_ptrs, mirror::Object** ptrs) {
size_t freed = 0; // Sort the pointers to free non class objects first. See b/131542326 for why this is necessary to // avoid crashes.
std::sort(ptrs, ptrs + num_ptrs, [](mirror::Object* a, mirror::Object* b)
REQUIRES_SHARED(Locks::mutator_lock_) { return a->IsClass() < b->IsClass();
}); for (size_t i = 0; i < num_ptrs; i++) {
freed += Free(self, ptrs[i]);
ptrs[i] = nullptr;
} return freed;
}
template <typename S,
size_t kMemoryToolRedZoneBytes, bool kAdjustForRedzoneInAllocSize, bool kUseObjSizeForUsable> template <typename... Params>
MemoryToolMallocSpace<S,
kMemoryToolRedZoneBytes,
kAdjustForRedzoneInAllocSize,
kUseObjSizeForUsable>::MemoryToolMallocSpace(
MemMap&& mem_map, size_t initial_size, Params... params)
: S(std::move(mem_map), initial_size, params...) { // Don't want to change the memory tool states of the mem map here as the allocator is already // initialized at this point and that may interfere with what the allocator does internally. Note // that the tail beyond the initial size is mprotected.
}
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 und die Messung sind noch experimentell.