CodeCache.cpp revision dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0
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> 22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <cutils/log.h> 24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <cutils/atomic.h> 25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "codeflinger/CodeCache.h" 27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectnamespace android { 29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ---------------------------------------------------------------------------- 31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if defined(__arm__) 33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <unistd.h> 34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <errno.h> 35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ---------------------------------------------------------------------------- 38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectAssembly::Assembly(size_t size) 40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project : mCount(1), mSize(0) 41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mBase = (uint32_t*)malloc(size); 43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (mBase) { 44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mSize = size; 45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectAssembly::~Assembly() 49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(mBase); 51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid Assembly::incStrong(const void*) const 54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project android_atomic_inc(&mCount); 56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid Assembly::decStrong(const void*) const 59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (android_atomic_dec(&mCount) == 1) { 61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project delete this; 62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectssize_t Assembly::size() const 66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!mBase) return NO_MEMORY; 68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return mSize; 69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectuint32_t* Assembly::base() const 72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return mBase; 74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectssize_t Assembly::resize(size_t newSize) 77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mBase = (uint32_t*)realloc(mBase, newSize); 79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mSize = newSize; 80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return size(); 81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ---------------------------------------------------------------------------- 84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectCodeCache::CodeCache(size_t size) 86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project : mCacheSize(size), mCacheInUse(0) 87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pthread_mutex_init(&mLock, 0); 89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectCodeCache::~CodeCache() 92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pthread_mutex_destroy(&mLock); 94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectsp<Assembly> CodeCache::lookup(const AssemblyKeyBase& keyBase) const 97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pthread_mutex_lock(&mLock); 99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sp<Assembly> r; 100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ssize_t index = mCacheData.indexOfKey(key_t(keyBase)); 101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (index >= 0) { 102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const cache_entry_t& e = mCacheData.valueAt(index); 103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project e.when = mWhen++; 104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project r = e.entry; 105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pthread_mutex_unlock(&mLock); 107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return r; 108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint CodeCache::cache( const AssemblyKeyBase& keyBase, 111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const sp<Assembly>& assembly) 112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pthread_mutex_lock(&mLock); 114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const ssize_t assemblySize = assembly->size(); 116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (mCacheInUse + assemblySize > mCacheSize) { 117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // evict the LRU 118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project size_t lru = 0; 119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project size_t count = mCacheData.size(); 120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (size_t i=0 ; i<count ; i++) { 121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const cache_entry_t& e = mCacheData.valueAt(i); 122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (e.when < mCacheData.valueAt(lru).when) { 123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project lru = i; 124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const cache_entry_t& e = mCacheData.valueAt(lru); 127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mCacheInUse -= e.entry->size(); 128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mCacheData.removeItemsAt(lru); 129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ssize_t err = mCacheData.add(key_t(keyBase), cache_entry_t(assembly, mWhen)); 132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (err >= 0) { 133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mCacheInUse += assemblySize; 134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mWhen++; 135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // synchronize caches... 136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if defined(__arm__) 137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const long base = long(assembly->base()); 138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const long curr = base + long(assembly->size()); 139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project err = cacheflush(base, curr, 0); 140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project LOGE_IF(err, "__ARM_NR_cacheflush error %s\n", 141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strerror(errno)); 142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pthread_mutex_unlock(&mLock); 146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return err; 147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ---------------------------------------------------------------------------- 150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}; // namespace android 152