1551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik/*
2551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik * Copyright 2012, The Android Open Source Project
3551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik *
4551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik * Redistribution and use in source and binary forms, with or without
5551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik * modification, are permitted provided that the following conditions
6551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik * are met:
7551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik *  * Redistributions of source code must retain the above copyright
8551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik *    notice, this list of conditions and the following disclaimer.
9551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik *  * Redistributions in binary form must reproduce the above copyright
10551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik *    notice, this list of conditions and the following disclaimer in the
11551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik *    documentation and/or other materials provided with the distribution.
12551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik *
13551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
14551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
17551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik */
25551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik
26551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik#define LOG_TAG "LinearAllocator"
27551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik#define LOG_NDEBUG 1
28551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik
29551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik#include <stdlib.h>
30551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik#include <utils/LinearAllocator.h>
31551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik#include <utils/Log.h>
32551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik
33551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik
34551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik// The ideal size of a page allocation (these need to be multiples of 8)
35551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik#define INITIAL_PAGE_SIZE ((size_t)4096) // 4kb
36551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik#define MAX_PAGE_SIZE ((size_t)131072) // 128kb
37551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik
38551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik// The maximum amount of wasted space we can have per page
39551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik// Allocations exceeding this will have their own dedicated page
40551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik// If this is too low, we will malloc too much
41551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik// Too high, and we may waste too much space
42551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik// Must be smaller than INITIAL_PAGE_SIZE
43551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik#define MAX_WASTE_SIZE ((size_t)1024)
44551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik
45551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik#if ALIGN_DOUBLE
46551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik#define ALIGN_SZ (sizeof(double))
47551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik#else
48551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik#define ALIGN_SZ (sizeof(int))
49551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik#endif
50551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik
51551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik#define ALIGN(x) ((x + ALIGN_SZ - 1 ) & ~(ALIGN_SZ - 1))
52551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik#define ALIGN_PTR(p) ((void*)(ALIGN((size_t)p)))
53551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik
54551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik#if LOG_NDEBUG
55551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik#define ADD_ALLOCATION(size)
56551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik#define RM_ALLOCATION(size)
57551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik#else
58551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik#include <utils/Thread.h>
59551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik#include <utils/Timers.h>
60551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craikstatic size_t s_totalAllocations = 0;
61551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craikstatic nsecs_t s_nextLog = 0;
62551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craikstatic android::Mutex s_mutex;
63551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik
64551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craikstatic void _logUsageLocked() {
65551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
66551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    if (now > s_nextLog) {
67551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik        s_nextLog = now + milliseconds_to_nanoseconds(10);
68551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik        ALOGV("Total memory usage: %zu kb", s_totalAllocations / 1024);
69551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    }
70551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik}
71551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik
72551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craikstatic void _addAllocation(size_t size) {
73551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    android::AutoMutex lock(s_mutex);
74551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    s_totalAllocations += size;
75551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    _logUsageLocked();
76551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik}
77551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik
78551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik#define ADD_ALLOCATION(size) _addAllocation(size);
79551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik#define RM_ALLOCATION(size) _addAllocation(-size);
80551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik#endif
81551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik
82551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik#define min(x,y) (((x) < (y)) ? (x) : (y))
83551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik
84551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craiknamespace android {
85551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik
86551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craikclass LinearAllocator::Page {
87551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craikpublic:
88551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    Page* next() { return mNextPage; }
89551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    void setNext(Page* next) { mNextPage = next; }
90551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik
91551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    Page()
92551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik        : mNextPage(0)
93551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    {}
94551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik
95551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    void* operator new(size_t size, void* buf) { return buf; }
96551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik
97551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    void* start() {
98551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik        return (void*) (((size_t)this) + sizeof(Page));
99551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    }
100551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik
101551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    void* end(int pageSize) {
102551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik        return (void*) (((size_t)start()) + pageSize);
103551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    }
104551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik
105551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craikprivate:
106551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    Page(const Page& other) {}
107551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    Page* mNextPage;
108551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik};
109551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik
110551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris CraikLinearAllocator::LinearAllocator()
111551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    : mPageSize(INITIAL_PAGE_SIZE)
112551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    , mMaxAllocSize(MAX_WASTE_SIZE)
113551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    , mNext(0)
114551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    , mCurrentPage(0)
115551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    , mPages(0)
116551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    , mTotalAllocated(0)
117551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    , mWastedSpace(0)
118551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    , mPageCount(0)
119551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    , mDedicatedPageCount(0) {}
120551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik
121551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris CraikLinearAllocator::~LinearAllocator(void) {
122551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    Page* p = mPages;
123551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    while (p) {
124551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik        Page* next = p->next();
125551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik        p->~Page();
126551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik        free(p);
127551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik        RM_ALLOCATION(mPageSize);
128551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik        p = next;
129551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    }
130551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik}
131551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik
132551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craikvoid* LinearAllocator::start(Page* p) {
133551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    return ALIGN_PTR(((size_t*)p) + sizeof(Page));
134551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik}
135551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik
136551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craikvoid* LinearAllocator::end(Page* p) {
137551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    return ((char*)p) + mPageSize;
138551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik}
139551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik
140551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craikbool LinearAllocator::fitsInCurrentPage(size_t size) {
141551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    return mNext && ((char*)mNext + size) <= end(mCurrentPage);
142551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik}
143551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik
144551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craikvoid LinearAllocator::ensureNext(size_t size) {
145551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    if (fitsInCurrentPage(size)) return;
146551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik
147551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    if (mCurrentPage && mPageSize < MAX_PAGE_SIZE) {
148551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik        mPageSize = min(MAX_PAGE_SIZE, mPageSize * 2);
149551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik        mPageSize = ALIGN(mPageSize);
150551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    }
151551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    mWastedSpace += mPageSize;
152551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    Page* p = newPage(mPageSize);
153551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    if (mCurrentPage) {
154551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik        mCurrentPage->setNext(p);
155551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    }
156551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    mCurrentPage = p;
157551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    if (!mPages) {
158551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik        mPages = mCurrentPage;
159551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    }
160551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    mNext = start(mCurrentPage);
161551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik}
162551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik
163551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craikvoid* LinearAllocator::alloc(size_t size) {
164551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    size = ALIGN(size);
165551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    if (size > mMaxAllocSize && !fitsInCurrentPage(size)) {
166551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik        ALOGV("Exceeded max size %zu > %zu", size, mMaxAllocSize);
167551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik        // Allocation is too large, create a dedicated page for the allocation
168551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik        Page* page = newPage(size);
169551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik        mDedicatedPageCount++;
170551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik        page->setNext(mPages);
171551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik        mPages = page;
172551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik        if (!mCurrentPage)
173551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik            mCurrentPage = mPages;
174551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik        return start(page);
175551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    }
176551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    ensureNext(size);
177551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    void* ptr = mNext;
178551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    mNext = ((char*)mNext) + size;
179551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    mWastedSpace -= size;
180551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    return ptr;
181551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik}
182551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik
183551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craikvoid LinearAllocator::rewindIfLastAlloc(void* ptr, size_t allocSize) {
184551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    // Don't bother rewinding across pages
185551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    allocSize = ALIGN(allocSize);
186551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    if (ptr >= start(mCurrentPage) && ptr < end(mCurrentPage)
187551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik            && ptr == ((char*)mNext - allocSize)) {
188551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik        mTotalAllocated -= allocSize;
189551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik        mWastedSpace += allocSize;
190551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik        mNext = ptr;
191551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    }
192551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik}
193551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik
194551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris CraikLinearAllocator::Page* LinearAllocator::newPage(size_t pageSize) {
195551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    pageSize = ALIGN(pageSize + sizeof(LinearAllocator::Page));
196551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    ADD_ALLOCATION(pageSize);
197551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    mTotalAllocated += pageSize;
198551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    mPageCount++;
199551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    void* buf = malloc(pageSize);
200551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    return new (buf) Page();
201551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik}
202551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik
203551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craikstatic const char* toSize(size_t value, float& result) {
204551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    if (value < 2000) {
205551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik        result = value;
206551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik        return "B";
207551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    }
208551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    if (value < 2000000) {
209551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik        result = value / 1024.0f;
210551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik        return "KB";
211551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    }
212551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    result = value / 1048576.0f;
213551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    return "MB";
214551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik}
215551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik
216551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craikvoid LinearAllocator::dumpMemoryStats(const char* prefix) {
217551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    float prettySize;
218551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    const char* prettySuffix;
219551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    prettySuffix = toSize(mTotalAllocated, prettySize);
220551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    ALOGD("%sTotal allocated: %.2f%s", prefix, prettySize, prettySuffix);
221551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    prettySuffix = toSize(mWastedSpace, prettySize);
222551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    ALOGD("%sWasted space: %.2f%s (%.1f%%)", prefix, prettySize, prettySuffix,
223551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik          (float) mWastedSpace / (float) mTotalAllocated * 100.0f);
224551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik    ALOGD("%sPages %zu (dedicated %zu)", prefix, mPageCount, mDedicatedPageCount);
225551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik}
226551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik
227551fcf4fe39e68fab17d56cc6c4b8a61164891ffChris Craik}; // namespace android
228