• ## Dalvik

千次阅读 2012-07-19 10:44:36
The Dalvik virtual machine is intended to run on a variety of platforms.The baseline system is expected to be a variant of UNIX (Linux, BSD, MacOS X) running the GNU C compiler. Little-endian CPUs hav
The Dalvik virtual machine is intended to run on a variety of platforms.The baseline system is expected to be a variant of UNIX (Linux, BSD, MacOS X) running the GNU C compiler. Little-endian CPUs have been exercisedthe most heavily, but big-endian systems
are explicitly supported.
There are two general categories of work: porting to a Linux systemwith a previously unseen CPU architecture, and porting to a differentoperating system. This document covers the former.

Core Libraries
The native code in the core libraries (chiefly dalvik/libcore,but also
dalvik/vm/native) is written in C/C++ and is expectedto work without modification in a Linux environment. Much of the codecomes directly from the Apache Harmony project.
The core libraries pull in code from many other projects, includingOpenSSL, zlib, and ICU. These will also need to be ported before the VMcan be used.

JNI Call Bridge
Most of the Dalvik VM runtime is written in portable C. The onenon-portable component of the runtime is the JNI call bridge. Simply put,this converts an array of integers into function arguments of varioustypes, and calls a function. This must be done according
to the C callingconventions for the platform. The task could be as simple as pushing allof the arguments onto the stack, or involve complex rules for registerassignment and stack alignment.
To ease porting to new platforms, the
open-source FFI library (Foreign Function Interface) is used when acustom bridge is unavailable. FFI is not as fast as a native implementation,and the optional performance improvements it does offer are not used, sowriting a replacement is a good first
step.
The code lives in dalvik/vm/arch/*, with the FFI-based versionin the "generic" directory. There are two source files for each architecture.One defines the call bridge itself:
void dvmPlatformInvoke(void* pEnv, ClassObject* clazz, int argInfo,int argc, const u4* argv, const char* signature, void* func,JValue* pReturn)

This will invoke a C/C++ function declared:
return_type func(JNIEnv* pEnv, Object* this [, args])
or (for a "static" method):
return_type func(JNIEnv* pEnv, ClassObject* clazz [, args])

The role of dvmPlatformInvoke is to convert the values inargv into C-style calling conventions, call the method, andthen place the return type into
pReturn (a union that holdsall of the basic JNI types). The code may use the method signature(a DEX "shorty" signature, with one character for the return type and oneper argument) to determine how to handle the values.
The other source file involved here defines a 32-bit "hint". The hintis computed when the method's class is loaded, and passed in as the"argInfo" argument. The hint can be used to avoid scanning the ASCIImethod signature for things like the return value,
total argument size,or inter-argument 64-bit alignment restrictions.

Interpreter
The Dalvik runtime includes two interpreters, labeled "portable" and "fast".The portable interpreter is largely contained within a single C function,and should compile on any system that supports gcc. (If you don't have gcc,you may need to disable the "threaded"
execution model, which relies ongcc's "goto table" implementation; look for the THREADED_INTERP define.)
The fast interpreter uses hand-coded assembly fragments. If none areavailable for the current architecture, the build system will create aninterpreter out of C "stubs". The resulting "all stubs" interpreter isquite a bit slower than the portable interpreter,
making "fast" somethingof a misnomer.
The fast interpreter is enabled by default. On platforms without nativesupport, you may want to switch to the portable interpreter. This canbe controlled with the
dalvik.vm.execution-mode systemproperty. For example, if you:
adb shell "echo dalvik.vm.execution-mode = int:portable >> /data/local.prop"

and reboot, the Android app framework will start the VM with the portableinterpreter enabled.
Mterp Interpreter Structure
There may be significant performance advantages to rewriting theinterpreter core in assembly language, using architecture-specificoptimizations. In Dalvik this can be done one instruction at a time.
The simplest way to implement an interpreter is to have a large "switch"statement. After each instruction is handled, the interpreter returns tothe top of the loop, fetches the next instruction, and jumps to theappropriate label.
An improvement on this is called "threaded" execution. The instructionfetch and dispatch are included at the end of every instruction handler.This makes the interpreter a little larger overall, but you get to avoidthe (potentially expensive) branch back
to the top of the switch statement.
Dalvik mterp goes one step further, using a computed goto instead of a gototable. Instead of looking up the address in a table, which requires anextra memory fetch on every instruction, mterp multiplies the opcode numberby a fixed value. By default, each
handler is allowed 64 bytes of space.
Not all handlers fit in 64 bytes. Those that don't can have subroutinesor simply continue on to additional code outside the basic space. Some ofthis is handled automatically by Dalvik, but there's no portable way to detectoverflow of a 64-byte handler until
the VM starts executing.
The choice of 64 bytes is somewhat arbitrary, but has worked out well forARM and x86.
In the course of development it's useful to have C and assemblyimplementations of each handler, and be able to flip back and forthbetween them when hunting problems down. In mterp this is relativelystraightforward. You can always see the files being fed
to the compilerand assembler for your platform by looking in thedalvik/vm/mterp/out directory.
The interpreter sources live in dalvik/vm/mterp. If youhaven't yet, you should read
dalvik/vm/mterp/README.txt now.
Getting Started With Mterp
Getting started:
Decide on the name of your architecture. For the sake of discussion,let's call it
myarch.Make a copy of dalvik/vm/mterp/config-allstubs todalvik/vm/mterp/config-myarch.Create a dalvik/vm/mterp/myarch directory to hold yoursource files.Add myarch to the list indalvik/vm/mterp/rebuild.sh.Make sure dalvik/vm/Android.mk will find the files foryour architecture. If
$(TARGET_ARCH) is configured thiswill happen automatically.You now have the basic framework in place. Whenever you make a change, youneed to perform two steps: regenerate the mterp output, and build thecore VM library. (It's two steps because we didn't want the build systemto require Python 2.5. Which, incidentally, you need to have.) In the dalvik/vm/mterp directory, regenerate the contentsof the files in dalvik/vm/mterp/out by executing./rebuild.sh. Note there are two files, one in C and onein assembly.In the dalvik directory, regenerate thelibdvm.so library with mm. You can also usemake libdvm from the top of the tree.This will leave you with an updated libdvm.so, which can be pushed out toa device with adb sync or adb push. If you'reusing the emulator, you need to add make snod (System image,NO Dependency check) to rebuild the system image file. You should notneed to do a top-level "make" and rebuild the dependent binaries. At this point you have an "all stubs" interpreter. You can see how itworks by examining dalvik/vm/mterp/cstubs/entry.c. Thecode runs in a loop, pulling out the next opcode, and invoking thehandler through a function pointer. Each handler takes a "glue" argumentthat contains all of the useful state. Your goal is to replace the entry method, exit method, and each individualinstruction with custom implementations. The first thing you need to dois create an entry function that calls the handler for the first instruction.After that, the instructions chain together, so you don't need a loop.(Look at the ARM or x86 implementation to see how they work.) Once you have that, you need something to jump to. You can't branchdirectly to the C stub because it's expecting to be called with a "glue"argument and then return. We need a C stub "wrapper" that does thesetup and jumps directly to the next handler. We write this in assemblyand then add it to the config file definition. To see how this works, create a file calleddalvik/vm/mterp/myarch/stub.S that contains one line: /* stub for${opcode} */

Then, in dalvik/vm/mterp/config-myarch, add this below thehandler-size directive:

# source for the instruction table stub
asm-stub myarch/stub.S

Regenerate the sources with ./rebuild.sh, and take a lookinside 
dalvik/vm/mterp/out/InterpAsm-myarch.S. You shouldsee 256 copies of the stub function in a single large block after thedvmAsmInstructionStart label. The
stub.S code will be used anywhere you don't provide an assembly implementation.
Note that each block begins with a .balign 64 directive.This is what pads each handler out to 64 bytes. Note also that the${opcode} text changed into an opcode name, which shouldbe used to call the C implementation (dvmMterp_${opcode}).
The actual contents of stub.S are up to you to define.See entry.S and
stub.S in the armv5te or x86 directories for working examples.
If you're working on a variation of an existing architecture, you may beable to use most of the existing code and just provide replacements fora few instructions. Look at the
armv4t implementation asan example.
Replacing Stubs
There are roughly 230 Dalvik opcodes, including some that are inserted bydexopt and aren't described in theDalvik bytecode
documentation. Eachone must perform the appropriate actions, fetch the next opcode, andbranch to the next handler. The actions performed by the assembly versionmust exactly match those performed by the C version (indalvik/vm/mterp/c/OP_*).
It is possible to customize the set of "optimized" instructions for yourplatform. This is possible because optimized DEX files are not expectedto work on multiple devices. Adding, removing, or redefining instructionsis beyond the scope of this document,
and for simplicity it's best to stickwith the basic set defined by the portable interpreter.
Once you have written a handler that looks like it should work, addit to the config file. For example, suppose we have a working versionof
OP_NOP. For demonstration purposes, fake it for now byputting this into
dalvik/vm/mterp/myarch/OP_NOP.S:

/* This is my NOP handler */

Then, in the op-start section of config-myarch, add:

op OP_NOP myarch

This tells the generation script to use the assembly version from themyarch directory instead of the C version from the
c directory.
Execute ./rebuild.sh. Look at InterpAsm-myarch.S and
InterpC-myarch.c in the out directory. Youwill see that the
OP_NOP stub wrapper has been replaced with ournew code in the assembly file, and the C stub implementation is no longerincluded.
As you implement instructions, the C version and corresponding stub wrapperwill disappear from the output files. Eventually you will have a 100%assembly interpreter.
Interpreter Switching
The Dalvik VM actually includes a third interpreter implementation: the debuginterpreter. This is a variation of the portable interpreter that includessupport for debugging and profiling.
When a debugger attaches, or a profiling feature is enabled, the VMwill switch interpreters at a convenient point. This is done at thesame time as the GC safe point check: on a backward branch, a methodreturn, or an exception throw. Similarly, when the debugger
detachesor profiling is discontinued, execution transfers back to the "fast" or"portable" interpreter.
Your entry function needs to test the "entryPoint" value in the "glue"pointer to determine where execution should begin. Your exit functionwill need to return a boolean that indicates whether the interpreter isexiting (because we reached the "bottom" of
a thread stack) or wants toswitch to the other implementation.
See the entry.S file in x86 or armv5te for examples.
Testing
A number of VM tests can be found in dalvik/tests. The mostuseful during interpreter development is
003-omnibus-opcodes,which tests many different instructions.
The basic invocation is:

$cd dalvik/tests$ ./run-test 003

This will run test 003 on an attached device or emulator. You can runthe test against your desktop VM by specifying
--reference if you suspect the test may be faulty. You can also use--portable and
--fast to explictly specifyone Dalvik interpreter or the other.
Some instructions are replaced by dexopt, notably when"quickening" field accesses and method invocations. To ensurethat you are testing the basic form of the instruction, add the--no-optimize option.
There is no in-built instruction tracing mechanism. If you wantto know for sure that your implementation of an opcode handleris being used, the easiest approach is to insert a "printf"call. For an example, look at
common_squeak indalvik/vm/mterp/armv5te/footer.S.
At some point you need to ensure that debuggers and profiling work withyour interpreter. The easiest way to do this is to simply connect adebugger or toggle profiling. (A future test suite may include sometests for this.)

展开全文
• ## dalvik

2014-08-29 09:20:00
dalvik Google公司自己设计用于Android平台的Java虚拟机 posted on 2014-08-29 09:20 jiahuafu 阅读(...) 评论(...) 编辑 收藏


dalvik

posted on 2014-08-29 09:20 jiahuafu 阅读(...) 评论(...)  编辑 收藏


展开全文
• ## Dalvik虚拟机 PPT版

千次下载 热门讨论 2013-10-23 01:26:13
Android应用程序是运行在Dalvik虚拟机里面的，并且每一个应用程序对应有一个单独的Dalvik虚拟机实例。Android应用程序中的Dalvik虚拟机实例实际上是从Zygote进程的地址空间拷贝而来的，这样就可以加快Android应用...
• 《Android Dalvik虚拟机结构及机制剖析：第1卷 Dalvik虚拟机结构剖析》是一本以情景方式对Android的源代码进行深入分析的书，内容广泛，主要从Dalvik虚拟机整体结构、获取和编译Dalvik虚拟机的源码、源码分析辅助...
• Android虚拟机Dalvik完整源码，宝贵资源，欢迎下载！ This directory contains the Dalvik virtual machine and core class library, as well as related tools, libraries, and tests. A note about the licenses...


java虚拟机和Dalvik虚拟机的区别：

java虚拟机
Dalvik虚拟机

java虚拟机基于栈。 基于栈的机器必须使用指令来载入和操作栈上数据，所需指令更多更多
dalvik虚拟机是基于寄存器的

java虚拟机运行的是java字节码。（java类会被编译成一个或多个字节码.class文件，打包到.jar文件中，java虚拟机从相应的.class文件和.jar文件中获取相应的字节码）
Dalvik运行的是自定义的.dex字节码格式。（java类被编译成.class文件后，会通过一个dx工具将所有的.class文件转换成一个.dex文件，然后dalvik虚拟机会从其中读取指令和数据）

常量池已被修改为只使用32位的索引，以 简化解释器。dalvik的堆和栈的参数可以通过-Xms和-Xmx更改

一个应用，一个虚拟机实例，一个进程（所有android应用的线程都是对应一个linux线程，都运行在自己的沙盒中，不同的应用在不同的进程中运行。每个android dalvik应用程序都被赋予了一个独立的linux PID(app_*)）

Dalvik虚拟机架构：

在android源码中,Dalvik虚拟机的实现位于“dalvik/”目录下，其中“dalvik/vm”是虚拟机的实现部分，将会编译成libdvm.so;而"dalvik/libdex"将会编译成libdex.a静态库作为dex工具；“dalvik/dexdump”是.dex文件的反编译工具；虚拟机的可执行程序位于“dalvik/dalvikvm”中，将会编译成dalvikvm可执行文件。

dalvik虚拟机架构：

Android应用编译及运行流程：

Dalvik进程管理：

dalvik进程管理是依赖于linux的进程体系结构的，如要为应用程序创建一个进程，它会使用linux的fork机制来复制一个进程（复制进程往往比创建进程效率更高）。

Zygote是一个虚拟机进程，同时也是一个虚拟机实例的孵化器，它通过init进程启动。首先会孵化出System_Server（android绝大多系统服务的守护进程，它会监听socket等待请求命令，当有一个应用程序启动时，就会向它发出请求，zygote就会FORK出一个新的应用程序进程）.每当系统要求执行一个android应用程序时，Zygote就会运用linux的FORK进制产生一个子进程来执行该应用程序。

JVM和Dalvik进程管理的区别：

........

linux中进程间通信的方式有很多，但是dalvik使用的是信号方式来完成进程间通信。

最后，介绍下android的初始化流程图

Android的初始化流程：


展开全文
• 进入 Android Dalvik 虚拟机，android dalvik介绍 Dalvik 虚拟机的特点——掌握 Android 程序的运行原理 Android 系统的架构采用分层思想，这样的好处是拥有减少各层之间的依赖性、便于独 立分发、容易收敛问题和...
• Dalvik VM unable to locate class 'org/jruby/Main' java.lang.NoClassDefFoundError: org.jruby.Main at dalvik.system.NativeStart.main(Native Method) Caused by: java.lang.ClassNotFoundException: ...
• Android 平台虽然是使用java语言来开发应用程序，但Android程序却不是运行在标准java虚拟机上的。谷歌专门为Android平台设计了一套虚拟机来运行Android程序。它就是Dalvik虚拟机。
• ## Dalvik VM介绍

万次阅读 2009-05-12 15:05:00
Dalvik VM介绍

Dalvik虚拟机是Google的用于移动设备的Android平台的一个主要部分。虚拟机可运行Java平台应用程序，这些应用程序被转换成紧凑的Dalvik可执行格式（.dex），该格式适合内存和处理器速度受限的系统。Dalvik虚拟机的作者是丹伯恩斯坦（Dan Bornstein）。与大多数虚拟机和真正的Java虚拟机不同，前者是栈机（stack machine），而Dalvik VM是基于寄存器的架构。就像CISC与RISC的争论，这两种方式的相对优点是一个不断争论的话题，且有时技术界限会变得模糊不清。此外，两种方法的相对优势取决于所选择的解释/编译策略。但是，总的来说，基于stack的机器必须使用指令来载入stack上的数据，或使用指令来操纵数据，因此与基于寄存器的机器相比，需要的指令更多。然而，在寄存器的指令必须编码源和目的地寄存器，因此往往指令更大。一个名为dx的工具，它用于转换Java的.class文件到.dex格式。多个类文件可包含到单个的.dex文件中。重复的、可用于多个类的字符串和其它常量在转换到.dex格式时输出到保留空间。Java字节码还可转换成可选择的、Delvik VM使用的指令集。一个未压缩的.dex文件在文件大小方面往往比从同样的.class文件压缩成的.jar文件更小。当Dalvik可执行文件安装到移动设备时，它们是可以被修改的。为了进一步的优化，在某些数据、简单数据结构和内联的函数库中的字节顺序可以互换，例如空类对象被短路。为满足低内存要求而不断优化， Dalvik虚拟机有一些独特的、有别于其它标准虚拟机的特征：（1）虚拟机很小，使用的空间也小；（2）Dalvik没有JIT编译器；（3）常量池已被修改为只使用32位的索引，以简化解释器；（4）它使用自己的字节码，而非Java字节码。

此外， Dalvik被设计来满足可高效运行多种虚拟机实例。

Dalvik虚拟机在Android架构中的位置

展开全文
• ## Dalvik虚拟机总结

千次阅读 2015-08-10 16:59:26
一、Dalvik虚拟机启动 在启动Zygote进程时，会启动Dalvik虚拟机，完成下面几件事： 1. 创建了一个Dalvik虚拟机实例； 2. 加载了Java核心类及注册其JNI方法； 3. 为主线程的设置了一个JNI环境； 4. 注册了...
• Dalvik虚拟机运行时，同样为每个线层维护一个PC计数器和调用栈，与Java虚拟机不同的是，这个调用栈维护一份寄存器列表，寄存器的数量在方法结构体的register字段中给出，Dalvik虚拟机会根据这个值来创建一份虚拟的...
• 学习了解dalvik的好东西，分享。内容描述了dalvik的结构，android框架中虚拟机的特征及机理，值得一读。
• <div><p>I was working on upgrading Dexmaker and discovered that this project used an out-of-date version of the Dalvik dx project. This PR updates the dalvik-dx to the latest version and fixes the ...
• dalvik_patch Under the Hood: Dalvik patch for Facebook for Android Implemention By David Reiss on Monday, March 4, 2013 at 1:59pm Facebook is one of the most feature-rich apps available for Android. ...
• ## Dalvik虚拟机简要介绍和学习计划

万次阅读 多人点赞 2013-05-06 00:57:08
我们知道，Android应用程序是运行在Dalvik虚拟机里面的，并且每一个应用程序对应有一个单独的Dalvik虚拟机实例。除了指令集和类文件格式不同，Dalvik虚拟机与Java虚拟机共享有差不多的特性，例如，它们都是解释执行...
• ## Dalvik虚拟机的启动过程分析

万次阅读 多人点赞 2013-05-13 00:57:04
Zygote进程在启动时会创建一个Dalvik虚拟机实例，每当它孵化一个新的应用程序进程时，都会将这个Dalvik虚拟机实例复制到新的应用程序进程里面去，从而使得每一个应用程序进程都有一个独立的Dalvik虚拟机实例。...
• ## Dalvik虚拟机的运行过程分析

万次阅读 多人点赞 2013-05-20 00:57:26
在前面一篇文章中，我们分析了Dalvik虚拟机在Zygote进程中的启动过程。Dalvik虚拟机启动完成之后，也就是在各个子模块初始化完成以及加载了相应的Java核心类库之后，就是可以执行Java代码了。当然，Dalvik虚拟机除了...
• Android 4.4发布了一个ART运行时，准备用来替换掉之前一直使用的Dalvik虚拟机，希望籍此解决饱受诟病的性能问题。老罗不打算分析ART的实现原理，只是很有兴趣知道ART是如何无缝替换掉原来的Dalvik虚拟机的。毕竟在...

...