CodeCache.cpp revision 2d13791ce7ff61221ca047553891f31a23b2e943
1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* libs/pixelflinger/codeflinger/CodeCache.cpp
2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**
3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Copyright 2006, The Android Open Source Project
4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**
5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");
6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** you may not use this file except in compliance with the License.
7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** You may obtain a copy of the License at
8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**
9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**     http://www.apache.org/licenses/LICENSE-2.0
10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**
11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Unless required by applicable law or agreed to in writing, software
12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS,
13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** See the License for the specific language governing permissions and
15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** limitations under the License.
16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project*/
17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <assert.h>
20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h>
21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h>
22beeeee705bcf16d705748713ea40dca3486cc7b7Nick Kralevich#include <unistd.h>
23beeeee705bcf16d705748713ea40dca3486cc7b7Nick Kralevich#include <sys/mman.h>
24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <cutils/log.h>
262d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers#include <cutils/ashmem.h>
27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <cutils/atomic.h>
28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "codeflinger/CodeCache.h"
30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
312d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers#define LOG_TAG "CodeCache"
322d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers
33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectnamespace android {
34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ----------------------------------------------------------------------------
36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if defined(__arm__)
38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <unistd.h>
39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <errno.h>
40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ----------------------------------------------------------------------------
43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
442d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers// A dlmalloc mspace is used to manage the code cache over a mmaped region.
452d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers#define HAVE_MMAP 0
462d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers#define HAVE_MREMAP 0
472d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers#define HAVE_MORECORE 0
482d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers#define MALLOC_ALIGNMENT 16
492d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers#define MSPACES 1
502d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers#define NO_MALLINFO 1
512d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers#define ONLY_MSPACES 1
522d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers// Custom heap error handling.
532d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers#define PROCEED_ON_ERROR 0
542d13791ce7ff61221ca047553891f31a23b2e943Ian Rogersstatic void heap_error(const char* msg, const char* function, void* p);
552d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers#define CORRUPTION_ERROR_ACTION(m) \
562d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers    heap_error("HEAP MEMORY CORRUPTION", __FUNCTION__, NULL)
572d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers#define USAGE_ERROR_ACTION(m,p) \
582d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers    heap_error("ARGUMENT IS INVALID HEAP ADDRESS", __FUNCTION__, p)
592d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers
602d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers
612d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers#pragma GCC diagnostic ignored "-Wstrict-aliasing"
622d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers#pragma GCC diagnostic ignored "-Wempty-body"
632d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers#include "../../../../bionic/libc/upstream-dlmalloc/malloc.c"
642d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers#pragma GCC diagnostic warning "-Wstrict-aliasing"
652d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers#pragma GCC diagnostic warning "-Wempty-body"
662d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers
672d13791ce7ff61221ca047553891f31a23b2e943Ian Rogersstatic void heap_error(const char* msg, const char* function, void* p) {
682d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers    ALOG(LOG_FATAL, LOG_TAG, "@@@ ABORTING: CODE FLINGER: %s IN %s addr=%p",
692d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers         msg, function, p);
702d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers    /* So that we can get a memory dump around p */
712d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers    *((int **) 0xdeadbaad) = (int *) p;
722d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers}
732d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers
742d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers// ----------------------------------------------------------------------------
752d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers
762d13791ce7ff61221ca047553891f31a23b2e943Ian Rogersstatic void* gExecutableStore = NULL;
772d13791ce7ff61221ca047553891f31a23b2e943Ian Rogersstatic mspace gMspace = NULL;
782d13791ce7ff61221ca047553891f31a23b2e943Ian Rogersconst size_t kMaxCodeCacheCapacity = 1024 * 1024;
792d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers
802d13791ce7ff61221ca047553891f31a23b2e943Ian Rogersstatic mspace getMspace()
812d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers{
822d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers    if (gExecutableStore == NULL) {
832d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers        int fd = ashmem_create_region("CodeFlinger code cache",
842d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers                                      kMaxCodeCacheCapacity);
852d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers        LOG_ALWAYS_FATAL_IF(fd < 0,
862d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers                            "Creating code cache, ashmem_create_region "
872d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers                            "failed with error '%s'", strerror(errno));
882d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers        gExecutableStore = mmap(NULL, kMaxCodeCacheCapacity,
892d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers                                PROT_READ | PROT_WRITE | PROT_EXEC,
902d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers                                MAP_PRIVATE, fd, 0);
912d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers        LOG_ALWAYS_FATAL_IF(gExecutableStore == NULL,
922d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers                            "Creating code cache, mmap failed with error "
932d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers                            "'%s'", strerror(errno));
942d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers        close(fd);
952d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers        gMspace = create_mspace_with_base(gExecutableStore, kMaxCodeCacheCapacity,
962d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers                                          /*locked=*/ false);
972d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers        mspace_set_footprint_limit(gMspace, kMaxCodeCacheCapacity);
982d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers    }
992d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers    return gMspace;
1002d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers}
1012d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers
102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectAssembly::Assembly(size_t size)
103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    : mCount(1), mSize(0)
104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
105beeeee705bcf16d705748713ea40dca3486cc7b7Nick Kralevich    mBase = (uint32_t*)mspace_malloc(getMspace(), size);
1062d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers    LOG_ALWAYS_FATAL_IF(mBase == NULL,
1072d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers                        "Failed to create Assembly of size %zd in executable "
1082d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers                        "store of size %zd", size, kMaxCodeCacheCapacity);
109beeeee705bcf16d705748713ea40dca3486cc7b7Nick Kralevich    mSize = size;
110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectAssembly::~Assembly()
113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
114beeeee705bcf16d705748713ea40dca3486cc7b7Nick Kralevich    mspace_free(getMspace(), mBase);
115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid Assembly::incStrong(const void*) const
118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    android_atomic_inc(&mCount);
120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid Assembly::decStrong(const void*) const
123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (android_atomic_dec(&mCount) == 1) {
125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        delete this;
126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectssize_t Assembly::size() const
130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!mBase) return NO_MEMORY;
132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return mSize;
133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectuint32_t* Assembly::base() const
136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return mBase;
138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectssize_t Assembly::resize(size_t newSize)
141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
142beeeee705bcf16d705748713ea40dca3486cc7b7Nick Kralevich    mBase = (uint32_t*)mspace_realloc(getMspace(), mBase, newSize);
1432d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers    LOG_ALWAYS_FATAL_IF(mBase == NULL,
1442d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers                        "Failed to resize Assembly to %zd in code cache "
1452d13791ce7ff61221ca047553891f31a23b2e943Ian Rogers                        "of size %zd", newSize, kMaxCodeCacheCapacity);
146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    mSize = newSize;
147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return size();
148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ----------------------------------------------------------------------------
151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectCodeCache::CodeCache(size_t size)
153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    : mCacheSize(size), mCacheInUse(0)
154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pthread_mutex_init(&mLock, 0);
156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectCodeCache::~CodeCache()
159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pthread_mutex_destroy(&mLock);
161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectsp<Assembly> CodeCache::lookup(const AssemblyKeyBase& keyBase) const
164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pthread_mutex_lock(&mLock);
166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    sp<Assembly> r;
167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ssize_t index = mCacheData.indexOfKey(key_t(keyBase));
168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (index >= 0) {
169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        const cache_entry_t& e = mCacheData.valueAt(index);
170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        e.when = mWhen++;
171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        r = e.entry;
172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pthread_mutex_unlock(&mLock);
174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return r;
175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint CodeCache::cache(  const AssemblyKeyBase& keyBase,
178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                            const sp<Assembly>& assembly)
179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pthread_mutex_lock(&mLock);
181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const ssize_t assemblySize = assembly->size();
183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    while (mCacheInUse + assemblySize > mCacheSize) {
184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // evict the LRU
185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        size_t lru = 0;
186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        size_t count = mCacheData.size();
187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        for (size_t i=0 ; i<count ; i++) {
188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            const cache_entry_t& e = mCacheData.valueAt(i);
189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (e.when < mCacheData.valueAt(lru).when) {
190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                lru = i;
191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        const cache_entry_t& e = mCacheData.valueAt(lru);
194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        mCacheInUse -= e.entry->size();
195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        mCacheData.removeItemsAt(lru);
196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ssize_t err = mCacheData.add(key_t(keyBase), cache_entry_t(assembly, mWhen));
199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (err >= 0) {
200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        mCacheInUse += assemblySize;
201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        mWhen++;
202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // synchronize caches...
203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if defined(__arm__)
204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        const long base = long(assembly->base());
205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        const long curr = base + long(assembly->size());
206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        err = cacheflush(base, curr, 0);
20701dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block        ALOGE_IF(err, "__ARM_NR_cacheflush error %s\n",
208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                strerror(errno));
209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pthread_mutex_unlock(&mLock);
213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return err;
214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ----------------------------------------------------------------------------
217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}; // namespace android
219