115bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers/* 215bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers * Copyright (C) 2012 The Android Open Source Project 315bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers * 415bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers * Licensed under the Apache License, Version 2.0 (the "License"); 515bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers * you may not use this file except in compliance with the License. 615bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers * You may obtain a copy of the License at 715bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers * 815bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers * http://www.apache.org/licenses/LICENSE-2.0 915bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers * 1015bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers * Unless required by applicable law or agreed to in writing, software 1115bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers * distributed under the License is distributed on an "AS IS" BASIS, 1215bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1315bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers * See the License for the specific language governing permissions and 1415bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers * limitations under the License. 1515bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers */ 1615bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers 1715bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers#include "dlmalloc.h" 1815bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers 1980afd02024d20e60b197d3adfbb43cc303cf29e0Vladimir Marko#include "base/bit_utils.h" 2007ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes#include "base/logging.h" 2115bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers 2215bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers// ART specific morecore implementation defined in space.cc. 23277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampestatic void* art_heap_morecore(void* m, intptr_t increment); 2415bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers#define MORECORE(x) art_heap_morecore(m, x) 2515bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers 2615bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers// Custom heap error handling. 2715bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers#define PROCEED_ON_ERROR 0 2815bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogersstatic void art_heap_corruption(const char* function); 2915bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogersstatic void art_heap_usage_error(const char* function, void* p); 3015bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers#define CORRUPTION_ERROR_ACTION(m) art_heap_corruption(__FUNCTION__) 31b1eba213afaf7fa6445de863ddc9680ab99762eaBrian Carlstrom#define USAGE_ERROR_ACTION(m, p) art_heap_usage_error(__FUNCTION__, p) 3215bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers 3315bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers// Ugly inclusion of C file so that ART specific #defines configure dlmalloc for our use for 3415bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers// mspaces (regular dlmalloc is still declared in bionic). 35277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe#pragma GCC diagnostic push 36277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe#pragma GCC diagnostic ignored "-Wredundant-decls" 3715bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers#pragma GCC diagnostic ignored "-Wempty-body" 3815bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers#pragma GCC diagnostic ignored "-Wstrict-aliasing" 393220a6dabf4988f146afbdd2bd903020d32255e3Josh Gao#include "../../../external/dlmalloc/malloc.c" 40277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe#pragma GCC diagnostic pop 4115bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers 42277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampestatic void* art_heap_morecore(void* m, intptr_t increment) { 43277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe return ::art::gc::allocator::ArtDlMallocMoreCore(m, increment); 44277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe} 4515bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers 4615bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogersstatic void art_heap_corruption(const char* function) { 47c7dd295a4e0cc1d15c0c96088e55a85389bade74Ian Rogers LOG(::art::FATAL) << "Corrupt heap detected in: " << function; 4815bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers} 4915bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers 5015bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogersstatic void art_heap_usage_error(const char* function, void* p) { 516a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers LOG(::art::FATAL) << "Incorrect use of function '" << function << "' argument " << p 526a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers << " not expected"; 5315bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers} 541d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 551d54e73444e017d3a65234e0f193846f3e27472bIan Rogers#include "globals.h" 561d54e73444e017d3a65234e0f193846f3e27472bIan Rogers#include "utils.h" 571d54e73444e017d3a65234e0f193846f3e27472bIan Rogers#include <sys/mman.h> 581d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 591d54e73444e017d3a65234e0f193846f3e27472bIan Rogersextern "C" void DlmallocMadviseCallback(void* start, void* end, size_t used_bytes, void* arg) { 601d54e73444e017d3a65234e0f193846f3e27472bIan Rogers // Is this chunk in use? 611d54e73444e017d3a65234e0f193846f3e27472bIan Rogers if (used_bytes != 0) { 621d54e73444e017d3a65234e0f193846f3e27472bIan Rogers return; 631d54e73444e017d3a65234e0f193846f3e27472bIan Rogers } 641d54e73444e017d3a65234e0f193846f3e27472bIan Rogers // Do we have any whole pages to give back? 653e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom start = reinterpret_cast<void*>(art::RoundUp(reinterpret_cast<uintptr_t>(start), art::kPageSize)); 663e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom end = reinterpret_cast<void*>(art::RoundDown(reinterpret_cast<uintptr_t>(end), art::kPageSize)); 671d54e73444e017d3a65234e0f193846f3e27472bIan Rogers if (end > start) { 683e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom size_t length = reinterpret_cast<uint8_t*>(end) - reinterpret_cast<uint8_t*>(start); 691d54e73444e017d3a65234e0f193846f3e27472bIan Rogers int rc = madvise(start, length, MADV_DONTNEED); 701d54e73444e017d3a65234e0f193846f3e27472bIan Rogers if (UNLIKELY(rc != 0)) { 711d54e73444e017d3a65234e0f193846f3e27472bIan Rogers errno = rc; 72c7dd295a4e0cc1d15c0c96088e55a85389bade74Ian Rogers PLOG(::art::FATAL) << "madvise failed during heap trimming"; 731d54e73444e017d3a65234e0f193846f3e27472bIan Rogers } 741d54e73444e017d3a65234e0f193846f3e27472bIan Rogers size_t* reclaimed = reinterpret_cast<size_t*>(arg); 751d54e73444e017d3a65234e0f193846f3e27472bIan Rogers *reclaimed += length; 761d54e73444e017d3a65234e0f193846f3e27472bIan Rogers } 771d54e73444e017d3a65234e0f193846f3e27472bIan Rogers} 78be031fff278799984166ec866c2dd202447e0f23Hiroshi Yamauchi 796a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogersextern "C" void DlmallocBytesAllocatedCallback(void* start ATTRIBUTE_UNUSED, 804b8f1ecd3aa5a29ec1463ff88fee9db365f257dcRoland Levillain void* end ATTRIBUTE_UNUSED, 814b8f1ecd3aa5a29ec1463ff88fee9db365f257dcRoland Levillain size_t used_bytes, 826a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers void* arg) { 83be031fff278799984166ec866c2dd202447e0f23Hiroshi Yamauchi if (used_bytes == 0) { 84be031fff278799984166ec866c2dd202447e0f23Hiroshi Yamauchi return; 85be031fff278799984166ec866c2dd202447e0f23Hiroshi Yamauchi } 86be031fff278799984166ec866c2dd202447e0f23Hiroshi Yamauchi size_t* bytes_allocated = reinterpret_cast<size_t*>(arg); 87be031fff278799984166ec866c2dd202447e0f23Hiroshi Yamauchi *bytes_allocated += used_bytes + sizeof(size_t); 88be031fff278799984166ec866c2dd202447e0f23Hiroshi Yamauchi} 89be031fff278799984166ec866c2dd202447e0f23Hiroshi Yamauchi 904b8f1ecd3aa5a29ec1463ff88fee9db365f257dcRoland Levillainextern "C" void DlmallocObjectsAllocatedCallback(void* start ATTRIBUTE_UNUSED, 914b8f1ecd3aa5a29ec1463ff88fee9db365f257dcRoland Levillain void* end ATTRIBUTE_UNUSED, 924b8f1ecd3aa5a29ec1463ff88fee9db365f257dcRoland Levillain size_t used_bytes, 936a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers void* arg) { 94be031fff278799984166ec866c2dd202447e0f23Hiroshi Yamauchi if (used_bytes == 0) { 95be031fff278799984166ec866c2dd202447e0f23Hiroshi Yamauchi return; 96be031fff278799984166ec866c2dd202447e0f23Hiroshi Yamauchi } 97be031fff278799984166ec866c2dd202447e0f23Hiroshi Yamauchi size_t* objects_allocated = reinterpret_cast<size_t*>(arg); 98be031fff278799984166ec866c2dd202447e0f23Hiroshi Yamauchi ++(*objects_allocated); 99be031fff278799984166ec866c2dd202447e0f23Hiroshi Yamauchi} 100