Dalvik VM make file config and source tree

Source: Internet
Author: User
Dalvik VM compilation script and source code tree

This article briefly analyzes the structure of Dalvik Virtual Machine source code (Dalvik/Vm) and the compilation script (*. mk)

Compile scripts

The directory structure of Dalvik source code is not complex. The compilation script is also very simple. It consists of the following files:

Dalvik/Vm/Android. mk

Dalvik/Vm/reconfiguredvm. mk

Dalvik/Vm/DVM. mk

Similar to other modules in the Android system, Dalvik uses Android. mk as the top-level compilation configuration file or entry. Its content is as follows:

Https://github.com/android/platform_dalvik/blob/master/vm/Android.mk

Let's analyze it from scratch. Note the following for the first time:

## Android.mk for Dalvik VM.## This makefile builds both for host and target, and so the very large# swath of common definitions are factored out into a separate file to# minimize duplication.## If you enable or disable optional features here (or in Dvm.mk),# rebuild the VM with:##  make clean-libdvm clean-libdvm_assert clean-libdvm_sv clean-libdvm_interp#  make -j4 libdvm#

He told us that the compilation file programmed Dalvik into two parts: Host Machine and target machine. In most typical configurations, the host machine is our Linux compilation server. The target machine is our mobile device. To reduce duplication, the compilation configurations required by both the host machine and the target machine are put in a separate file. A separate file is followed by ethics (reconfiguredvm. mk and DVM. mk ).

At the same time, it should also come out after we modified the Dalvik source code, how to compile a clean implementation from the beginning. We will practice it later.

LOCAL_PATH:= $(call my-dir)

Like most modules, assign the Dalvik source code path to the local_path variable. To facilitate later use. Here local_path should be Dalvik/VM.

## Build for the target (device).#ifeq ($(TARGET_CPU_SMP),true)    target_smp_flag := -DANDROID_SMP=1else    target_smp_flag := -DANDROID_SMP=0endifhost_smp_flag := -DANDROID_SMP=1# Build the installed version (libdvm.so) firstinclude $(LOCAL_PATH)/ReconfigureDvm.mk# Overwrite default settingsLOCAL_MODULE_TAGS := optionalLOCAL_MODULE := libdvmLOCAL_CFLAGS += $(target_smp_flag)include $(BUILD_SHARED_LIBRARY)

Compile for the target machine first. First, set the variable target_smp_flag based on whether the target machine supports SMP. Later we will see that this variable is used to pass to the compiler options. Most hosts currently support SMP, so direct replication is supported.

Then we call the script reconfiguredvm. mk. From the name, we can easily guess that the script is used to initialize the compiling environment for DVM compilation. We will see its main content later.

The following is the final compilation target of the actual DVM on the host machine. This is a shared library. The name is libdvm. We can find it on the compiled machine.

Out/target/XXX/libs/libdvm. So

# If WITH_JIT is configured, build multiple versions of libdvm.so to facilitate# correctness/performance bugs triageifeq ($(WITH_JIT),true)    # Derivation #1    # Enable assert and JIT tuning    include $(LOCAL_PATH)/ReconfigureDvm.mk    # Enable assertions and JIT-tuning    LOCAL_CFLAGS += -UNDEBUG -DDEBUG=1 -DLOG_NDEBUG=1 -DWITH_DALVIK_ASSERT \                    -DWITH_JIT_TUNING $(target_smp_flag)    LOCAL_MODULE := libdvm_assert    include $(BUILD_SHARED_LIBRARY)    # Derivation #2    # Enable assert and self-verification    include $(LOCAL_PATH)/ReconfigureDvm.mk    # Enable assertions and JIT self-verification    LOCAL_CFLAGS += -UNDEBUG -DDEBUG=1 -DLOG_NDEBUG=1 -DWITH_DALVIK_ASSERT \                    -DWITH_SELF_VERIFICATION $(target_smp_flag)    LOCAL_MODULE := libdvm_sv    include $(BUILD_SHARED_LIBRARY)    # Derivation #3    # Compile out the JIT    WITH_JIT := false    include $(LOCAL_PATH)/ReconfigureDvm.mk    LOCAL_CFLAGS += $(target_smp_flag)    LOCAL_MODULE := libdvm_interp    include $(BUILD_SHARED_LIBRARY)endif

This part is special to JIT. When the system supports the JIT compiler, DVM compiles three additional target shared libraries to Support the Development Features of DVM. They are

Libdvm_assert is used to open assert in the DVM source code ). We will see in subsequent analysis articles that a large number of assertions are used in DVM implementation to increase runtime checks. When you enable these assertions, any failure in the assertion check will directly cause the DVM to exit unexpectedly. We can find the asserted failure from the trace file to check for possible bugs. In the final release version, assertions will be closed, and which assertions are equivalent to null statements. Therefore, the client will not exit unexpectedly when the final version is DVM.

In addition to assertion, libdvm_sv also provides the self-check capability to check whether the current DVM status is abnormal at some important moments. In the subsequent articles, we will analyze in detail what self-Checks DVM has done.

In the last version, libdvm_interp is used to turn off JIT and compile a DVM instance implemented by the pure interpreter. In this way, we can check whether the behavior after JIT is enabled is different from the DVM implemented by the interpreter.

We can find the three DVM shared libraries generated for debugging in the following directory:

Out/target/XXX/symbol/libs/

The final content is used for compiling the host. All content is wrapped in the following code:

## Build for the host.#ifeq ($(WITH_HOST_DALVIK),true)
...
endif

First, clear the local variable content:

    include $(CLEAR_VARS)

Then, set three compilation variables based on the compiling environment:

    # Variables used in the included Dvm.mk.    dvm_os := $(HOST_OS)    dvm_arch := $(HOST_ARCH)    # Note: HOST_ARCH_VARIANT isn't defined.    dvm_arch_variant := $(HOST_ARCH)

These three variables will eventually be passed to the compiler. They introduce platform-specific behaviors. Because the host does not need to support JIT, set it to false.

WITH_JIT := false
include $(LOCAL_PATH)/Dvm.mk

DVM. mk will be analyzed later.

Next, we will introduce the required libraries for compilation based on the Target Platform:

    LOCAL_SHARED_LIBRARIES += libcrypto libssl libicuuc libicui18n    LOCAL_LDLIBS := -lpthread -ldl    ifeq ($(HOST_OS),linux)      # need this for clock_gettime() in profiling      LOCAL_LDLIBS += -lrt    endif    # Build as a WHOLE static library so dependencies are available at link    # time. When building this target as a regular static library, certain    # dependencies like expat are not found by the linker.    LOCAL_WHOLE_STATIC_LIBRARIES += libexpat libcutils libdex liblog libnativehelper libz    # The libffi from the source tree should never be used by host builds.    # The recommendation is that host builds should always either    # have sufficient custom code so that libffi isn't needed at all,    # or they should use the platform's provided libffi. So, if the common    # build rules decided to include it, axe it back out here.    ifneq (,$(findstring libffi,$(LOCAL_SHARED_LIBRARIES)))        LOCAL_SHARED_LIBRARIES := \            $(patsubst libffi, ,$(LOCAL_SHARED_LIBRARIES))    endif

Finally, the compilation system is told that DVM has two compilation results on the host:

LOCAL_CFLAGS += $(host_smp_flag)    LOCAL_MODULE_TAGS := optional    LOCAL_MODULE := libdvm    include $(BUILD_HOST_SHARED_LIBRARY)    # Copy the dalvik shell script to the host's bin directory    include $(CLEAR_VARS)    LOCAL_IS_HOST_MODULE := true    LOCAL_MODULE_TAGS := optional    LOCAL_MODULE_CLASS := EXECUTABLES    LOCAL_MODULE := dalvik    include $(BUILD_SYSTEM)/base_rules.mk$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/dalvik | $(ACP)@echo "Copy: $(PRIVATE_MODULE) ($@)"$(copy-file-to-new-target)$(hide) chmod 755 $@

They are the DVM shared library libdvm. So and the executable file dalvikvm. We can find them in the compiled directory:

Out/host/XXX/libs/libdvm. So

Out/host/XXX/bin/dalvikvm

As we can see above, DVM may have several compilation results on the target machine, the ultimate shared library libdvm. So, and several shared libraries libsdvm_xx.so used by developers. To compile these goals, we need to first clean up the current compilation environment to eliminate the side effects of the previous goal. This work is put separately in the compilation script reconfiguredvm. mk to reduce duplication. The reconfiguredvm. mk content is as follows:

include $(CLEAR_VARS)# Variables used in the included Dvm.mk.dvm_os := $(TARGET_OS)dvm_arch := $(TARGET_ARCH)dvm_arch_variant := $(TARGET_ARCH_VARIANT)# for now, disable x86-atom variantifeq ($(dvm_arch_variant),x86-atom)dvm_arch_variant := x86endifinclude $(LOCAL_PATH)/Dvm.mkLOCAL_SHARED_LIBRARIES += liblog libcutils libnativehelper libz libdlLOCAL_STATIC_LIBRARIES += libdexLOCAL_C_INCLUDES += external/stlport/stlport bionic/ bionic/libstdc++/includeLOCAL_SHARED_LIBRARIES += libstlport# Don't install on any build by defaultLOCAL_MODULE_TAGS := optional

Its content is not surprising. Clear local variables, set DVM variables, and introduce the library required by DVM. Finally, set local_module_tags to optional to tell the compiling system that DVM will not be compiled unless explicitly specified (include Dalvik/Vm/Android. mk.

The last file DVM. mk sets the definitions required for both the host machine and the target machine. Its content is also intuitive. The complete content is as follows:

Https://github.com/android/platform_dalvik/blob/master/vm/Dvm.mk

First, set the compiler options:

## Compiler defines.#LOCAL_CFLAGS += -fstrict-aliasing -Wstrict-aliasing=2 -fno-align-jumpsLOCAL_CFLAGS += -Wall -Wextra -Wno-unused-parameterLOCAL_CFLAGS += -DARCH_VARIANT=\"$(dvm_arch_variant)\"

Then, determine whether debug_dalvik_vm is specified during compilation:

## Optional features.  These may impact the size or performance of the VM.## Make a debugging version when building the simulator (if not told# otherwise) and when explicitly asked.dvm_make_debug_vm := falseifneq ($(strip $(DEBUG_DALVIK_VM)),)  dvm_make_debug_vm := $(DEBUG_DALVIK_VM)endif

If this option is specified, additional compilation options are enabled. Otherwise, nothing is done:

ifeq ($(dvm_make_debug_vm),true)  #  # "Debug" profile:  # - debugger enabled  # - profiling enabled  # - tracked-reference verification enabled  # - allocation limits enabled  # - GDB helpers enabled  # - LOGV  # - assert()  #  LOCAL_CFLAGS += -DWITH_INSTR_CHECKS  LOCAL_CFLAGS += -DWITH_EXTRA_OBJECT_VALIDATION  LOCAL_CFLAGS += -DWITH_TRACKREF_CHECKS  LOCAL_CFLAGS += -DWITH_EXTRA_GC_CHECKS=1  #LOCAL_CFLAGS += -DCHECK_MUTEX  LOCAL_CFLAGS += -DDVM_SHOW_EXCEPTION=3  # add some extra stuff to make it easier to examine with GDB  LOCAL_CFLAGS += -DEASY_GDB  # overall config may be for a "release" build, so reconfigure these  LOCAL_CFLAGS += -UNDEBUG -DDEBUG=1 -DLOG_NDEBUG=1 -DWITH_DALVIK_ASSERTelse  # !dvm_make_debug_vm  #  # "Performance" profile:  # - all development features disabled  # - compiler optimizations enabled (redundant for "release" builds)  # - (debugging and profiling still enabled)  #  #LOCAL_CFLAGS += -DNDEBUG -DLOG_NDEBUG=1  # "-O2" is redundant for device (release) but useful for sim (debug)  #LOCAL_CFLAGS += -O2 -Winline  #LOCAL_CFLAGS += -DWITH_EXTRA_OBJECT_VALIDATION  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_ASSERTendif  # !dvm_make_debug_vm

Next is the big head of the file, introduce the source file for compilation. These include the source files used by all platforms, such as alloctracker. cpp. To support jit-specific files, such as Compiler/compiler. cpp. The following sections require special attention:

ifeq ($(WITH_COPYING_GC),true)  LOCAL_CFLAGS += -DWITH_COPYING_GC  LOCAL_SRC_FILES += \alloc/Copying.cpp.armelse  LOCAL_SRC_FILES += \alloc/HeapSource.cpp \alloc/MarkSweep.cpp.armendif

This is the type of the specified garbage collector. When with_copying_gc is specified in the compilation option, the copy garbage collector is used; otherwise, the garbage collector is marked with-cleared. We will introduce DVM garbage collection in separate chapters later.

At this point, the parsing of the compiled script is complete. The source code structure of DVM is simple and Its compiling script is clear.

Source code directory tree

Below is the DVM source code directory tree. The following sections describe the most important parts:

Https://github.com/android/platform_dalvik/tree/master/vm

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.