OSDN Git Service

Use GCC visibility to reduce the size of libdvm by 10% android-x86-2.2
authorJim Huang <jserv@0xlab.org>
Mon, 13 Sep 2010 12:04:09 +0000 (20:04 +0800)
committerChih-Wei Huang <cwhuang@linux.org.tw>
Fri, 12 Nov 2010 09:09:02 +0000 (17:09 +0800)
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

dalvikdefines.h [new file with mode: 0644]
libdex/Android.mk
libdex/OptInvocation.c
libdex/ZipArchive.c
vm/Dvm.mk
vm/Init.c
vm/Jni.c
vm/analysis/DexOptimize.c

diff --git a/dalvikdefines.h b/dalvikdefines.h
new file mode 100644 (file)
index 0000000..4329fcf
--- /dev/null
@@ -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 */
index df45f04..4a6ef9a 100644 (file)
@@ -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)
index 8ce918b..ae0e237 100644 (file)
@@ -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;
index 7c7e18e..48e8fd9 100644 (file)
@@ -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)
 {
index baf41c6..ddc8519 100644 (file)
--- 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
index 6630395..ab1be0e 100644 (file)
--- 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)
 {
index 6692f3b..9ce2f80 100644 (file)
--- 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;
index a5b8b6f..b134a3f 100644 (file)
@@ -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)
 {