16fac447555dc94a935b78198479cce645c837b89Ian Rogers/* 26fac447555dc94a935b78198479cce645c837b89Ian Rogers * Copyright (C) 2014 The Android Open Source Project 36fac447555dc94a935b78198479cce645c837b89Ian Rogers * 46fac447555dc94a935b78198479cce645c837b89Ian Rogers * Licensed under the Apache License, Version 2.0 (the "License"); 56fac447555dc94a935b78198479cce645c837b89Ian Rogers * you may not use this file except in compliance with the License. 66fac447555dc94a935b78198479cce645c837b89Ian Rogers * You may obtain a copy of the License at 76fac447555dc94a935b78198479cce645c837b89Ian Rogers * 86fac447555dc94a935b78198479cce645c837b89Ian Rogers * http://www.apache.org/licenses/LICENSE-2.0 96fac447555dc94a935b78198479cce645c837b89Ian Rogers * 106fac447555dc94a935b78198479cce645c837b89Ian Rogers * Unless required by applicable law or agreed to in writing, software 116fac447555dc94a935b78198479cce645c837b89Ian Rogers * distributed under the License is distributed on an "AS IS" BASIS, 126fac447555dc94a935b78198479cce645c837b89Ian Rogers * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136fac447555dc94a935b78198479cce645c837b89Ian Rogers * See the License for the specific language governing permissions and 146fac447555dc94a935b78198479cce645c837b89Ian Rogers * limitations under the License. 156fac447555dc94a935b78198479cce645c837b89Ian Rogers */ 166fac447555dc94a935b78198479cce645c837b89Ian Rogers 171e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov#ifndef ART_RUNTIME_GC_SPACE_MEMORY_TOOL_MALLOC_SPACE_INL_H_ 181e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov#define ART_RUNTIME_GC_SPACE_MEMORY_TOOL_MALLOC_SPACE_INL_H_ 196fac447555dc94a935b78198479cce645c837b89Ian Rogers 201e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov#include "memory_tool_malloc_space.h" 218cf9cb386cd9286d67e879f1ee501ec00d72a4e1Andreas Gampe 228cf9cb386cd9286d67e879f1ee501ec00d72a4e1Andreas Gampe#include "base/memory_tool.h" 231e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov#include "memory_tool_settings.h" 248cf9cb386cd9286d67e879f1ee501ec00d72a4e1Andreas Gampe#include "mirror/object-inl.h" 25d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe 266fac447555dc94a935b78198479cce645c837b89Ian Rogersnamespace art { 276fac447555dc94a935b78198479cce645c837b89Ian Rogersnamespace gc { 286fac447555dc94a935b78198479cce645c837b89Ian Rogersnamespace space { 296fac447555dc94a935b78198479cce645c837b89Ian Rogers 301e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanovnamespace memory_tool_details { 316fac447555dc94a935b78198479cce645c837b89Ian Rogers 321e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanovtemplate <size_t kMemoryToolRedZoneBytes, bool kUseObjSizeForUsable> 33d7576328811e5103e99d31f834a857522cc1463fAndreas Gampeinline mirror::Object* AdjustForValgrind(void* obj_with_rdz, size_t num_bytes, 34d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe size_t bytes_allocated, size_t usable_size, 354460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi size_t bytes_tl_bulk_allocated, 364460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi size_t* bytes_allocated_out, size_t* usable_size_out, 374460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi size_t* bytes_tl_bulk_allocated_out) { 38d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe if (bytes_allocated_out != nullptr) { 39d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe *bytes_allocated_out = bytes_allocated; 406fac447555dc94a935b78198479cce645c837b89Ian Rogers } 414460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi if (bytes_tl_bulk_allocated_out != nullptr) { 424460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi *bytes_tl_bulk_allocated_out = bytes_tl_bulk_allocated; 434460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi } 44d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe 45d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe // This cuts over-provision and is a trade-off between testing the over-provisioning code paths 46d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe // vs checking overflows in the regular paths. 47d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe if (usable_size_out != nullptr) { 48d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe if (kUseObjSizeForUsable) { 49d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe *usable_size_out = num_bytes; 50d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe } else { 511e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov *usable_size_out = usable_size - 2 * kMemoryToolRedZoneBytes; 52d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe } 53d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe } 54d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe 55d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe // Left redzone. 561e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov MEMORY_TOOL_MAKE_NOACCESS(obj_with_rdz, kMemoryToolRedZoneBytes); 57d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe 58d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe // Make requested memory readable. 59d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe // (If the allocator assumes memory is zeroed out, we might get UNDEFINED warnings, so make 60d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe // everything DEFINED initially.) 616fac447555dc94a935b78198479cce645c837b89Ian Rogers mirror::Object* result = reinterpret_cast<mirror::Object*>( 621e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov reinterpret_cast<uint8_t*>(obj_with_rdz) + kMemoryToolRedZoneBytes); 631e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov MEMORY_TOOL_MAKE_DEFINED(result, num_bytes); 64d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe 65d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe // Right redzone. Assumes that if bytes_allocated > usable_size, then the difference is 66d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe // management data at the upper end, and for simplicity we will not protect that. 67d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe // At the moment, this fits RosAlloc (no management data in a slot, usable_size == alloc_size) 68d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe // and DlMalloc (allocation_size = (usable_size == num_bytes) + 4, 4 is management) 691e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov MEMORY_TOOL_MAKE_NOACCESS(reinterpret_cast<uint8_t*>(result) + num_bytes, 701e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov usable_size - (num_bytes + kMemoryToolRedZoneBytes)); 71d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe 726fac447555dc94a935b78198479cce645c837b89Ian Rogers return result; 736fac447555dc94a935b78198479cce645c837b89Ian Rogers} 746fac447555dc94a935b78198479cce645c837b89Ian Rogers 75d7576328811e5103e99d31f834a857522cc1463fAndreas Gampeinline size_t GetObjSizeNoThreadSafety(mirror::Object* obj) NO_THREAD_SAFETY_ANALYSIS { 76d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe return obj->SizeOf<kVerifyNone>(); 77d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe} 78d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe 791e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov} // namespace memory_tool_details 80d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe 81d7576328811e5103e99d31f834a857522cc1463fAndreas Gampetemplate <typename S, 821e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov size_t kMemoryToolRedZoneBytes, 83d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe bool kAdjustForRedzoneInAllocSize, 84d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe bool kUseObjSizeForUsable> 85d7576328811e5103e99d31f834a857522cc1463fAndreas Gampemirror::Object* 861e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii StepanovMemoryToolMallocSpace<S, 871e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov kMemoryToolRedZoneBytes, 88d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe kAdjustForRedzoneInAllocSize, 89d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe kUseObjSizeForUsable>::AllocWithGrowth( 904460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi Thread* self, size_t num_bytes, size_t* bytes_allocated_out, size_t* usable_size_out, 914460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi size_t* bytes_tl_bulk_allocated_out) { 92d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe size_t bytes_allocated; 93d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe size_t usable_size; 944460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi size_t bytes_tl_bulk_allocated; 951e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov void* obj_with_rdz = S::AllocWithGrowth(self, num_bytes + 2 * kMemoryToolRedZoneBytes, 964460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi &bytes_allocated, &usable_size, 974460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi &bytes_tl_bulk_allocated); 986fac447555dc94a935b78198479cce645c837b89Ian Rogers if (obj_with_rdz == nullptr) { 996fac447555dc94a935b78198479cce645c837b89Ian Rogers return nullptr; 1006fac447555dc94a935b78198479cce645c837b89Ian Rogers } 101d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe 1021e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov return memory_tool_details::AdjustForValgrind<kMemoryToolRedZoneBytes, kUseObjSizeForUsable>( 1034460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi obj_with_rdz, num_bytes, 1044460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi bytes_allocated, usable_size, 1054460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi bytes_tl_bulk_allocated, 1064460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi bytes_allocated_out, 1074460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi usable_size_out, 1084460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi bytes_tl_bulk_allocated_out); 1096fac447555dc94a935b78198479cce645c837b89Ian Rogers} 1106fac447555dc94a935b78198479cce645c837b89Ian Rogers 111d7576328811e5103e99d31f834a857522cc1463fAndreas Gampetemplate <typename S, 1121e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov size_t kMemoryToolRedZoneBytes, 113d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe bool kAdjustForRedzoneInAllocSize, 114d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe bool kUseObjSizeForUsable> 1151e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanovmirror::Object* MemoryToolMallocSpace<S, 1161e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov kMemoryToolRedZoneBytes, 117d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe kAdjustForRedzoneInAllocSize, 118d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe kUseObjSizeForUsable>::Alloc( 1194460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi Thread* self, size_t num_bytes, size_t* bytes_allocated_out, size_t* usable_size_out, 1204460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi size_t* bytes_tl_bulk_allocated_out) { 121d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe size_t bytes_allocated; 122d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe size_t usable_size; 1234460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi size_t bytes_tl_bulk_allocated; 1241e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov void* obj_with_rdz = S::Alloc(self, num_bytes + 2 * kMemoryToolRedZoneBytes, 1254460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi &bytes_allocated, &usable_size, &bytes_tl_bulk_allocated); 126d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe if (obj_with_rdz == nullptr) { 127d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe return nullptr; 128d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe } 129d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe 1301e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov return memory_tool_details::AdjustForValgrind<kMemoryToolRedZoneBytes, 131d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe kUseObjSizeForUsable>(obj_with_rdz, num_bytes, 132d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe bytes_allocated, usable_size, 1334460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi bytes_tl_bulk_allocated, 134d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe bytes_allocated_out, 1354460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi usable_size_out, 1364460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi bytes_tl_bulk_allocated_out); 137d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe} 138d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe 139d7576328811e5103e99d31f834a857522cc1463fAndreas Gampetemplate <typename S, 1401e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov size_t kMemoryToolRedZoneBytes, 141d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe bool kAdjustForRedzoneInAllocSize, 142d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe bool kUseObjSizeForUsable> 1431e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanovmirror::Object* MemoryToolMallocSpace<S, 1441e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov kMemoryToolRedZoneBytes, 14524a5a3003aa7dbc29db698ac86bfa18ef64b2593Andreas Gampe kAdjustForRedzoneInAllocSize, 14624a5a3003aa7dbc29db698ac86bfa18ef64b2593Andreas Gampe kUseObjSizeForUsable>::AllocThreadUnsafe( 1474460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi Thread* self, size_t num_bytes, size_t* bytes_allocated_out, size_t* usable_size_out, 1484460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi size_t* bytes_tl_bulk_allocated_out) { 14924a5a3003aa7dbc29db698ac86bfa18ef64b2593Andreas Gampe size_t bytes_allocated; 15024a5a3003aa7dbc29db698ac86bfa18ef64b2593Andreas Gampe size_t usable_size; 1514460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi size_t bytes_tl_bulk_allocated; 1521e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov void* obj_with_rdz = S::AllocThreadUnsafe(self, num_bytes + 2 * kMemoryToolRedZoneBytes, 1534460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi &bytes_allocated, &usable_size, 1544460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi &bytes_tl_bulk_allocated); 15524a5a3003aa7dbc29db698ac86bfa18ef64b2593Andreas Gampe if (obj_with_rdz == nullptr) { 15624a5a3003aa7dbc29db698ac86bfa18ef64b2593Andreas Gampe return nullptr; 15724a5a3003aa7dbc29db698ac86bfa18ef64b2593Andreas Gampe } 15824a5a3003aa7dbc29db698ac86bfa18ef64b2593Andreas Gampe 1591e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov return memory_tool_details::AdjustForValgrind<kMemoryToolRedZoneBytes, kUseObjSizeForUsable>( 1604460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi obj_with_rdz, num_bytes, 1614460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi bytes_allocated, usable_size, 1624460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi bytes_tl_bulk_allocated, 1634460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi bytes_allocated_out, 1644460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi usable_size_out, 1654460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi bytes_tl_bulk_allocated_out); 16624a5a3003aa7dbc29db698ac86bfa18ef64b2593Andreas Gampe} 16724a5a3003aa7dbc29db698ac86bfa18ef64b2593Andreas Gampe 16824a5a3003aa7dbc29db698ac86bfa18ef64b2593Andreas Gampetemplate <typename S, 1691e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov size_t kMemoryToolRedZoneBytes, 17024a5a3003aa7dbc29db698ac86bfa18ef64b2593Andreas Gampe bool kAdjustForRedzoneInAllocSize, 17124a5a3003aa7dbc29db698ac86bfa18ef64b2593Andreas Gampe bool kUseObjSizeForUsable> 1721e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanovsize_t MemoryToolMallocSpace<S, 1731e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov kMemoryToolRedZoneBytes, 174d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe kAdjustForRedzoneInAllocSize, 175d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe kUseObjSizeForUsable>::AllocationSize( 176d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe mirror::Object* obj, size_t* usable_size) { 1776fac447555dc94a935b78198479cce645c837b89Ian Rogers size_t result = S::AllocationSize(reinterpret_cast<mirror::Object*>( 1781e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov reinterpret_cast<uint8_t*>(obj) - (kAdjustForRedzoneInAllocSize ? kMemoryToolRedZoneBytes : 0)), 179d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe usable_size); 180d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe if (usable_size != nullptr) { 181d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe if (kUseObjSizeForUsable) { 1821e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov *usable_size = memory_tool_details::GetObjSizeNoThreadSafety(obj); 183d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe } else { 1841e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov *usable_size = *usable_size - 2 * kMemoryToolRedZoneBytes; 185d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe } 186d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe } 187661974a5561e5ccdfbac8cb5d8df8b7e6f3483b8Mathieu Chartier return result; 1886fac447555dc94a935b78198479cce645c837b89Ian Rogers} 1896fac447555dc94a935b78198479cce645c837b89Ian Rogers 190d7576328811e5103e99d31f834a857522cc1463fAndreas Gampetemplate <typename S, 1911e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov size_t kMemoryToolRedZoneBytes, 192d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe bool kAdjustForRedzoneInAllocSize, 193d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe bool kUseObjSizeForUsable> 1941e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanovsize_t MemoryToolMallocSpace<S, 1951e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov kMemoryToolRedZoneBytes, 196d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe kAdjustForRedzoneInAllocSize, 197d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe kUseObjSizeForUsable>::Free( 198d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe Thread* self, mirror::Object* ptr) { 1996fac447555dc94a935b78198479cce645c837b89Ian Rogers void* obj_after_rdz = reinterpret_cast<void*>(ptr); 2001e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov uint8_t* obj_with_rdz = reinterpret_cast<uint8_t*>(obj_after_rdz) - kMemoryToolRedZoneBytes; 2011e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov 2026fac447555dc94a935b78198479cce645c837b89Ian Rogers // Make redzones undefined. 203d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe size_t usable_size; 204d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe size_t allocation_size = AllocationSize(ptr, &usable_size); 205d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe 206d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe // Unprotect the allocation. 207d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe // Use the obj-size-for-usable flag to determine whether usable_size is the more important one, 208d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe // e.g., whether there's data in the allocation_size (and usable_size can't be trusted). 209d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe if (kUseObjSizeForUsable) { 2101e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov MEMORY_TOOL_MAKE_UNDEFINED(obj_with_rdz, allocation_size); 211d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe } else { 2121e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov MEMORY_TOOL_MAKE_UNDEFINED(obj_with_rdz, usable_size + 2 * kMemoryToolRedZoneBytes); 213d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe } 214d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe 215661974a5561e5ccdfbac8cb5d8df8b7e6f3483b8Mathieu Chartier return S::Free(self, reinterpret_cast<mirror::Object*>(obj_with_rdz)); 2166fac447555dc94a935b78198479cce645c837b89Ian Rogers} 2176fac447555dc94a935b78198479cce645c837b89Ian Rogers 218d7576328811e5103e99d31f834a857522cc1463fAndreas Gampetemplate <typename S, 2191e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov size_t kMemoryToolRedZoneBytes, 220d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe bool kAdjustForRedzoneInAllocSize, 221d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe bool kUseObjSizeForUsable> 2221e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanovsize_t MemoryToolMallocSpace<S, 2231e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov kMemoryToolRedZoneBytes, 224d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe kAdjustForRedzoneInAllocSize, 225d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe kUseObjSizeForUsable>::FreeList( 226d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe Thread* self, size_t num_ptrs, mirror::Object** ptrs) { 2276fac447555dc94a935b78198479cce645c837b89Ian Rogers size_t freed = 0; 2286fac447555dc94a935b78198479cce645c837b89Ian Rogers for (size_t i = 0; i < num_ptrs; i++) { 2296fac447555dc94a935b78198479cce645c837b89Ian Rogers freed += Free(self, ptrs[i]); 230661974a5561e5ccdfbac8cb5d8df8b7e6f3483b8Mathieu Chartier ptrs[i] = nullptr; 2316fac447555dc94a935b78198479cce645c837b89Ian Rogers } 2326fac447555dc94a935b78198479cce645c837b89Ian Rogers return freed; 2336fac447555dc94a935b78198479cce645c837b89Ian Rogers} 2346fac447555dc94a935b78198479cce645c837b89Ian Rogers 235d7576328811e5103e99d31f834a857522cc1463fAndreas Gampetemplate <typename S, 2361e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov size_t kMemoryToolRedZoneBytes, 237d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe bool kAdjustForRedzoneInAllocSize, 238d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe bool kUseObjSizeForUsable> 239d7576328811e5103e99d31f834a857522cc1463fAndreas Gampetemplate <typename... Params> 2401e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii StepanovMemoryToolMallocSpace<S, 2411e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov kMemoryToolRedZoneBytes, 242d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe kAdjustForRedzoneInAllocSize, 2431e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov kUseObjSizeForUsable>::MemoryToolMallocSpace( 244d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe MemMap* mem_map, size_t initial_size, Params... params) : S(mem_map, initial_size, params...) { 245b5e31f3dd5f792ff60225a4daa048a57d261cdd0Hiroshi Yamauchi // Don't want to change the valgrind states of the mem map here as the allocator is already 246b5e31f3dd5f792ff60225a4daa048a57d261cdd0Hiroshi Yamauchi // initialized at this point and that may interfere with what the allocator does internally. Note 247b5e31f3dd5f792ff60225a4daa048a57d261cdd0Hiroshi Yamauchi // that the tail beyond the initial size is mprotected. 2486fac447555dc94a935b78198479cce645c837b89Ian Rogers} 2496fac447555dc94a935b78198479cce645c837b89Ian Rogers 2504460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchitemplate <typename S, 2511e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov size_t kMemoryToolRedZoneBytes, 2524460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi bool kAdjustForRedzoneInAllocSize, 2534460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi bool kUseObjSizeForUsable> 2541e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanovsize_t MemoryToolMallocSpace<S, 2551e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov kMemoryToolRedZoneBytes, 2564460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi kAdjustForRedzoneInAllocSize, 2574460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi kUseObjSizeForUsable>::MaxBytesBulkAllocatedFor(size_t num_bytes) { 2581e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov return S::MaxBytesBulkAllocatedFor(num_bytes + 2 * kMemoryToolRedZoneBytes); 2594460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi} 2604460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi 2616fac447555dc94a935b78198479cce645c837b89Ian Rogers} // namespace space 2626fac447555dc94a935b78198479cce645c837b89Ian Rogers} // namespace gc 2636fac447555dc94a935b78198479cce645c837b89Ian Rogers} // namespace art 2646fac447555dc94a935b78198479cce645c837b89Ian Rogers 2651e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov#endif // ART_RUNTIME_GC_SPACE_MEMORY_TOOL_MALLOC_SPACE_INL_H_ 266