xref: /aosp_15_r20/dalvik/docs/porting-guide.html (revision 055d459012065f78d96b68be8421640240ddf631)
1*055d4590SKeyi Gui<html>
2*055d4590SKeyi Gui<head>
3*055d4590SKeyi Gui    <title>Dalvik Porting Guide</title>
4*055d4590SKeyi Gui</head>
5*055d4590SKeyi Gui
6*055d4590SKeyi Gui<body>
7*055d4590SKeyi Gui<h1>Dalvik Porting Guide</h1>
8*055d4590SKeyi Gui
9*055d4590SKeyi Gui<p>
10*055d4590SKeyi GuiThe Dalvik virtual machine is intended to run on a variety of platforms.
11*055d4590SKeyi GuiThe baseline system is expected to be a variant of UNIX (Linux, BSD, Mac
12*055d4590SKeyi GuiOS X) running the GNU C compiler.  Little-endian CPUs have been exercised
13*055d4590SKeyi Guithe most heavily, but big-endian systems are explicitly supported.
14*055d4590SKeyi Gui</p><p>
15*055d4590SKeyi GuiThere are two general categories of work: porting to a Linux system
16*055d4590SKeyi Guiwith a previously unseen CPU architecture, and porting to a different
17*055d4590SKeyi Guioperating system.  This document covers the former.
18*055d4590SKeyi Gui</p><p>
19*055d4590SKeyi GuiBasic familiarity with the Android platform, source code structure, and
20*055d4590SKeyi Guibuild system is assumed.
21*055d4590SKeyi Gui</p>
22*055d4590SKeyi Gui
23*055d4590SKeyi Gui
24*055d4590SKeyi Gui<h2>Core Libraries</h2>
25*055d4590SKeyi Gui
26*055d4590SKeyi Gui<p>
27*055d4590SKeyi GuiThe native code in the core libraries (chiefly <code>libcore</code>,
28*055d4590SKeyi Guibut also <code>dalvik/vm/native</code>) is written in C/C++ and is expected
29*055d4590SKeyi Guito work without modification in a Linux environment.
30*055d4590SKeyi Gui</p><p>
31*055d4590SKeyi GuiThe core libraries pull in code from many other projects, including
32*055d4590SKeyi GuiOpenSSL, zlib, and ICU.  These will also need to be ported before the VM
33*055d4590SKeyi Guican be used.
34*055d4590SKeyi Gui</p>
35*055d4590SKeyi Gui
36*055d4590SKeyi Gui
37*055d4590SKeyi Gui<h2>JNI Call Bridge</h2>
38*055d4590SKeyi Gui
39*055d4590SKeyi Gui<p>
40*055d4590SKeyi GuiMost of the Dalvik VM runtime is written in portable C.  The one
41*055d4590SKeyi Guinon-portable component of the runtime is the JNI call bridge.  Simply put,
42*055d4590SKeyi Guithis converts an array of integers into function arguments of various
43*055d4590SKeyi Guitypes, and calls a function.  This must be done according to the C calling
44*055d4590SKeyi Guiconventions for the platform.  The task could be as simple as pushing all
45*055d4590SKeyi Guiof the arguments onto the stack, or involve complex rules for register
46*055d4590SKeyi Guiassignment and stack alignment.
47*055d4590SKeyi Gui</p><p>
48*055d4590SKeyi GuiTo ease porting to new platforms, the <a href="http://sourceware.org/libffi/">
49*055d4590SKeyi Guiopen-source FFI library</a> (Foreign Function Interface) is used when a
50*055d4590SKeyi Guicustom bridge is unavailable.  FFI is not as fast as a native implementation,
51*055d4590SKeyi Guiand the optional performance improvements it does offer are not used, so
52*055d4590SKeyi Guiwriting a replacement is a good first step.
53*055d4590SKeyi Gui</p><p>
54*055d4590SKeyi GuiThe code lives in <code>dalvik/vm/arch/*</code>, with the FFI-based version
55*055d4590SKeyi Guiin the "generic" directory.  There are two source files for each architecture.
56*055d4590SKeyi GuiOne defines the call bridge itself:
57*055d4590SKeyi Gui</p><p><blockquote>
58*055d4590SKeyi Gui<code>void dvmPlatformInvoke(void* pEnv, ClassObject* clazz, int argInfo,
59*055d4590SKeyi Guiint argc, const u4* argv, const char* signature, void* func,
60*055d4590SKeyi GuiJValue* pReturn)</code>
61*055d4590SKeyi Gui</blockquote></p><p>
62*055d4590SKeyi GuiThis will invoke a C/C++ function declared:
63*055d4590SKeyi Gui</p><p><blockquote>
64*055d4590SKeyi Gui    <code>return_type func(JNIEnv* pEnv, Object* this [, <i>args</i>])<br></code>
65*055d4590SKeyi Gui</blockquote>or (for a "static" method):<blockquote>
66*055d4590SKeyi Gui    <code>return_type func(JNIEnv* pEnv, ClassObject* clazz [, <i>args</i>])</code>
67*055d4590SKeyi Gui</blockquote></p><p>
68*055d4590SKeyi GuiThe role of <code>dvmPlatformInvoke</code> is to convert the values in
69*055d4590SKeyi Gui<code>argv</code> into C-style calling conventions, call the method, and
70*055d4590SKeyi Guithen place the return type into <code>pReturn</code> (a union that holds
71*055d4590SKeyi Guiall of the basic JNI types).  The code may use the method signature
72*055d4590SKeyi Gui(a DEX "shorty" signature, with one character for the return type and one
73*055d4590SKeyi Guiper argument) to determine how to handle the values.
74*055d4590SKeyi Gui</p><p>
75*055d4590SKeyi GuiThe other source file involved here defines a 32-bit "hint".  The hint
76*055d4590SKeyi Guiis computed when the method's class is loaded, and passed in as the
77*055d4590SKeyi Gui"argInfo" argument.  The hint can be used to avoid scanning the ASCII
78*055d4590SKeyi Guimethod signature for things like the return value, total argument size,
79*055d4590SKeyi Guior inter-argument 64-bit alignment restrictions.
80*055d4590SKeyi Gui
81*055d4590SKeyi Gui
82*055d4590SKeyi Gui<h2>Interpreter</h2>
83*055d4590SKeyi Gui
84*055d4590SKeyi Gui<p>
85*055d4590SKeyi GuiThe Dalvik runtime includes two interpreters, labeled "portable" and "fast".
86*055d4590SKeyi GuiThe portable interpreter is largely contained within a single C function,
87*055d4590SKeyi Guiand should compile on any system that supports gcc.  (If you don't have gcc,
88*055d4590SKeyi Guiyou may need to disable the "threaded" execution model, which relies on
89*055d4590SKeyi Guigcc's "goto table" implementation; look for the THREADED_INTERP define.)
90*055d4590SKeyi Gui</p><p>
91*055d4590SKeyi GuiThe fast interpreter uses hand-coded assembly fragments.  If none are
92*055d4590SKeyi Guiavailable for the current architecture, the build system will create an
93*055d4590SKeyi Guiinterpreter out of C "stubs".  The resulting "all stubs" interpreter is
94*055d4590SKeyi Guiquite a bit slower than the portable interpreter, making "fast" something
95*055d4590SKeyi Guiof a misnomer.
96*055d4590SKeyi Gui</p><p>
97*055d4590SKeyi GuiThe fast interpreter is enabled by default.  On platforms without native
98*055d4590SKeyi Guisupport, you may want to switch to the portable interpreter.  This can
99*055d4590SKeyi Guibe controlled with the <code>dalvik.vm.execution-mode</code> system
100*055d4590SKeyi Guiproperty.  For example, if you:
101*055d4590SKeyi Gui</p><p><blockquote>
102*055d4590SKeyi Gui<code>adb shell "echo dalvik.vm.execution-mode = int:portable >> /data/local.prop"</code>
103*055d4590SKeyi Gui</blockquote></p><p>
104*055d4590SKeyi Guiand reboot, the Android app framework will start the VM with the portable
105*055d4590SKeyi Guiinterpreter enabled.
106*055d4590SKeyi Gui</p>
107*055d4590SKeyi Gui
108*055d4590SKeyi Gui
109*055d4590SKeyi Gui<h3>Mterp Interpreter Structure</h3>
110*055d4590SKeyi Gui
111*055d4590SKeyi Gui<p>
112*055d4590SKeyi GuiThere may be significant performance advantages to rewriting the
113*055d4590SKeyi Guiinterpreter core in assembly language, using architecture-specific
114*055d4590SKeyi Guioptimizations.  In Dalvik this can be done one instruction at a time.
115*055d4590SKeyi Gui</p><p>
116*055d4590SKeyi GuiThe simplest way to implement an interpreter is to have a large "switch"
117*055d4590SKeyi Guistatement.  After each instruction is handled, the interpreter returns to
118*055d4590SKeyi Guithe top of the loop, fetches the next instruction, and jumps to the
119*055d4590SKeyi Guiappropriate label.
120*055d4590SKeyi Gui</p><p>
121*055d4590SKeyi GuiAn improvement on this is called "threaded" execution.  The instruction
122*055d4590SKeyi Guifetch and dispatch are included at the end of every instruction handler.
123*055d4590SKeyi GuiThis makes the interpreter a little larger overall, but you get to avoid
124*055d4590SKeyi Guithe (potentially expensive) branch back to the top of the switch statement.
125*055d4590SKeyi Gui</p><p>
126*055d4590SKeyi GuiDalvik mterp goes one step further, using a computed goto instead of a goto
127*055d4590SKeyi Guitable.  Instead of looking up the address in a table, which requires an
128*055d4590SKeyi Guiextra memory fetch on every instruction, mterp multiplies the opcode number
129*055d4590SKeyi Guiby a fixed value.  By default, each handler is allowed 64 bytes of space.
130*055d4590SKeyi Gui</p><p>
131*055d4590SKeyi GuiNot all handlers fit in 64 bytes.  Those that don't can have subroutines
132*055d4590SKeyi Guior simply continue on to additional code outside the basic space.  Some of
133*055d4590SKeyi Guithis is handled automatically by Dalvik, but there's no portable way to detect
134*055d4590SKeyi Guioverflow of a 64-byte handler until the VM starts executing.
135*055d4590SKeyi Gui</p><p>
136*055d4590SKeyi GuiThe choice of 64 bytes is somewhat arbitrary, but has worked out well for
137*055d4590SKeyi GuiARM and x86.
138*055d4590SKeyi Gui</p><p>
139*055d4590SKeyi GuiIn the course of development it's useful to have C and assembly
140*055d4590SKeyi Guiimplementations of each handler, and be able to flip back and forth
141*055d4590SKeyi Guibetween them when hunting problems down.  In mterp this is relatively
142*055d4590SKeyi Guistraightforward.  You can always see the files being fed to the compiler
143*055d4590SKeyi Guiand assembler for your platform by looking in the
144*055d4590SKeyi Gui<code>dalvik/vm/mterp/out</code> directory.
145*055d4590SKeyi Gui</p><p>
146*055d4590SKeyi GuiThe interpreter sources live in <code>dalvik/vm/mterp</code>.  If you
147*055d4590SKeyi Guihaven't yet, you should read <code>dalvik/vm/mterp/README.txt</code> now.
148*055d4590SKeyi Gui</p>
149*055d4590SKeyi Gui
150*055d4590SKeyi Gui
151*055d4590SKeyi Gui<h3>Getting Started With Mterp</h3>
152*055d4590SKeyi Gui
153*055d4590SKeyi Gui</p><p>
154*055d4590SKeyi GuiGetting started:
155*055d4590SKeyi Gui<ol>
156*055d4590SKeyi Gui<li>Decide on the name of your architecture.  For the sake of discussion,
157*055d4590SKeyi Guilet's call it <code>myarch</code>.
158*055d4590SKeyi Gui<li>Make a copy of <code>dalvik/vm/mterp/config-allstubs</code> to
159*055d4590SKeyi Gui<code>dalvik/vm/mterp/config-myarch</code>.
160*055d4590SKeyi Gui<li>Create a <code>dalvik/vm/mterp/myarch</code> directory to hold your
161*055d4590SKeyi Guisource files.
162*055d4590SKeyi Gui<li>Add <code>myarch</code> to the list in
163*055d4590SKeyi Gui<code>dalvik/vm/mterp/rebuild.sh</code>.
164*055d4590SKeyi Gui<li>Make sure <code>dalvik/vm/Android.mk</code> will find the files for
165*055d4590SKeyi Guiyour architecture.  If <code>$(TARGET_ARCH)</code> is configured this
166*055d4590SKeyi Guiwill happen automatically.
167*055d4590SKeyi Gui<li>Disable the Dalvik JIT.  You can do this in the general device
168*055d4590SKeyi Guiconfiguration, or by editing the initialization of WITH_JIT in
169*055d4590SKeyi Gui<code>dalvik/vm/Dvm.mk</code> to always be <code>false</code>.
170*055d4590SKeyi Gui</ol>
171*055d4590SKeyi Gui</p><p>
172*055d4590SKeyi GuiYou now have the basic framework in place.  Whenever you make a change, you
173*055d4590SKeyi Guineed to perform two steps: regenerate the mterp output, and build the
174*055d4590SKeyi Guicore VM library.  (It's two steps because we didn't want the build system
175*055d4590SKeyi Guito require Python 2.5.  Which, incidentally, you need to have.)
176*055d4590SKeyi Gui<ol>
177*055d4590SKeyi Gui<li>In the <code>dalvik/vm/mterp</code> directory, regenerate the contents
178*055d4590SKeyi Guiof the files in <code>dalvik/vm/mterp/out</code> by executing
179*055d4590SKeyi Gui<code>./rebuild.sh</code>.  Note there are two files, one in C and one
180*055d4590SKeyi Guiin assembly.
181*055d4590SKeyi Gui<li>In the <code>dalvik</code> directory, regenerate the
182*055d4590SKeyi Gui<code>libdvm.so</code> library with <code>mm</code>.  You can also use
183*055d4590SKeyi Gui<code>mmm dalvik/vm</code> from the top of the tree.
184*055d4590SKeyi Gui</ol>
185*055d4590SKeyi Gui</p><p>
186*055d4590SKeyi GuiThis will leave you with an updated libdvm.so, which can be pushed out to
187*055d4590SKeyi Guia device with <code>adb sync</code> or <code>adb push</code>.  If you're
188*055d4590SKeyi Guiusing the emulator, you need to add <code>make snod</code> (System image,
189*055d4590SKeyi GuiNO Dependency check) to rebuild the system image file.  You should not
190*055d4590SKeyi Guineed to do a top-level "make" and rebuild the dependent binaries.
191*055d4590SKeyi Gui</p><p>
192*055d4590SKeyi GuiAt this point you have an "all stubs" interpreter.  You can see how it
193*055d4590SKeyi Guiworks by examining <code>dalvik/vm/mterp/cstubs/entry.c</code>.  The
194*055d4590SKeyi Guicode runs in a loop, pulling out the next opcode, and invoking the
195*055d4590SKeyi Guihandler through a function pointer.  Each handler takes a "glue" argument
196*055d4590SKeyi Guithat contains all of the useful state.
197*055d4590SKeyi Gui</p><p>
198*055d4590SKeyi GuiYour goal is to replace the entry method, exit method, and each individual
199*055d4590SKeyi Guiinstruction with custom implementations.  The first thing you need to do
200*055d4590SKeyi Guiis create an entry function that calls the handler for the first instruction.
201*055d4590SKeyi GuiAfter that, the instructions chain together, so you don't need a loop.
202*055d4590SKeyi Gui(Look at the ARM or x86 implementation to see how they work.)
203*055d4590SKeyi Gui</p><p>
204*055d4590SKeyi GuiOnce you have that, you need something to jump to.  You can't branch
205*055d4590SKeyi Guidirectly to the C stub because it's expecting to be called with a "glue"
206*055d4590SKeyi Guiargument and then return.  We need a C stub "wrapper" that does the
207*055d4590SKeyi Guisetup and jumps directly to the next handler.  We write this in assembly
208*055d4590SKeyi Guiand then add it to the config file definition.
209*055d4590SKeyi Gui</p><p>
210*055d4590SKeyi GuiTo see how this works, create a file called
211*055d4590SKeyi Gui<code>dalvik/vm/mterp/myarch/stub.S</code> that contains one line:
212*055d4590SKeyi Gui<pre>
213*055d4590SKeyi Gui/* stub for ${opcode} */
214*055d4590SKeyi Gui</pre>
215*055d4590SKeyi GuiThen, in <code>dalvik/vm/mterp/config-myarch</code>, add this below the
216*055d4590SKeyi Gui<code>handler-size</code> directive:
217*055d4590SKeyi Gui<pre>
218*055d4590SKeyi Gui# source for the instruction table stub
219*055d4590SKeyi Guiasm-stub myarch/stub.S
220*055d4590SKeyi Gui</pre>
221*055d4590SKeyi Gui</p><p>
222*055d4590SKeyi GuiRegenerate the sources with <code>./rebuild.sh</code>, and take a look
223*055d4590SKeyi Guiinside <code>dalvik/vm/mterp/out/InterpAsm-myarch.S</code>.  You should
224*055d4590SKeyi Guisee 256 copies of the stub function in a single large block after the
225*055d4590SKeyi Gui<code>dvmAsmInstructionStart</code> label.  The <code>stub.S</code>
226*055d4590SKeyi Guicode will be used anywhere you don't provide an assembly implementation.
227*055d4590SKeyi Gui</p><p>
228*055d4590SKeyi GuiNote that each block begins with a <code>.balign 64</code> directive.
229*055d4590SKeyi GuiThis is what pads each handler out to 64 bytes.  Note also that the
230*055d4590SKeyi Gui<code>${opcode}</code> text changed into an opcode name, which should
231*055d4590SKeyi Guibe used to call the C implementation (<code>dvmMterp_${opcode}</code>).
232*055d4590SKeyi Gui</p><p>
233*055d4590SKeyi GuiThe actual contents of <code>stub.S</code> are up to you to define.
234*055d4590SKeyi GuiSee <code>entry.S</code> and <code>stub.S</code> in the <code>armv5te</code>
235*055d4590SKeyi Guior <code>x86</code> directories for working examples.
236*055d4590SKeyi Gui</p><p>
237*055d4590SKeyi GuiIf you're working on a variation of an existing architecture, you may be
238*055d4590SKeyi Guiable to use most of the existing code and just provide replacements for
239*055d4590SKeyi Guia few instructions.  Look at the <code>vm/mterp/config-*</code> files
240*055d4590SKeyi Guifor examples.
241*055d4590SKeyi Gui</p>
242*055d4590SKeyi Gui
243*055d4590SKeyi Gui
244*055d4590SKeyi Gui<h3>Replacing Stubs</h3>
245*055d4590SKeyi Gui
246*055d4590SKeyi Gui<p>
247*055d4590SKeyi GuiThere are roughly 250 Dalvik opcodes, including some that are inserted by
248*055d4590SKeyi Gui<a href="dexopt.html">dexopt</a> and aren't described in the
249*055d4590SKeyi Gui<a href="dalvik-bytecode.html">Dalvik bytecode</a> documentation.  Each
250*055d4590SKeyi Guione must perform the appropriate actions, fetch the next opcode, and
251*055d4590SKeyi Guibranch to the next handler.  The actions performed by the assembly version
252*055d4590SKeyi Guimust exactly match those performed by the C version (in
253*055d4590SKeyi Gui<code>dalvik/vm/mterp/c/OP_*</code>).
254*055d4590SKeyi Gui</p><p>
255*055d4590SKeyi GuiIt is possible to customize the set of "optimized" instructions for your
256*055d4590SKeyi Guiplatform.  This is possible because optimized DEX files are not expected
257*055d4590SKeyi Guito work on multiple devices.  Adding, removing, or redefining instructions
258*055d4590SKeyi Guiis beyond the scope of this document, and for simplicity it's best to stick
259*055d4590SKeyi Guiwith the basic set defined by the portable interpreter.
260*055d4590SKeyi Gui</p><p>
261*055d4590SKeyi GuiOnce you have written a handler that looks like it should work, add
262*055d4590SKeyi Guiit to the config file.  For example, suppose we have a working version
263*055d4590SKeyi Guiof <code>OP_NOP</code>.  For demonstration purposes, fake it for now by
264*055d4590SKeyi Guiputting this into <code>dalvik/vm/mterp/myarch/OP_NOP.S</code>:
265*055d4590SKeyi Gui<pre>
266*055d4590SKeyi Gui/* This is my NOP handler */
267*055d4590SKeyi Gui</pre>
268*055d4590SKeyi Gui</p><p>
269*055d4590SKeyi GuiThen, in the <code>op-start</code> section of <code>config-myarch</code>, add:
270*055d4590SKeyi Gui<pre>
271*055d4590SKeyi Gui    op OP_NOP myarch
272*055d4590SKeyi Gui</pre>
273*055d4590SKeyi Gui</p><p>
274*055d4590SKeyi GuiThis tells the generation script to use the assembly version from the
275*055d4590SKeyi Gui<code>myarch</code> directory instead of the C version from the <code>c</code>
276*055d4590SKeyi Guidirectory.
277*055d4590SKeyi Gui</p><p>
278*055d4590SKeyi GuiExecute <code>./rebuild.sh</code>.  Look at <code>InterpAsm-myarch.S</code>
279*055d4590SKeyi Guiand <code>InterpC-myarch.c</code> in the <code>out</code> directory.  You
280*055d4590SKeyi Guiwill see that the <code>OP_NOP</code> stub wrapper has been replaced with our
281*055d4590SKeyi Guinew code in the assembly file, and the C stub implementation is no longer
282*055d4590SKeyi Guiincluded.
283*055d4590SKeyi Gui</p><p>
284*055d4590SKeyi GuiAs you implement instructions, the C version and corresponding stub wrapper
285*055d4590SKeyi Guiwill disappear from the output files.  Eventually you will have a 100%
286*055d4590SKeyi Guiassembly interpreter.  You may find it saves a little time to examine
287*055d4590SKeyi Guithe output of your compiler for some of the operations.  The
288*055d4590SKeyi Gui<a href="porting-proto.c.txt">porting-proto.c</a> sample code can be
289*055d4590SKeyi Guihelpful here.
290*055d4590SKeyi Gui</p>
291*055d4590SKeyi Gui
292*055d4590SKeyi Gui
293*055d4590SKeyi Gui<h3>Interpreter Switching</h3>
294*055d4590SKeyi Gui
295*055d4590SKeyi Gui<p>
296*055d4590SKeyi GuiThe Dalvik VM actually includes a third interpreter implementation: the debug
297*055d4590SKeyi Guiinterpreter.  This is a variation of the portable interpreter that includes
298*055d4590SKeyi Guisupport for debugging and profiling.
299*055d4590SKeyi Gui</p><p>
300*055d4590SKeyi GuiWhen a debugger attaches, or a profiling feature is enabled, the VM
301*055d4590SKeyi Guiwill switch interpreters at a convenient point.  This is done at the
302*055d4590SKeyi Guisame time as the GC safe point check: on a backward branch, a method
303*055d4590SKeyi Guireturn, or an exception throw.  Similarly, when the debugger detaches
304*055d4590SKeyi Guior profiling is discontinued, execution transfers back to the "fast" or
305*055d4590SKeyi Gui"portable" interpreter.
306*055d4590SKeyi Gui</p><p>
307*055d4590SKeyi GuiYour entry function needs to test the "entryPoint" value in the "glue"
308*055d4590SKeyi Guipointer to determine where execution should begin.  Your exit function
309*055d4590SKeyi Guiwill need to return a boolean that indicates whether the interpreter is
310*055d4590SKeyi Guiexiting (because we reached the "bottom" of a thread stack) or wants to
311*055d4590SKeyi Guiswitch to the other implementation.
312*055d4590SKeyi Gui</p><p>
313*055d4590SKeyi GuiSee the <code>entry.S</code> file in <code>x86</code> or <code>armv5te</code>
314*055d4590SKeyi Guifor examples.
315*055d4590SKeyi Gui</p>
316*055d4590SKeyi Gui
317*055d4590SKeyi Gui
318*055d4590SKeyi Gui<h3>Testing</h3>
319*055d4590SKeyi Gui
320*055d4590SKeyi Gui<p>
321*055d4590SKeyi GuiA number of VM tests can be found in <code>dalvik/tests</code>.  The most
322*055d4590SKeyi Guiuseful during interpreter development is <code>003-omnibus-opcodes</code>,
323*055d4590SKeyi Guiwhich tests many different instructions.
324*055d4590SKeyi Gui</p><p>
325*055d4590SKeyi GuiThe basic invocation is:
326*055d4590SKeyi Gui<pre>
327*055d4590SKeyi Gui$ cd dalvik/tests
328*055d4590SKeyi Gui$ ./run-test 003
329*055d4590SKeyi Gui</pre>
330*055d4590SKeyi Gui</p><p>
331*055d4590SKeyi GuiThis will run test 003 on an attached device or emulator.  You can run
332*055d4590SKeyi Guithe test against your desktop VM by specifying <code>--reference</code>
333*055d4590SKeyi Guiif you suspect the test may be faulty.  You can also use
334*055d4590SKeyi Gui<code>--portable</code> and <code>--fast</code> to explictly specify
335*055d4590SKeyi Guione Dalvik interpreter or the other.
336*055d4590SKeyi Gui</p><p>
337*055d4590SKeyi GuiSome instructions are replaced by <code>dexopt</code>, notably when
338*055d4590SKeyi Gui"quickening" field accesses and method invocations.  To ensure
339*055d4590SKeyi Guithat you are testing the basic form of the instruction, add the
340*055d4590SKeyi Gui<code>--no-optimize</code> option.
341*055d4590SKeyi Gui</p><p>
342*055d4590SKeyi GuiThere is no in-built instruction tracing mechanism.  If you want
343*055d4590SKeyi Guito know for sure that your implementation of an opcode handler
344*055d4590SKeyi Guiis being used, the easiest approach is to insert a "printf"
345*055d4590SKeyi Guicall.  For an example, look at <code>common_squeak</code> in
346*055d4590SKeyi Gui<code>dalvik/vm/mterp/armv5te/footer.S</code>.
347*055d4590SKeyi Gui</p><p>
348*055d4590SKeyi GuiAt some point you need to ensure that debuggers and profiling work with
349*055d4590SKeyi Guiyour interpreter.  The easiest way to do this is to simply connect a
350*055d4590SKeyi Guidebugger or toggle profiling.  (A future test suite may include some
351*055d4590SKeyi Guitests for this.)
352*055d4590SKeyi Gui</p>
353*055d4590SKeyi Gui
354*055d4590SKeyi Gui
355*055d4590SKeyi Gui<h2>Other Performance Issues</h2>
356*055d4590SKeyi Gui
357*055d4590SKeyi Gui<p>
358*055d4590SKeyi GuiThe <code>System.arraycopy()</code> function is heavily used.  The
359*055d4590SKeyi Guiimplementation relies on the bionic C library to provide a fast,
360*055d4590SKeyi Guiplatform-optimized data copy function for arrays with elements wider
361*055d4590SKeyi Guithan one byte.  If you're not using bionic, or your platform does not
362*055d4590SKeyi Guihave an implementation of this method, Dalvik will use correct but
363*055d4590SKeyi Guisub-optimal algorithms instead.  For best performance you will want
364*055d4590SKeyi Guito provide your own version.
365*055d4590SKeyi Gui</p><p>
366*055d4590SKeyi GuiSee the comments in <code>dalvik/vm/native/java_lang_System.c</code>
367*055d4590SKeyi Guifor details.
368*055d4590SKeyi Gui</p>
369*055d4590SKeyi Gui
370*055d4590SKeyi Gui<p>
371*055d4590SKeyi Gui<address>Copyright &copy; 2009 The Android Open Source Project</address>
372*055d4590SKeyi Gui
373*055d4590SKeyi Gui</body>
374*055d4590SKeyi Gui</html>
375