Compiler.cpp revision f9f33287693f9f9aa44318036b8aab627bd21a32
1ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* 2ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * Copyright (C) 2009 The Android Open Source Project 3ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * 4ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * Licensed under the Apache License, Version 2.0 (the "License"); 5ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * you may not use this file except in compliance with the License. 6ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * You may obtain a copy of the License at 7ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * 8ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * http://www.apache.org/licenses/LICENSE-2.0 9ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * 10ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * Unless required by applicable law or agreed to in writing, software 11ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * distributed under the License is distributed on an "AS IS" BASIS, 12ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * See the License for the specific language governing permissions and 14ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * limitations under the License. 15ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng */ 16ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 17ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng#include <sys/mman.h> 18ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng#include <errno.h> 19ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 20ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng#include "Dalvik.h" 21ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng#include "interp/Jit.h" 22ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng#include "CompilerInternals.h" 23ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 24ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Chengstatic inline bool workQueueLength(void) 25ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng{ 26ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng return gDvmJit.compilerQueueLength; 27ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng} 28ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 29ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Chengstatic CompilerWorkOrder workDequeue(void) 30ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng{ 31ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng assert(gDvmJit.compilerWorkQueue[gDvmJit.compilerWorkDequeueIndex].kind 32ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng != kWorkOrderInvalid); 33ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng CompilerWorkOrder work = 34ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng gDvmJit.compilerWorkQueue[gDvmJit.compilerWorkDequeueIndex]; 35ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng gDvmJit.compilerWorkQueue[gDvmJit.compilerWorkDequeueIndex++].kind = 36ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng kWorkOrderInvalid; 37ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng if (gDvmJit.compilerWorkDequeueIndex == COMPILER_WORK_QUEUE_SIZE) { 38ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng gDvmJit.compilerWorkDequeueIndex = 0; 39ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } 40ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng gDvmJit.compilerQueueLength--; 41f9f33287693f9f9aa44318036b8aab627bd21a32Bill Buzbee if (gDvmJit.compilerQueueLength == 0) { 42f9f33287693f9f9aa44318036b8aab627bd21a32Bill Buzbee int cc = pthread_cond_signal(&gDvmJit.compilerQueueEmpty); 43f9f33287693f9f9aa44318036b8aab627bd21a32Bill Buzbee } 44ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 45ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng /* Remember the high water mark of the queue length */ 46ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng if (gDvmJit.compilerQueueLength > gDvmJit.compilerMaxQueued) 47ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng gDvmJit.compilerMaxQueued = gDvmJit.compilerQueueLength; 48ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 49ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng return work; 50ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng} 51ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 52ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Chengbool dvmCompilerWorkEnqueue(const u2 *pc, WorkOrderKind kind, void* info) 53ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng{ 54ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng int cc; 55ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng int i; 56ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng int numWork; 57ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 58ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng dvmLockMutex(&gDvmJit.compilerLock); 59ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 60ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng /* Queue full */ 61ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng if (gDvmJit.compilerQueueLength == COMPILER_WORK_QUEUE_SIZE || 62ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng gDvmJit.codeCacheFull == true) { 63ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng dvmUnlockMutex(&gDvmJit.compilerLock); 64ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng return false; 65ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } 66ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 67ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng for (numWork = gDvmJit.compilerQueueLength, 68ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng i = gDvmJit.compilerWorkDequeueIndex; 69ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng numWork > 0; 70ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng numWork--) { 71ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng /* Already enqueued */ 72ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng if (gDvmJit.compilerWorkQueue[i++].pc == pc) 73ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng goto done; 74ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng /* Wrap around */ 75ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng if (i == COMPILER_WORK_QUEUE_SIZE) 76ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng i = 0; 77ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } 78ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 79ccd6c0102d1f898aaea1c94761167fdd083b5275Ben Cheng CompilerWorkOrder *newOrder = 80ccd6c0102d1f898aaea1c94761167fdd083b5275Ben Cheng &gDvmJit.compilerWorkQueue[gDvmJit.compilerWorkEnqueueIndex]; 81ccd6c0102d1f898aaea1c94761167fdd083b5275Ben Cheng newOrder->pc = pc; 82ccd6c0102d1f898aaea1c94761167fdd083b5275Ben Cheng newOrder->kind = kind; 83ccd6c0102d1f898aaea1c94761167fdd083b5275Ben Cheng newOrder->info = info; 84ccd6c0102d1f898aaea1c94761167fdd083b5275Ben Cheng newOrder->result.codeAddress = NULL; 85ccd6c0102d1f898aaea1c94761167fdd083b5275Ben Cheng newOrder->result.discardResult = 86ccd6c0102d1f898aaea1c94761167fdd083b5275Ben Cheng (kind == kWorkOrderTraceDebug) ? true : false; 87ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng gDvmJit.compilerWorkEnqueueIndex++; 88ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng if (gDvmJit.compilerWorkEnqueueIndex == COMPILER_WORK_QUEUE_SIZE) 89ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng gDvmJit.compilerWorkEnqueueIndex = 0; 90ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng gDvmJit.compilerQueueLength++; 91ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng cc = pthread_cond_signal(&gDvmJit.compilerQueueActivity); 92ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng assert(cc == 0); 93ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 94ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Chengdone: 95ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng dvmUnlockMutex(&gDvmJit.compilerLock); 96ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng return true; 97ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng} 98ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 99ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* Block until queue length is 0 */ 100ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Chengvoid dvmCompilerDrainQueue(void) 101ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng{ 102d726991ba52466cde88e37aba4de2395b62477faBill Buzbee int oldStatus = dvmChangeStatus(NULL, THREAD_VMWAIT); 103ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng dvmLockMutex(&gDvmJit.compilerLock); 104ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng while (workQueueLength() != 0 && !gDvmJit.haltCompilerThread) { 105ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng pthread_cond_wait(&gDvmJit.compilerQueueEmpty, &gDvmJit.compilerLock); 106ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } 107ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng dvmUnlockMutex(&gDvmJit.compilerLock); 108d726991ba52466cde88e37aba4de2395b62477faBill Buzbee dvmChangeStatus(NULL, oldStatus); 109ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng} 110ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 111ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Chengstatic void *compilerThreadStart(void *arg) 112ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng{ 1135ccdf0be4b448c98b595444a77dbaa21471ad1b1Ben Cheng dvmChangeStatus(NULL, THREAD_VMWAIT); 1145ccdf0be4b448c98b595444a77dbaa21471ad1b1Ben Cheng 115ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng dvmLockMutex(&gDvmJit.compilerLock); 116ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng /* 117ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * Since the compiler thread will not touch any objects on the heap once 118ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * being created, we just fake its state as VMWAIT so that it can be a 119ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * bit late when there is suspend request pending. 120ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng */ 121ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng while (!gDvmJit.haltCompilerThread) { 122ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng if (workQueueLength() == 0) { 123ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng int cc; 124ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng cc = pthread_cond_signal(&gDvmJit.compilerQueueEmpty); 125ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng assert(cc == 0); 126ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng pthread_cond_wait(&gDvmJit.compilerQueueActivity, 127ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng &gDvmJit.compilerLock); 128ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng continue; 129ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } else { 130ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng do { 131ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng CompilerWorkOrder work = workDequeue(); 132ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng dvmUnlockMutex(&gDvmJit.compilerLock); 133ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng /* Check whether there is a suspend request on me */ 134ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng dvmCheckSuspendPending(NULL); 1352717622484eb0f7ad537275f7260b2f93324eda2Bill Buzbee /* Is JitTable filling up? */ 1362717622484eb0f7ad537275f7260b2f93324eda2Bill Buzbee if (gDvmJit.jitTableEntriesUsed > 1372717622484eb0f7ad537275f7260b2f93324eda2Bill Buzbee (gDvmJit.jitTableSize - gDvmJit.jitTableSize/4)) { 1382717622484eb0f7ad537275f7260b2f93324eda2Bill Buzbee dvmJitResizeJitTable(gDvmJit.jitTableSize * 2); 1392717622484eb0f7ad537275f7260b2f93324eda2Bill Buzbee } 140ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng if (gDvmJit.haltCompilerThread) { 141ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng LOGD("Compiler shutdown in progress - discarding request"); 142ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } else { 143d726991ba52466cde88e37aba4de2395b62477faBill Buzbee /* If compilation failed, use interpret-template */ 144d726991ba52466cde88e37aba4de2395b62477faBill Buzbee if (!dvmCompilerDoWork(&work)) { 145d726991ba52466cde88e37aba4de2395b62477faBill Buzbee work.result.codeAddress = gDvmJit.interpretTemplate; 146ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } 147d726991ba52466cde88e37aba4de2395b62477faBill Buzbee dvmJitSetCodeAddr(work.pc, work.result.codeAddress, 148d726991ba52466cde88e37aba4de2395b62477faBill Buzbee work.result.instructionSet); 149ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } 150ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng free(work.info); 151ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng dvmLockMutex(&gDvmJit.compilerLock); 152ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } while (workQueueLength() != 0); 153ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } 154ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } 155ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng pthread_cond_signal(&gDvmJit.compilerQueueEmpty); 156ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng dvmUnlockMutex(&gDvmJit.compilerLock); 157ef00a85e7f148f044b14942aa09204e2d0d72738Ben Cheng 1585ccdf0be4b448c98b595444a77dbaa21471ad1b1Ben Cheng /* 1595ccdf0be4b448c98b595444a77dbaa21471ad1b1Ben Cheng * As part of detaching the thread we need to call into Java code to update 1605ccdf0be4b448c98b595444a77dbaa21471ad1b1Ben Cheng * the ThreadGroup, and we should not be in VMWAIT state while executing 1615ccdf0be4b448c98b595444a77dbaa21471ad1b1Ben Cheng * interpreted code. 1625ccdf0be4b448c98b595444a77dbaa21471ad1b1Ben Cheng */ 1635ccdf0be4b448c98b595444a77dbaa21471ad1b1Ben Cheng dvmChangeStatus(NULL, THREAD_RUNNING); 1645ccdf0be4b448c98b595444a77dbaa21471ad1b1Ben Cheng 165ef00a85e7f148f044b14942aa09204e2d0d72738Ben Cheng LOGD("Compiler thread shutting down\n"); 166ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng return NULL; 167ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng} 168ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 169ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Chengbool dvmCompilerSetupCodeCache(void) 170ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng{ 171ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng extern void dvmCompilerTemplateStart(void); 172ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng extern void dmvCompilerTemplateEnd(void); 173ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 174ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng /* Allocate the code cache */ 175ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng gDvmJit.codeCache = mmap(0, CODE_CACHE_SIZE, 176ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng PROT_READ | PROT_WRITE | PROT_EXEC, 177cede69b8119b7091bf2a660b72f9a5568a451ff0Dan Bornstein MAP_PRIVATE | MAP_ANON, -1, 0); 178ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng if (gDvmJit.codeCache == MAP_FAILED) { 179ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng LOGE("Failed to create the code cache: %s\n", strerror(errno)); 180ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng return false; 181ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } 182ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 183ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng /* Copy the template code into the beginning of the code cache */ 184ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng int templateSize = (intptr_t) dmvCompilerTemplateEnd - 185ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng (intptr_t) dvmCompilerTemplateStart; 186ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng memcpy((void *) gDvmJit.codeCache, 187ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng (void *) dvmCompilerTemplateStart, 188ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng templateSize); 1898b258bfd8562edf1306ea6a5642595186f1f3f36Ben Cheng 1908b258bfd8562edf1306ea6a5642595186f1f3f36Ben Cheng gDvmJit.templateSize = templateSize; 191ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng gDvmJit.codeCacheByteUsed = templateSize; 192ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 193b28d3a820d0bc0659bfadf85281383625eae4d5bBen Cheng /* Only flush the part in the code cache that is being used now */ 194ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng cacheflush((intptr_t) gDvmJit.codeCache, 195b28d3a820d0bc0659bfadf85281383625eae4d5bBen Cheng (intptr_t) gDvmJit.codeCache + templateSize, 0); 196ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng return true; 197ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng} 198ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 199ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Chengbool dvmCompilerStartup(void) 200ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng{ 201ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng /* Make sure the BBType enum is in sane state */ 2021465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee assert(kChainingCellNormal == 0); 203ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 204ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng /* Architecture-specific chores to initialize */ 205ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng if (!dvmCompilerArchInit()) 206ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng goto fail; 207ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 208ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng /* 209ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * Setup the code cache if it is not done so already. For apps it should be 210ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * done by the Zygote already, but for command-line dalvikvm invocation we 211ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * need to do it here. 212ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng */ 213ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng if (gDvmJit.codeCache == NULL) { 214ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng if (!dvmCompilerSetupCodeCache()) 215ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng goto fail; 216ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } 217ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 218ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng /* Allocate the initial arena block */ 219ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng if (dvmCompilerHeapInit() == false) { 220ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng goto fail; 221ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } 222ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 223ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng dvmInitMutex(&gDvmJit.compilerLock); 224ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng pthread_cond_init(&gDvmJit.compilerQueueActivity, NULL); 225ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng pthread_cond_init(&gDvmJit.compilerQueueEmpty, NULL); 226ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 227ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng dvmLockMutex(&gDvmJit.compilerLock); 228ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 229ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng gDvmJit.haltCompilerThread = false; 230ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 231ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng /* Reset the work queue */ 232ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng memset(gDvmJit.compilerWorkQueue, 0, 233ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng sizeof(CompilerWorkOrder) * COMPILER_WORK_QUEUE_SIZE); 234ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng gDvmJit.compilerWorkEnqueueIndex = gDvmJit.compilerWorkDequeueIndex = 0; 235ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng gDvmJit.compilerQueueLength = 0; 236ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng gDvmJit.compilerHighWater = 237ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng COMPILER_WORK_QUEUE_SIZE - (COMPILER_WORK_QUEUE_SIZE/4); 238ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 239ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng assert(gDvmJit.compilerHighWater < COMPILER_WORK_QUEUE_SIZE); 240ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng if (!dvmCreateInternalThread(&gDvmJit.compilerHandle, "Compiler", 241ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng compilerThreadStart, NULL)) { 242ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng dvmUnlockMutex(&gDvmJit.compilerLock); 243ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng goto fail; 244ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } 245ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 2468b258bfd8562edf1306ea6a5642595186f1f3f36Ben Cheng /* Track method-level compilation statistics */ 2478b258bfd8562edf1306ea6a5642595186f1f3f36Ben Cheng gDvmJit.methodStatsTable = dvmHashTableCreate(32, NULL); 2488b258bfd8562edf1306ea6a5642595186f1f3f36Ben Cheng 249ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng dvmUnlockMutex(&gDvmJit.compilerLock); 250ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 251ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng return true; 252ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 253ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Chengfail: 254ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng return false; 255ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng} 256ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 257ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Chengvoid dvmCompilerShutdown(void) 258ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng{ 259ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng void *threadReturn; 260ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 261ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng if (gDvmJit.compilerHandle) { 262ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 263ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng gDvmJit.haltCompilerThread = true; 264ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 265ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng dvmLockMutex(&gDvmJit.compilerLock); 266ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng pthread_cond_signal(&gDvmJit.compilerQueueActivity); 267ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng dvmUnlockMutex(&gDvmJit.compilerLock); 268ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 269ef00a85e7f148f044b14942aa09204e2d0d72738Ben Cheng if (pthread_join(gDvmJit.compilerHandle, &threadReturn) != 0) 270ef00a85e7f148f044b14942aa09204e2d0d72738Ben Cheng LOGW("Compiler thread join failed\n"); 271ef00a85e7f148f044b14942aa09204e2d0d72738Ben Cheng else 272ef00a85e7f148f044b14942aa09204e2d0d72738Ben Cheng LOGD("Compiler thread has shut down\n"); 273ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } 274ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng} 275