summaryrefslogtreecommitdiffstats
path: root/pdk/docs/guide/dalvik.jd
diff options
context:
space:
mode:
authorJean-Baptiste Queru <jbq@google.com>2009-11-12 18:45:17 -0800
committerJean-Baptiste Queru <jbq@google.com>2009-11-13 15:09:24 -0800
commit2c8ead32c7ebf08db568e2e9d5dbb3738ac69797 (patch)
treea4b9a0b6b9a125c492e6584d48a15b3b62b327d7 /pdk/docs/guide/dalvik.jd
parent50992e805e758e2231f28ec2127b57a1a9fd0ddc (diff)
downloadandroid_development-2c8ead32c7ebf08db568e2e9d5dbb3738ac69797.tar.gz
android_development-2c8ead32c7ebf08db568e2e9d5dbb3738ac69797.tar.bz2
android_development-2c8ead32c7ebf08db568e2e9d5dbb3738ac69797.zip
eclair snapshot
Diffstat (limited to 'pdk/docs/guide/dalvik.jd')
-rwxr-xr-xpdk/docs/guide/dalvik.jd355
1 files changed, 0 insertions, 355 deletions
diff --git a/pdk/docs/guide/dalvik.jd b/pdk/docs/guide/dalvik.jd
deleted file mode 100755
index 6fa37da9b..000000000
--- a/pdk/docs/guide/dalvik.jd
+++ /dev/null
@@ -1,355 +0,0 @@
-page.title=Dalvik
-pdk.version=1.0
-doc.type=guide
-@jd:body
-
-<div id="qv-wrapper">
-<div id="qv">
-<h2>In this document</h2>
-<a name="toc"/>
-<ul>
-<li><a href="#dalvikCoreLibraries">Core Libraries</a></li>
-<li><a href="#dalvikJNICallBridge">JNI Call Bridge</a></li>
-<li><a href="#dalvikInterpreter">Interpreter</a></li>
-</ul>
-</div>
-</div>
-
-<p>
-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, Mac
-OS X) running the GNU C compiler. Little-endian CPUs have been exercised
-the most heavily, but big-endian systems are explicitly supported.
-</p><p>
-There are two general categories of work: porting to a Linux system
-with a previously unseen CPU architecture, and porting to a different
-operating system. This document covers the former.
-</p>
-
-
-<a name="dalvikCoreLibraries"></a><h3>Core Libraries</h3>
-
-<p>
-The native code in the core libraries (chiefly <code>dalvik/libcore</code>,
-but also <code>dalvik/vm/native</code>) is written in C/C++ and is expected
-to work without modification in a Linux environment. Much of the code
-comes directly from the Apache Harmony project.
-</p><p>
-The core libraries pull in code from many other projects, including
-OpenSSL, zlib, and ICU. These will also need to be ported before the VM
-can be used.
-</p>
-
-
-<a name="dalvikJNICallBridge"></a><h3>JNI Call Bridge</h3>
-
-<p>
-Most of the Dalvik VM runtime is written in portable C. The one
-non-portable component of the runtime is the JNI call bridge. Simply put,
-this converts an array of integers into function arguments of various
-types, and calls a function. This must be done according to the C calling
-conventions for the platform. The task could be as simple as pushing all
-of the arguments onto the stack, or involve complex rules for register
-assignment and stack alignment.
-</p><p>
-To ease porting to new platforms, the <a href="http://sourceware.org/libffi/">
-open-source FFI library</a> (Foreign Function Interface) is used when a
-custom bridge is unavailable. FFI is not as fast as a native implementation,
-and the optional performance improvements it does offer are not used, so
-writing a replacement is a good first step.
-</p><p>
-The code lives in <code>dalvik/vm/arch/*</code>, with the FFI-based version
-in the "generic" directory. There are two source files for each architecture.
-One defines the call bridge itself:
-</p><p><blockquote>
-<code>void dvmPlatformInvoke(void* pEnv, ClassObject* clazz, int argInfo,
-int argc, const u4* argv, const char* signature, void* func,
-JValue* pReturn)</code>
-</blockquote></p><p>
-This will invoke a C/C++ function declared:
-</p><p><blockquote>
- <code>return_type func(JNIEnv* pEnv, Object* this [, <i>args</i>])<br></code>
-</blockquote>or (for a "static" method):<blockquote>
- <code>return_type func(JNIEnv* pEnv, ClassObject* clazz [, <i>args</i>])</code>
-</blockquote></p><p>
-The role of <code>dvmPlatformInvoke</code> is to convert the values in
-<code>argv</code> into C-style calling conventions, call the method, and
-then place the return type into <code>pReturn</code> (a union that holds
-all of the basic JNI types). The code may use the method signature
-(a DEX "shorty" signature, with one character for the return type and one
-per argument) to determine how to handle the values.
-</p><p>
-The other source file involved here defines a 32-bit "hint". The hint
-is computed when the method's class is loaded, and passed in as the
-"argInfo" argument. The hint can be used to avoid scanning the ASCII
-method signature for things like the return value, total argument size,
-or inter-argument 64-bit alignment restrictions.
-</p>
-
-<a name="dalvikInterpreter"></a><h3>Interpreter</h3>
-
-<p>
-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 on
-gcc's "goto table" implementation; look for the THREADED_INTERP define.)
-</p><p>
-The fast interpreter uses hand-coded assembly fragments. If none are
-available for the current architecture, the build system will create an
-interpreter out of C "stubs". The resulting "all stubs" interpreter is
-quite a bit slower than the portable interpreter, making "fast" something
-of a misnomer.
-</p><p>
-The fast interpreter is enabled by default. On platforms without native
-support, you may want to switch to the portable interpreter. This can
-be controlled with the <code>dalvik.vm.execution-mode</code> system
-property. For example, if you:
-</p><p><blockquote>
-<code>adb shell "echo dalvik.vm.execution-mode = int:portable >> /data/local.prop"</code>
-</blockquote></p><p>
-and reboot, the Android app framework will start the VM with the portable
-interpreter enabled.
-</p>
-
-
-<h3>Mterp Interpreter Structure</h3>
-
-<p>
-There may be significant performance advantages to rewriting the
-interpreter core in assembly language, using architecture-specific
-optimizations. In Dalvik this can be done one instruction at a time.
-</p><p>
-The simplest way to implement an interpreter is to have a large "switch"
-statement. After each instruction is handled, the interpreter returns to
-the top of the loop, fetches the next instruction, and jumps to the
-appropriate label.
-</p><p>
-An improvement on this is called "threaded" execution. The instruction
-fetch and dispatch are included at the end of every instruction handler.
-This makes the interpreter a little larger overall, but you get to avoid
-the (potentially expensive) branch back to the top of the switch statement.
-</p><p>
-Dalvik mterp goes one step further, using a computed goto instead of a goto
-table. Instead of looking up the address in a table, which requires an
-extra memory fetch on every instruction, mterp multiplies the opcode number
-by a fixed value. By default, each handler is allowed 64 bytes of space.
-</p><p>
-Not all handlers fit in 64 bytes. Those that don't can have subroutines
-or simply continue on to additional code outside the basic space. Some of
-this is handled automatically by Dalvik, but there's no portable way to detect
-overflow of a 64-byte handler until the VM starts executing.
-</p><p>
-The choice of 64 bytes is somewhat arbitrary, but has worked out well for
-ARM and x86.
-</p><p>
-In the course of development it's useful to have C and assembly
-implementations of each handler, and be able to flip back and forth
-between them when hunting problems down. In mterp this is relatively
-straightforward. You can always see the files being fed to the compiler
-and assembler for your platform by looking in the
-<code>dalvik/vm/mterp/out</code> directory.
-</p><p>
-The interpreter sources live in <code>dalvik/vm/mterp</code>. If you
-haven't yet, you should read <code>dalvik/vm/mterp/README.txt</code> now.
-</p>
-
-
-<h3>Getting Started With Mterp</h3>
-
-</p><p>
-Getting started:
-<ol>
-<li>Decide on the name of your architecture. For the sake of discussion,
-let's call it <code>myarch</code>.
-<li>Make a copy of <code>dalvik/vm/mterp/config-allstubs</code> to
-<code>dalvik/vm/mterp/config-myarch</code>.
-<li>Create a <code>dalvik/vm/mterp/myarch</code> directory to hold your
-source files.
-<li>Add <code>myarch</code> to the list in
-<code>dalvik/vm/mterp/rebuild.sh</code>.
-<li>Make sure <code>dalvik/vm/Android.mk</code> will find the files for
-your architecture. If <code>$(TARGET_ARCH)</code> is configured this
-will happen automatically.
-</ol>
-</p><p>
-You now have the basic framework in place. Whenever you make a change, you
-need to perform two steps: regenerate the mterp output, and build the
-core VM library. (It's two steps because we didn't want the build system
-to require Python 2.5. Which, incidentally, you need to have.)
-<ol>
-<li>In the <code>dalvik/vm/mterp</code> directory, regenerate the contents
-of the files in <code>dalvik/vm/mterp/out</code> by executing
-<code>./rebuild.sh</code>. Note there are two files, one in C and one
-in assembly.
-<li>In the <code>dalvik</code> directory, regenerate the
-<code>libdvm.so</code> library with <code>mm</code>. You can also use
-<code>make libdvm</code> from the top of the tree.
-</ol>
-</p><p>
-This will leave you with an updated libdvm.so, which can be pushed out to
-a device with <code>adb sync</code> or <code>adb push</code>. If you're
-using the emulator, you need to add <code>make snod</code> (System image,
-NO Dependency check) to rebuild the system image file. You should not
-need to do a top-level "make" and rebuild the dependent binaries.
-</p><p>
-At this point you have an "all stubs" interpreter. You can see how it
-works by examining <code>dalvik/vm/mterp/cstubs/entry.c</code>. The
-code runs in a loop, pulling out the next opcode, and invoking the
-handler through a function pointer. Each handler takes a "glue" argument
-that contains all of the useful state.
-</p><p>
-Your goal is to replace the entry method, exit method, and each individual
-instruction with custom implementations. The first thing you need to do
-is 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.)
-</p><p>
-Once you have that, you need something to jump to. You can't branch
-directly 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 the
-setup and jumps directly to the next handler. We write this in assembly
-and then add it to the config file definition.
-</p><p>
-To see how this works, create a file called
-<code>dalvik/vm/mterp/myarch/stub.S</code> that contains one line:
-<pre>
-/* stub for ${opcode} */
-</pre>
-Then, in <code>dalvik/vm/mterp/config-myarch</code>, add this below the
-<code>handler-size</code> directive:
-<pre>
-# source for the instruction table stub
-asm-stub myarch/stub.S
-</pre>
-</p><p>
-Regenerate the sources with <code>./rebuild.sh</code>, and take a look
-inside <code>dalvik/vm/mterp/out/InterpAsm-myarch.S</code>. You should
-see 256 copies of the stub function in a single large block after the
-<code>dvmAsmInstructionStart</code> label. The <code>stub.S</code>
-code will be used anywhere you don't provide an assembly implementation.
-</p><p>
-Note that each block begins with a <code>.balign 64</code> directive.
-This is what pads each handler out to 64 bytes. Note also that the
-<code>${opcode}</code> text changed into an opcode name, which should
-be used to call the C implementation (<code>dvmMterp_${opcode}</code>).
-</p><p>
-The actual contents of <code>stub.S</code> are up to you to define.
-See <code>entry.S</code> and <code>stub.S</code> in the <code>armv5te</code>
-or <code>x86</code> directories for working examples.
-</p><p>
-If you're working on a variation of an existing architecture, you may be
-able to use most of the existing code and just provide replacements for
-a few instructions. Look at the <code>armv4t</code> implementation as
-an example.
-</p>
-
-
-<h3>Replacing Stubs</h3>
-
-<p>
-There are roughly 230 Dalvik opcodes, including some that are inserted by
-<a href="dexopt.html">dexopt</a> and aren't described in the
-<a href="dalvik-bytecode.html">Dalvik bytecode</a> documentation. Each
-one must perform the appropriate actions, fetch the next opcode, and
-branch to the next handler. The actions performed by the assembly version
-must exactly match those performed by the C version (in
-<code>dalvik/vm/mterp/c/OP_*</code>).
-</p><p>
-It is possible to customize the set of "optimized" instructions for your
-platform. This is possible because optimized DEX files are not expected
-to work on multiple devices. Adding, removing, or redefining instructions
-is beyond the scope of this document, and for simplicity it's best to stick
-with the basic set defined by the portable interpreter.
-</p><p>
-Once you have written a handler that looks like it should work, add
-it to the config file. For example, suppose we have a working version
-of <code>OP_NOP</code>. For demonstration purposes, fake it for now by
-putting this into <code>dalvik/vm/mterp/myarch/OP_NOP.S</code>:
-<pre>
-/* This is my NOP handler */
-</pre>
-</p><p>
-Then, in the <code>op-start</code> section of <code>config-myarch</code>, add:
-<pre>
- op OP_NOP myarch
-</pre>
-</p><p>
-This tells the generation script to use the assembly version from the
-<code>myarch</code> directory instead of the C version from the <code>c</code>
-directory.
-</p><p>
-Execute <code>./rebuild.sh</code>. Look at <code>InterpAsm-myarch.S</code>
-and <code>InterpC-myarch.c</code> in the <code>out</code> directory. You
-will see that the <code>OP_NOP</code> stub wrapper has been replaced with our
-new code in the assembly file, and the C stub implementation is no longer
-included.
-</p><p>
-As you implement instructions, the C version and corresponding stub wrapper
-will disappear from the output files. Eventually you will have a 100%
-assembly interpreter.
-</p>
-
-
-<h3>Interpreter Switching</h3>
-
-<p>
-The Dalvik VM actually includes a third interpreter implementation: the debug
-interpreter. This is a variation of the portable interpreter that includes
-support for debugging and profiling.
-</p><p>
-When a debugger attaches, or a profiling feature is enabled, the VM
-will switch interpreters at a convenient point. This is done at the
-same time as the GC safe point check: on a backward branch, a method
-return, or an exception throw. Similarly, when the debugger detaches
-or profiling is discontinued, execution transfers back to the "fast" or
-"portable" interpreter.
-</p><p>
-Your entry function needs to test the "entryPoint" value in the "glue"
-pointer to determine where execution should begin. Your exit function
-will need to return a boolean that indicates whether the interpreter is
-exiting (because we reached the "bottom" of a thread stack) or wants to
-switch to the other implementation.
-</p><p>
-See the <code>entry.S</code> file in <code>x86</code> or <code>armv5te</code>
-for examples.
-</p>
-
-
-<h3>Testing</h3>
-
-<p>
-A number of VM tests can be found in <code>dalvik/tests</code>. The most
-useful during interpreter development is <code>003-omnibus-opcodes</code>,
-which tests many different instructions.
-</p><p>
-The basic invocation is:
-<pre>
-$ cd dalvik/tests
-$ ./run-test 003
-</pre>
-</p><p>
-This will run test 003 on an attached device or emulator. You can run
-the test against your desktop VM by specifying <code>--reference</code>
-if you suspect the test may be faulty. You can also use
-<code>--portable</code> and <code>--fast</code> to explictly specify
-one Dalvik interpreter or the other.
-</p><p>
-Some instructions are replaced by <code>dexopt</code>, notably when
-"quickening" field accesses and method invocations. To ensure
-that you are testing the basic form of the instruction, add the
-<code>--no-optimize</code> option.
-</p><p>
-There is no in-built instruction tracing mechanism. If you want
-to know for sure that your implementation of an opcode handler
-is being used, the easiest approach is to insert a "printf"
-call. For an example, look at <code>common_squeak</code> in
-<code>dalvik/vm/mterp/armv5te/footer.S</code>.
-</p><p>
-At some point you need to ensure that debuggers and profiling work with
-your interpreter. The easiest way to do this is to simply connect a
-debugger or toggle profiling. (A future test suite may include some
-tests for this.)
-</p>
-
-