OptMain.cpp revision 8911f7a2222124ba724a4a9281555b74d0e098e2
1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License. 6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at 7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and 14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License. 15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Command-line DEX optimization and verification entry point. 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * There are two ways to launch this: 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (1) From the VM. This takes a dozen args, one of which is a file 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * descriptor that acts as both input and output. This allows us to 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * remain ignorant of where the DEX data originally came from. 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (2) From installd or another native application. Pass in a file 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * descriptor for a zip file, a file descriptor for the output, and 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * a filename for debug messages. Many assumptions are made about 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * what's going on (verification + optimization are enabled, boot 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * class path is in BOOTCLASSPATH, etc). 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * There are some fragile aspects around bootclasspath entries, owing 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * largely to the VM's history of working on whenever it thought it needed 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * instead of strictly doing what it was told. If optimizing bootclasspath 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * entries, always do them in the order in which they appear in the path. 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "Dalvik.h" 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "libdex/OptInvocation.h" 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "utils/Log.h" 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "cutils/process_name.h" 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <stdlib.h> 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <stdio.h> 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <string.h> 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic const char* kClassesDex = "classes.dex"; 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Extract "classes.dex" from zipFd into "cacheFd", leaving a little space 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * up front for the DEX optimization header. 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int extractAndProcessZip(int zipFd, int cacheFd, 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* debugFileName, int isBootstrap, const char* bootClassPath, 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* dexoptFlagStr) 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ZipArchive zippy; 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ZipEntry zipEntry; 588911f7a2222124ba724a4a9281555b74d0e098e2Andy McFadden size_t uncompLen; 598911f7a2222124ba724a4a9281555b74d0e098e2Andy McFadden long modWhen, crc32; 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project off_t dexOffset; 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int err; 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int result = -1; 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memset(&zippy, 0, sizeof(zippy)); 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* make sure we're still at the start of an empty file */ 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (lseek(cacheFd, 0, SEEK_END) != 0) { 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("DexOptZ: new cache file '%s' is not empty\n", debugFileName); 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Write a skeletal DEX optimization header. We want the classes.dex 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to come just after it. 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project err = dexOptCreateEmptyHeader(cacheFd); 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (err != 0) 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* record the file position so we can get back here later */ 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexOffset = lseek(cacheFd, 0, SEEK_CUR); 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dexOffset < 0) 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Open the zip archive, find the DEX entry. 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dexZipPrepArchive(zipFd, debugFileName, &zippy) != 0) { 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("DexOptZ: unable to open zip archive '%s'\n", debugFileName); 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project zipEntry = dexZipFindEntry(&zippy, kClassesDex); 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (zipEntry == NULL) { 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("DexOptZ: zip archive '%s' does not include %s\n", 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project debugFileName, kClassesDex); 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Extract some info about the zip entry. 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1038911f7a2222124ba724a4a9281555b74d0e098e2Andy McFadden if (dexZipGetEntryInfo(&zippy, zipEntry, NULL, &uncompLen, NULL, NULL, 1048911f7a2222124ba724a4a9281555b74d0e098e2Andy McFadden &modWhen, &crc32) != 0) 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("DexOptZ: zip archive GetEntryInfo failed on %s\n", debugFileName); 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uncompLen = uncompLen; 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project modWhen = modWhen; 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project crc32 = crc32; 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Extract the DEX data into the cache file at the current offset. 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1178911f7a2222124ba724a4a9281555b74d0e098e2Andy McFadden if (dexZipExtractEntryToFile(&zippy, zipEntry, cacheFd) != 0) { 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("DexOptZ: extraction of %s from %s failed\n", 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kClassesDex, debugFileName); 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Prep the VM and perform the optimization. 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexClassVerifyMode verifyMode = VERIFY_MODE_ALL; 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexOptimizerMode dexOptMode = OPTIMIZE_MODE_VERIFIED; 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int dexoptFlags = 0; /* bit flags, from enum DexoptFlags */ 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dexoptFlagStr[0] != '\0') { 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* opc; 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* val; 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project opc = strstr(dexoptFlagStr, "v="); /* verification */ 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (opc != NULL) { 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (*(opc+2)) { 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'n': verifyMode = VERIFY_MODE_NONE; break; 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'r': verifyMode = VERIFY_MODE_REMOTE; break; 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'a': verifyMode = VERIFY_MODE_ALL; break; 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: break; 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project opc = strstr(dexoptFlagStr, "o="); /* optimization */ 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (opc != NULL) { 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (*(opc+2)) { 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'n': dexOptMode = OPTIMIZE_MODE_NONE; break; 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'v': dexOptMode = OPTIMIZE_MODE_VERIFIED; break; 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'a': dexOptMode = OPTIMIZE_MODE_ALL; break; 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: break; 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project opc = strstr(dexoptFlagStr, "m=y"); /* register map */ 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (opc != NULL) { 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexoptFlags |= DEXOPT_GEN_REGISTER_MAPS; 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmPrepForDexOpt(bootClassPath, dexOptMode, verifyMode, 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexoptFlags) != 0) 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("DexOptZ: VM init failed\n"); 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //vmStarted = 1; 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* do the optimization */ 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmContinueOptimization(cacheFd, dexOffset, uncompLen, debugFileName, 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project modWhen, crc32, isBootstrap)) 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("Optimization failed\n"); 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* we don't shut the VM down -- process is about to exit */ 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = 0; 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail: 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexZipCloseArchive(&zippy); 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* advance to the next arg and extract it */ 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define GET_ARG(_var, _func, _msg) \ 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { \ 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* endp; \ 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (_var) = _func(*++argv, &endp, 0); \ 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (*endp != '\0') { \ 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("%s '%s'", _msg, *argv); \ 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; \ 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } \ 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project --argc; \ 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Parse arguments. We want: 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 0. (name of dexopt command -- ignored) 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1. "--zip" 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2. zip fd (input, read-only) 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 3. cache fd (output, read-write, locked with flock) 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 4. filename of file being optimized (used for debug messages and 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * for comparing against BOOTCLASSPATH -- does not need to be 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * accessible or even exist) 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 5. dexopt flags 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The BOOTCLASSPATH environment variable is assumed to hold the correct 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * boot class path. If the filename provided appears in the boot class 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * path, the path will be truncated just before that entry (so that, if 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you were to dexopt "core.jar", your bootclasspath would be empty). 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This does not try to normalize the boot class path name, so the 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * filename test won't catch you if you get creative. 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int fromZip(int argc, char* const argv[]) 217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int result = -1; 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int zipFd, cacheFd, vmBuildVersion; 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* inputFileName; 221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* bcpCopy = NULL; 222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* dexoptFlagStr; 223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (argc != 6) { 225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("Wrong number of args for --zip (found %d)\n", argc); 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* skip "--zip" */ 230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project argc--; 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project argv++; 232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project GET_ARG(zipFd, strtol, "bad zip fd"); 234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project GET_ARG(cacheFd, strtol, "bad cache fd"); 235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project inputFileName = *++argv; 236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project --argc; 237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexoptFlagStr = *++argv; 238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project --argc; 239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Check to see if this is a bootstrap class entry. If so, truncate 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the path. 243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* bcp = getenv("BOOTCLASSPATH"); 245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (bcp == NULL) { 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("DexOptZ: BOOTCLASSPATH not set\n"); 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int isBootstrap = false; 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* match = strstr(bcp, inputFileName); 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (match != NULL) { 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * TODO: we have a partial string match, but that doesn't mean 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * we've matched an entire path component. We should make sure 256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * that we're matching on the full inputFileName, and if not we 257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * should re-do the strstr starting at (match+1). 258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The scenario would be a bootclasspath with something like 260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "/system/framework/core.jar" while we're trying to optimize 261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "/framework/core.jar". Not very likely since all paths are 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * absolute and end with ".jar", but not impossible. 263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int matchOffset = match - bcp; 265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (matchOffset > 0 && bcp[matchOffset-1] == ':') 266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project matchOffset--; 267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV("DexOptZ: found '%s' in bootclasspath, cutting off at %d\n", 268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project inputFileName, matchOffset); 269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bcpCopy = strdup(bcp); 270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bcpCopy[matchOffset] = '\0'; 271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bcp = bcpCopy; 273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGD("DexOptZ: truncated BOOTCLASSPATH to '%s'\n", bcp); 274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project isBootstrap = true; 275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = extractAndProcessZip(zipFd, cacheFd, inputFileName, 278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project isBootstrap, bcp, dexoptFlagStr); 279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail: 281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(bcpCopy); 282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Parse arguments for an "old-style" invocation directly from the VM. 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Here's what we want: 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 0. (name of dexopt command -- ignored) 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1. "--dex" 291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2. DALVIK_VM_BUILD value, as a sanity check 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 3. file descriptor, locked with flock, for DEX file being optimized 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 4. DEX offset within file 294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 5. DEX length 295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 6. filename of file being optimized (for debug messages only) 296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 7. modification date of source (goes into dependency section) 297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 8. CRC of source (goes into dependency section) 298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 9. flags (optimization level, isBootstrap) 299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 10. bootclasspath entry #1 300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 11. bootclasspath entry #2 301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ... 302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * dvmOptimizeDexFile() in dalvik/vm/analysis/DexOptimize.c builds the 304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * argument list and calls this executable. 305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The bootclasspath entries become the dependencies for this DEX file. 307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The open file descriptor MUST NOT be for one of the bootclasspath files. 309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The parent has the descriptor locked, and we'll try to lock it again as 310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * part of processing the bootclasspath. (We can catch this and return 311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * an error by comparing filenames or by opening the bootclasspath files 312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * and stat()ing them for inode numbers). 313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int fromDex(int argc, char* const argv[]) 315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int result = -1; 317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool vmStarted = false; 318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* bootClassPath = NULL; 319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int fd, flags, vmBuildVersion; 320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long offset, length; 321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* debugFileName; 322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 crc, modWhen; 323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* endp; 324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (argc < 10) { 326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* don't have all mandatory args */ 327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("Not enough arguments for --dex (found %d)\n", argc); 328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* skip "--dex" */ 332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project argc--; 333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project argv++; 334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Extract the args. 337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project GET_ARG(vmBuildVersion, strtol, "bad vm build"); 339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (vmBuildVersion != DALVIK_VM_BUILD) { 34087cf7312247b341b54be26904e3600e98967d695Andy McFadden LOGE("DexOpt: build rev does not match VM: %d vs %d\n", 341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vmBuildVersion, DALVIK_VM_BUILD); 342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project GET_ARG(fd, strtol, "bad fd"); 345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project GET_ARG(offset, strtol, "bad offset"); 346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project GET_ARG(length, strtol, "bad length"); 347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project debugFileName = *++argv; 348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project --argc; 349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project GET_ARG(modWhen, strtoul, "bad modWhen"); 350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project GET_ARG(crc, strtoul, "bad crc"); 351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project GET_ARG(flags, strtol, "bad flags"); 352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV("Args: fd=%d off=%ld len=%ld name='%s' mod=0x%x crc=0x%x flg=%d (argc=%d)\n", 354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fd, offset, length, debugFileName, modWhen, crc, flags, argc); 355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(argc > 0); 356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (--argc == 0) { 358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bootClassPath = strdup(""); 359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i, bcpLen; 361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* const* argp; 362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* cp; 363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bcpLen = 0; 365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0, argp = argv; i < argc; i++) { 366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ++argp; 367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV("DEP: '%s'\n", *argp); 368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bcpLen += strlen(*argp) + 1; 369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cp = bootClassPath = (char*) malloc(bcpLen +1); 372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0, argp = argv; i < argc; i++) { 373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int strLen; 374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ++argp; 376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project strLen = strlen(*argp); 377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (i != 0) 378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *cp++ = ':'; 379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memcpy(cp, *argp, strLen); 380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cp += strLen; 381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *cp = '\0'; 383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert((int) strlen(bootClassPath) == bcpLen-1); 385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV(" bootclasspath is '%s'\n", bootClassPath); 387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* start the VM partway */ 389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool onlyOptVerifiedDex = false; 390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexClassVerifyMode verifyMode; 391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DexOptimizerMode dexOptMode; 392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int dexoptFlags = 0; 393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* ugh -- upgrade these to a bit field if they get any more complex */ 395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((flags & DEXOPT_VERIFY_ENABLED) != 0) { 396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((flags & DEXOPT_VERIFY_ALL) != 0) 397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifyMode = VERIFY_MODE_ALL; 398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifyMode = VERIFY_MODE_REMOTE; 400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verifyMode = VERIFY_MODE_NONE; 402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((flags & DEXOPT_OPT_ENABLED) != 0) { 404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((flags & DEXOPT_OPT_ALL) != 0) 405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexOptMode = OPTIMIZE_MODE_ALL; 406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexOptMode = OPTIMIZE_MODE_VERIFIED; 408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexOptMode = OPTIMIZE_MODE_NONE; 410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((flags & DEXOPT_GEN_REGISTER_MAP) != 0) { 412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexoptFlags |= DEXOPT_GEN_REGISTER_MAPS; 413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmPrepForDexOpt(bootClassPath, dexOptMode, verifyMode, 416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dexoptFlags) != 0) 417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("VM init failed\n"); 419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vmStarted = true; 423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* do the optimization */ 425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmContinueOptimization(fd, offset, length, debugFileName, 426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project modWhen, crc, (flags & DEXOPT_IS_BOOTSTRAP) != 0)) 427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("Optimization failed\n"); 429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = 0; 433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail: 435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * In theory we should gracefully shut the VM down at this point. In 437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * practice that only matters if we're checking for memory leaks with 438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * valgrind -- simply exiting is much faster. 439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * As it turns out, the DEX optimizer plays a little fast and loose 441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * with class loading. We load all of the classes from a partially- 442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * formed DEX file, which is unmapped when we're done. If we want to 443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * do clean shutdown here, perhaps for testing with valgrind, we need 444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to skip the munmap call there. 445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0 447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (vmStarted) { 448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGI("DexOpt shutting down, result=%d\n", result); 449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmShutdown(); 450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //dvmLinearAllocDump(NULL); 454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0 456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project extern int gDvm__totalInstr, gDvm__gcInstr, gDvm__gcData, 458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm__gcSimpleData; 459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGI("GC DATA: totinst=%d, gcinst=%d, gcdata=%d simpled=%d\n", 460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm__totalInstr, gDvm__gcInstr, gDvm__gcData, gDvm__gcSimpleData); 461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(bootClassPath); 465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV("DexOpt command complete (result=%d)\n", result); 466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Main entry point. Decide where to go. 471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint main(int argc, char* const argv[]) 473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project set_process_name("dexopt"); 475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project setvbuf(stdout, NULL, _IONBF, 0); 477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (argc > 1) { 479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (strcmp(argv[1], "--zip") == 0) 480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return fromZip(argc, argv); 481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else if (strcmp(argv[1], "--dex") == 0) 482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return fromDex(argc, argv); 483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, "Usage: don't use this\n"); 486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 1; 487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 489