Compiler.cpp revision ccd6c0102d1f898aaea1c94761167fdd083b5275
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--;
41ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
42ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    /* Remember the high water mark of the queue length */
43ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    if (gDvmJit.compilerQueueLength > gDvmJit.compilerMaxQueued)
44ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng        gDvmJit.compilerMaxQueued = gDvmJit.compilerQueueLength;
45ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
46ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    return work;
47ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng}
48ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
49ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Chengbool dvmCompilerWorkEnqueue(const u2 *pc, WorkOrderKind kind, void* info)
50ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng{
51ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    int cc;
52ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    int i;
53ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    int numWork;
54ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
55ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    dvmLockMutex(&gDvmJit.compilerLock);
56ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
57ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    /* Queue full */
58ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    if (gDvmJit.compilerQueueLength == COMPILER_WORK_QUEUE_SIZE ||
59ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng        gDvmJit.codeCacheFull == true) {
60ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng        dvmUnlockMutex(&gDvmJit.compilerLock);
61ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng        return false;
62ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    }
63ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
64ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    for (numWork = gDvmJit.compilerQueueLength,
65ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng           i = gDvmJit.compilerWorkDequeueIndex;
66ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng         numWork > 0;
67ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng         numWork--) {
68ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng        /* Already enqueued */
69ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng        if (gDvmJit.compilerWorkQueue[i++].pc == pc)
70ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng            goto done;
71ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng        /* Wrap around */
72ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng        if (i == COMPILER_WORK_QUEUE_SIZE)
73ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng            i = 0;
74ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    }
75ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
76ccd6c0102d1f898aaea1c94761167fdd083b5275Ben Cheng    CompilerWorkOrder *newOrder =
77ccd6c0102d1f898aaea1c94761167fdd083b5275Ben Cheng        &gDvmJit.compilerWorkQueue[gDvmJit.compilerWorkEnqueueIndex];
78ccd6c0102d1f898aaea1c94761167fdd083b5275Ben Cheng    newOrder->pc = pc;
79ccd6c0102d1f898aaea1c94761167fdd083b5275Ben Cheng    newOrder->kind = kind;
80ccd6c0102d1f898aaea1c94761167fdd083b5275Ben Cheng    newOrder->info = info;
81ccd6c0102d1f898aaea1c94761167fdd083b5275Ben Cheng    newOrder->result.codeAddress = NULL;
82ccd6c0102d1f898aaea1c94761167fdd083b5275Ben Cheng    newOrder->result.discardResult =
83ccd6c0102d1f898aaea1c94761167fdd083b5275Ben Cheng        (kind == kWorkOrderTraceDebug) ? true : false;
84ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    gDvmJit.compilerWorkEnqueueIndex++;
85ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    if (gDvmJit.compilerWorkEnqueueIndex == COMPILER_WORK_QUEUE_SIZE)
86ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng        gDvmJit.compilerWorkEnqueueIndex = 0;
87ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    gDvmJit.compilerQueueLength++;
88ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    cc = pthread_cond_signal(&gDvmJit.compilerQueueActivity);
89ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    assert(cc == 0);
90ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
91ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Chengdone:
92ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    dvmUnlockMutex(&gDvmJit.compilerLock);
93ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    return true;
94ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng}
95ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
96ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* Block until queue length is 0 */
97ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Chengvoid dvmCompilerDrainQueue(void)
98ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng{
99ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    dvmLockMutex(&gDvmJit.compilerLock);
100ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    while (workQueueLength() != 0 && !gDvmJit.haltCompilerThread) {
101ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng        pthread_cond_wait(&gDvmJit.compilerQueueEmpty, &gDvmJit.compilerLock);
102ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    }
103ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    dvmUnlockMutex(&gDvmJit.compilerLock);
104ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng}
105ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
106ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Chengstatic void *compilerThreadStart(void *arg)
107ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng{
1085ccdf0be4b448c98b595444a77dbaa21471ad1b1Ben Cheng    dvmChangeStatus(NULL, THREAD_VMWAIT);
1095ccdf0be4b448c98b595444a77dbaa21471ad1b1Ben Cheng
110ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    dvmLockMutex(&gDvmJit.compilerLock);
111ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    /*
112ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * Since the compiler thread will not touch any objects on the heap once
113ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * being created, we just fake its state as VMWAIT so that it can be a
114ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * bit late when there is suspend request pending.
115ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     */
116ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    while (!gDvmJit.haltCompilerThread) {
117ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng        if (workQueueLength() == 0) {
118ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng            int cc;
119ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng            cc = pthread_cond_signal(&gDvmJit.compilerQueueEmpty);
120ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng            assert(cc == 0);
121ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng            pthread_cond_wait(&gDvmJit.compilerQueueActivity,
122ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng                              &gDvmJit.compilerLock);
123ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng            continue;
124ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng        } else {
125ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng            do {
126ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng                CompilerWorkOrder work = workDequeue();
127ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng                dvmUnlockMutex(&gDvmJit.compilerLock);
128ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng                /* Check whether there is a suspend request on me */
129ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng                dvmCheckSuspendPending(NULL);
1302717622484eb0f7ad537275f7260b2f93324eda2Bill Buzbee                /* Is JitTable filling up? */
1312717622484eb0f7ad537275f7260b2f93324eda2Bill Buzbee                if (gDvmJit.jitTableEntriesUsed >
1322717622484eb0f7ad537275f7260b2f93324eda2Bill Buzbee                    (gDvmJit.jitTableSize - gDvmJit.jitTableSize/4)) {
1332717622484eb0f7ad537275f7260b2f93324eda2Bill Buzbee                    dvmJitResizeJitTable(gDvmJit.jitTableSize * 2);
1342717622484eb0f7ad537275f7260b2f93324eda2Bill Buzbee                }
135ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng                if (gDvmJit.haltCompilerThread) {
136ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng                    LOGD("Compiler shutdown in progress - discarding request");
137ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng                } else {
138ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng                    /* Compilation is successful */
139716f120d7f33ca18a5dcbef811399df0cbefe5d0Bill Buzbee                    if (dvmCompilerDoWork(&work)) {
140716f120d7f33ca18a5dcbef811399df0cbefe5d0Bill Buzbee                        dvmJitSetCodeAddr(work.pc, work.result.codeAddress,
141716f120d7f33ca18a5dcbef811399df0cbefe5d0Bill Buzbee                                          work.result.instructionSet);
142ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng                    }
143ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng                }
144ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng                free(work.info);
145ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng                dvmLockMutex(&gDvmJit.compilerLock);
146ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng            } while (workQueueLength() != 0);
147ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng        }
148ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    }
149ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    pthread_cond_signal(&gDvmJit.compilerQueueEmpty);
150ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    dvmUnlockMutex(&gDvmJit.compilerLock);
151ef00a85e7f148f044b14942aa09204e2d0d72738Ben Cheng
1525ccdf0be4b448c98b595444a77dbaa21471ad1b1Ben Cheng    /*
1535ccdf0be4b448c98b595444a77dbaa21471ad1b1Ben Cheng     * As part of detaching the thread we need to call into Java code to update
1545ccdf0be4b448c98b595444a77dbaa21471ad1b1Ben Cheng     * the ThreadGroup, and we should not be in VMWAIT state while executing
1555ccdf0be4b448c98b595444a77dbaa21471ad1b1Ben Cheng     * interpreted code.
1565ccdf0be4b448c98b595444a77dbaa21471ad1b1Ben Cheng     */
1575ccdf0be4b448c98b595444a77dbaa21471ad1b1Ben Cheng    dvmChangeStatus(NULL, THREAD_RUNNING);
1585ccdf0be4b448c98b595444a77dbaa21471ad1b1Ben Cheng
159ef00a85e7f148f044b14942aa09204e2d0d72738Ben Cheng    LOGD("Compiler thread shutting down\n");
160ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    return NULL;
161ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng}
162ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
163ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Chengbool dvmCompilerSetupCodeCache(void)
164ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng{
165ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    extern void dvmCompilerTemplateStart(void);
166ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    extern void dmvCompilerTemplateEnd(void);
167ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
168ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    /* Allocate the code cache */
169ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    gDvmJit.codeCache = mmap(0, CODE_CACHE_SIZE,
170ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng                          PROT_READ | PROT_WRITE | PROT_EXEC,
171cede69b8119b7091bf2a660b72f9a5568a451ff0Dan Bornstein                          MAP_PRIVATE | MAP_ANON, -1, 0);
172ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    if (gDvmJit.codeCache == MAP_FAILED) {
173ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng        LOGE("Failed to create the code cache: %s\n", strerror(errno));
174ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng        return false;
175ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    }
176ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
177ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    /* Copy the template code into the beginning of the code cache */
178ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    int templateSize = (intptr_t) dmvCompilerTemplateEnd -
179ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng                       (intptr_t) dvmCompilerTemplateStart;
180ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    memcpy((void *) gDvmJit.codeCache,
181ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng           (void *) dvmCompilerTemplateStart,
182ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng           templateSize);
1838b258bfd8562edf1306ea6a5642595186f1f3f36Ben Cheng
1848b258bfd8562edf1306ea6a5642595186f1f3f36Ben Cheng    gDvmJit.templateSize = templateSize;
185ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    gDvmJit.codeCacheByteUsed = templateSize;
186ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
187ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    /* Flush dcache and invalidate the icache to maintain coherence */
188ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    cacheflush((intptr_t) gDvmJit.codeCache,
189ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng               (intptr_t) gDvmJit.codeCache + CODE_CACHE_SIZE, 0);
190ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    return true;
191ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng}
192ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
193ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Chengbool dvmCompilerStartup(void)
194ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng{
195ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    /* Make sure the BBType enum is in sane state */
1961efc9c5e4c5c4c2fccde18e5771c68d064c33bd3Ben Cheng    assert(CHAINING_CELL_NORMAL == 0);
197ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
198ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    /* Architecture-specific chores to initialize */
199ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    if (!dvmCompilerArchInit())
200ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng        goto fail;
201ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
202ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    /*
203ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * Setup the code cache if it is not done so already. For apps it should be
204ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * done by the Zygote already, but for command-line dalvikvm invocation we
205ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     * need to do it here.
206ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng     */
207ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    if (gDvmJit.codeCache == NULL) {
208ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng        if (!dvmCompilerSetupCodeCache())
209ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng            goto fail;
210ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    }
211ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
212ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    /* Allocate the initial arena block */
213ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    if (dvmCompilerHeapInit() == false) {
214ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng        goto fail;
215ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    }
216ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
217ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    dvmInitMutex(&gDvmJit.compilerLock);
218ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    pthread_cond_init(&gDvmJit.compilerQueueActivity, NULL);
219ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    pthread_cond_init(&gDvmJit.compilerQueueEmpty, NULL);
220ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
221ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    dvmLockMutex(&gDvmJit.compilerLock);
222ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
223ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    gDvmJit.haltCompilerThread = false;
224ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
225ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    /* Reset the work queue */
226ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    memset(gDvmJit.compilerWorkQueue, 0,
227ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng           sizeof(CompilerWorkOrder) * COMPILER_WORK_QUEUE_SIZE);
228ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    gDvmJit.compilerWorkEnqueueIndex = gDvmJit.compilerWorkDequeueIndex = 0;
229ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    gDvmJit.compilerQueueLength = 0;
230ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    gDvmJit.compilerHighWater =
231ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng        COMPILER_WORK_QUEUE_SIZE - (COMPILER_WORK_QUEUE_SIZE/4);
232ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
233ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    assert(gDvmJit.compilerHighWater < COMPILER_WORK_QUEUE_SIZE);
234ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    if (!dvmCreateInternalThread(&gDvmJit.compilerHandle, "Compiler",
235ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng                                 compilerThreadStart, NULL)) {
236ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng        dvmUnlockMutex(&gDvmJit.compilerLock);
237ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng        goto fail;
238ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    }
239ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
2408b258bfd8562edf1306ea6a5642595186f1f3f36Ben Cheng    /* Track method-level compilation statistics */
2418b258bfd8562edf1306ea6a5642595186f1f3f36Ben Cheng    gDvmJit.methodStatsTable =  dvmHashTableCreate(32, NULL);
2428b258bfd8562edf1306ea6a5642595186f1f3f36Ben Cheng
243ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    dvmUnlockMutex(&gDvmJit.compilerLock);
244ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
245ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    return true;
246ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
247ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Chengfail:
248ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    return false;
249ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng}
250ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
251ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Chengvoid dvmCompilerShutdown(void)
252ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng{
253ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    void *threadReturn;
254ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
255ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    if (gDvmJit.compilerHandle) {
256ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
257ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng        gDvmJit.haltCompilerThread = true;
258ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
259ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng        dvmLockMutex(&gDvmJit.compilerLock);
260ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng        pthread_cond_signal(&gDvmJit.compilerQueueActivity);
261ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng        dvmUnlockMutex(&gDvmJit.compilerLock);
262ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng
263ef00a85e7f148f044b14942aa09204e2d0d72738Ben Cheng        if (pthread_join(gDvmJit.compilerHandle, &threadReturn) != 0)
264ef00a85e7f148f044b14942aa09204e2d0d72738Ben Cheng            LOGW("Compiler thread join failed\n");
265ef00a85e7f148f044b14942aa09204e2d0d72738Ben Cheng        else
266ef00a85e7f148f044b14942aa09204e2d0d72738Ben Cheng            LOGD("Compiler thread has shut down\n");
267ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng    }
268ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng}
269