From: Jim Huang Date: Mon, 13 Sep 2010 12:04:09 +0000 (+0800) Subject: Use GCC visibility to reduce the size of libdvm by 10% X-Git-Tag: android-x86-2.2 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=ca4fd209d67b9e783f7ad8a1512aa85aa2aba083;p=android-x86%2Fdalvik.git Use GCC visibility to reduce the size of libdvm by 10% Originally, libdvm exports many ELF symbols, but Zygote and other applications don't really depend on all of them. This change hides most of the symbols which would have previously (and unnecessarily) been public. This means, it improves load time of libdvm, and the link optimizer could produce better code as well. The technique is applied in the "Performance" profile. Reference experimental results of Qualcomm MSM7x25: (524 MHz) [before] (1) number of ELF symbols (when WITH_JIT=true) # arm-eabi-nm --dynamic ./system/lib/libdvm.so | grep "T " | wc -l 1222 (2) dlopen/dlsym time 76906 us (3) code size ./system/lib/libdvm.so 601480 bytes [after] (1) number of ELF symbols (when WITH_JIT=true) # arm-eabi-nm --dynamic ./system/lib/libdvm.so | grep "T " | wc -l 58 (2) dlopen/dlsym time 72296 us (3) code size ./system/lib/libdvm.so 540016 bytes * dlopen/dlsym time: the time consumption from dlopen "libdvm" to dlsym "dvmPrepForDexOpt" Change-Id: I47fcf0da1acd970ff136378661360d3328c9c6c0 --- diff --git a/dalvikdefines.h b/dalvikdefines.h new file mode 100644 index 000000000..4329fcf94 --- /dev/null +++ b/dalvikdefines.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * Dalvik implementation specific definitions. + */ + +#ifndef _DALVIK_DEFINES_H +#define _DALVIK_DEFINES_H + +#if defined(ANDROID) + +/* Use GCC visibility */ +#define DVM_EXPORT __attribute__((visibility("default"))) +#define DEX_EXPORT DVM_EXPORT + +#else + +#define DVM_EXPORT +#define DEX_EXPORT + +#endif + +#endif /* ! _DALVIK_DEFINES_H */ diff --git a/libdex/Android.mk b/libdex/Android.mk index df45f045a..4a6ef9a31 100644 --- a/libdex/Android.mk +++ b/libdex/Android.mk @@ -44,8 +44,25 @@ dex_include_files := \ ifneq ($(SDK_ONLY),true) # SDK_only doesn't need device version include $(CLEAR_VARS) + +# Make a debugging version when building the simulator (if not told +# otherwise) and when explicitly asked. +dvm_make_debug_vm := false +ifeq ($(strip $(DEBUG_DALVIK_VM)),) + ifeq ($(dvm_simulator),true) + dvm_make_debug_vm := true + endif +else + dvm_make_debug_vm := $(DEBUG_DALVIK_VM) +endif + LOCAL_SRC_FILES := $(dex_src_files) LOCAL_C_INCLUDES += $(dex_include_files) +LOCAL_CFLAGS += -include "dalvikdefines.h" +ifeq ($(dvm_make_debug_vm),false) + # hide ELF symbols to reduce code size + LOCAL_CFLAGS += -fvisibility=hidden +endif LOCAL_MODULE := libdex include $(BUILD_STATIC_LIBRARY) @@ -60,5 +77,6 @@ endif # !SDK_ONLY include $(CLEAR_VARS) LOCAL_SRC_FILES := $(dex_src_files) LOCAL_C_INCLUDES += $(dex_include_files) +LOCAL_CFLAGS += -include "dalvikdefines.h" LOCAL_MODULE := libdex include $(BUILD_HOST_STATIC_LIBRARY) diff --git a/libdex/OptInvocation.c b/libdex/OptInvocation.c index 8ce918b97..ae0e2373e 100644 --- a/libdex/OptInvocation.c +++ b/libdex/OptInvocation.c @@ -116,6 +116,7 @@ char* dexOptGenerateCacheFileName(const char* fileName, const char* subFileName) * * Returns 0 on success, errno on failure. */ +DEX_EXPORT int dexOptCreateEmptyHeader(int fd) { DexOptHeader optHdr; diff --git a/libdex/ZipArchive.c b/libdex/ZipArchive.c index 7c7e18e95..48e8fd985 100644 --- a/libdex/ZipArchive.c +++ b/libdex/ZipArchive.c @@ -300,6 +300,7 @@ int dexZipOpenArchive(const char* fileName, ZipArchive* pArchive) /* * Prepare to access a ZipArchive in an open file descriptor. */ +DEX_EXPORT int dexZipPrepArchive(int fd, const char* debugFileName, ZipArchive* pArchive) { MemMapping map; @@ -347,6 +348,7 @@ bail: * * NOTE: the ZipArchive may not have been fully created. */ +DEX_EXPORT void dexZipCloseArchive(ZipArchive* pArchive) { LOGV("Closing archive %p\n", pArchive); @@ -370,6 +372,7 @@ void dexZipCloseArchive(ZipArchive* pArchive) * * Returns 0 if not found. */ +DEX_EXPORT ZipEntry dexZipFindEntry(const ZipArchive* pArchive, const char* entryName) { int nameLen = strlen(entryName); @@ -424,6 +427,7 @@ ZipEntry findEntryByIndex(ZipArchive* pArchive, int idx) * Returns "false" if the offsets to the fields or the contents of the fields * appear to be bogus. */ +DEX_EXPORT bool dexZipGetEntryInfo(const ZipArchive* pArchive, ZipEntry entry, int* pMethod, long* pUncompLen, long* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32) @@ -599,6 +603,7 @@ bail: * TODO: this doesn't verify the data's CRC, but probably should (especially * for uncompressed data). */ +DEX_EXPORT bool dexZipExtractEntryToFile(const ZipArchive* pArchive, const ZipEntry entry, int fd) { diff --git a/vm/Dvm.mk b/vm/Dvm.mk index baf41c6e9..ddc851908 100644 --- a/vm/Dvm.mk +++ b/vm/Dvm.mk @@ -26,6 +26,7 @@ # LOCAL_CFLAGS += -fstrict-aliasing -Wstrict-aliasing=2 -fno-align-jumps #LOCAL_CFLAGS += -DUSE_INDIRECT_REF +LOCAL_CFLAGS += -include "dalvikdefines.h" # # Optional features. These may impact the size or performance of the VM. @@ -64,6 +65,7 @@ ifeq ($(dvm_make_debug_vm),true) # - GDB helpers enabled # - LOGV # - assert() + # - full ELF symbols # LOCAL_CFLAGS += -DWITH_INSTR_CHECKS LOCAL_CFLAGS += -DWITH_EXTRA_OBJECT_VALIDATION @@ -83,6 +85,7 @@ else # !dvm_make_debug_vm # - all development features disabled # - compiler optimizations enabled (redundant for "release" builds) # - (debugging and profiling still enabled) + # - minimize ELF symbols to reduce code size by 10% # #LOCAL_CFLAGS += -DNDEBUG -DLOG_NDEBUG=1 # "-O2" is redundant for device (release) but useful for sim (debug) @@ -91,6 +94,8 @@ else # !dvm_make_debug_vm LOCAL_CFLAGS += -DDVM_SHOW_EXCEPTION=1 # if you want to try with assertions on the device, add: #LOCAL_CFLAGS += -UNDEBUG -DDEBUG=1 -DLOG_NDEBUG=1 -DWITH_DALVIK_ASSERT + # use GCC Visibility to reduce the footprint of runtime library + LOCAL_CFLAGS += -fvisibility=hidden endif # !dvm_make_debug_vm # bug hunting: checksum and verify interpreted stack when making JNI calls diff --git a/vm/Init.c b/vm/Init.c index 66303958c..ab1be0eee 100644 --- a/vm/Init.c +++ b/vm/Init.c @@ -1491,6 +1491,7 @@ static bool dvmInitJDWP(void) * * Returns 0 on success. */ +DVM_EXPORT int dvmPrepForDexOpt(const char* bootClassPath, DexOptimizerMode dexOptMode, DexClassVerifyMode verifyMode, int dexoptFlags) { diff --git a/vm/Jni.c b/vm/Jni.c index 6692f3bb5..9ce2f8026 100644 --- a/vm/Jni.c +++ b/vm/Jni.c @@ -4255,6 +4255,7 @@ void dvmLateEnableCheckedJni(void) /* * Not supported. */ +DVM_EXPORT jint JNI_GetDefaultJavaVMInitArgs(void* vm_args) { return JNI_ERR; @@ -4265,6 +4266,7 @@ jint JNI_GetDefaultJavaVMInitArgs(void* vm_args) * * We always have zero or one. */ +DVM_EXPORT jint JNI_GetCreatedJavaVMs(JavaVM** vmBuf, jsize bufLen, jsize* nVMs) { if (gDvm.vmList != NULL) { @@ -4286,6 +4288,7 @@ jint JNI_GetCreatedJavaVMs(JavaVM** vmBuf, jsize bufLen, jsize* nVMs) * The current thread becomes the main VM thread. We return immediately, * which effectively means the caller is executing in a native method. */ +DVM_EXPORT jint JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args) { const JavaVMInitArgs* args = (JavaVMInitArgs*) vm_args; diff --git a/vm/analysis/DexOptimize.c b/vm/analysis/DexOptimize.c index a5b8b6fa0..b134a3f27 100644 --- a/vm/analysis/DexOptimize.c +++ b/vm/analysis/DexOptimize.c @@ -508,6 +508,7 @@ bool dvmOptimizeDexFile(int fd, off_t dexOffset, long dexLength, * * Returns "true" on success. */ +DVM_EXPORT bool dvmContinueOptimization(int fd, off_t dexOffset, long dexLength, const char* fileName, u4 modWhen, u4 crc, bool isBootstrap) {