String's equals() method return wrong when using the generic C implementation of Android's Dalvik VM.

by Peter » Tue, 28 Apr 2009 14:43:25 GMT

Sponsored Links

I'm porting Android on a new architecture called XBurst, just like arm
and x86.

I did the following things:

1. Build a new toolchain for XBurst.
2. Porting the Linux 2.6.27 kernel to XBurst.
3. Porting the Android libc called bionic to XBurst (added syscalls,
linker etc.)
4. Use the generic C implementation of Dalvik VM (the quicker way for
me, next I will port it to XBurst)

Now, Android can be run successfully on XBurst and most applications
work normally.

But there is one problem with the String's equals() method. Some Java
codes using this method
get a wrong return value. For example:

String str1 = "android.intent.action.VIEW";
String str2 = "android.intent.action.PICK";
String str3 = "android.intent.action.GET_CONTENT";
Boolean res1, res2;

res1 = str1.equals(str2);
res2 = str1.equals(str3);

I ran these codes on the Android's emulator and they returned
res1=false and res2=false. (They are correct)

But when I ran them on XBurst, they returned res1=true and res2=false.
(They are wrong)

I did several tests with different strings and found that when the two
strings have different length, the method
can return a correct value. While they have the same length, the
method return a wrong value.

Then I ran above codes with dalvikvm on the command shell, and found
that they returned res1=false
and res2=false. (They are correct)

The difference is that the wrong one was got when the Android runtime
startuped and while the correct
one is just running .jar file on the command shell with dalvikvm.

So I guessed this should be the Android runtime problem when using the
generic C implementation of Dalvik VM.

Can anyone tell me the true reason? Is it a bug of the Android runtime
codes? Or is there other ways to help me to locate the issue?

Any suggestions are appreciated.




String's equals() method return wrong when using the generic C implementation of Android's Dalvik VM.

by fadden » Wed, 29 Apr 2009 02:24:17 GMT


There might be something else at work, depending on how exactly you're
going about things.

The optimizations performed by "dexopt" include a form of instruction
inlining.  For a handful of methods, listed in the gDvmInlineOpsTable
in dalvik/vm/InlineNative.c, the method call is replaced with an
instruction that performs the desired action without any of the method
overhead.  The actual implementation doesn't run any faster than a
method declared "native", but we can skip all of the stack frame prep
and other method call overhead, so it's useful for simple methods that
are called very frequently.

Typically your String.equals() call will end up in
javaLangString_equals() in InlineNative.c.  This may use an Android-
specific ARM "memcmp16" function, or do a simple iterative loop in C.
The result goes into "pResult->i", and the function returns "true" to
indicate that no exception was thrown.

If for some reason "dexopt" didn't optimize the code that calls
String.equals(), you will call the implementation in

I looked over the code and all of the implementations seem correct.
They all test the length before comparing characters, so I can see how
you could get the results you described above if one of the comparison
loops was broken.

When invoking Dalvik from the command line, you can control which
interpreter runs with "-Xint"; use "-Xint:portable" or "-Xint:fast".
You can control DEX optimizations with -Xdexopt, e.g. -Xdexopt:none to
disable it.  You can verify what it did by running "dexdump -d" on the
optimized file in /data/dalvik-cache.  Note the file doesn't get
regenerated if it doesn't need to be, so remove the /data/dalvik-cache
entry before running dalvikvm with a different "-Xdexopt" option.



Sponsored Links

String's equals() method return wrong when using the generic C implementation of Android's Dalvik VM.

by Peter » Wed, 29 Apr 2009 09:32:16 GMT

 i fadden,

Thanks for your suggestions.

Sure I traced the String.equals and found that some codes call the
implementation in, while the test code of mine didn't call
it. Then I followed your advice to trace the inline native
in dalvik/vm/InlineNative.c, luckily that it was called.

Then I checked the code in InlineNative.c carefully. They are all
And then the __memcmp16() in my implementation. And finally I found
that my __memcmp16() was wrong. In my implementation, I think that
the third parameter "size_t count" is in byte-length. While by reading
InlineNative.c I knowed that it is in short-length, but not byte-
So my __memcmp16() return a wrong value to "pResult->i" when the
two strings have the same length.

And now by fixing __memcmp16(), the test code ran well and can return
the correct result.

Thanks fadden again.

You know that my work is to porting Android to a new architecture
different from arm and x86. So almost everything needs to be added
for me, the toolchain, the kernel, the bionic C library, then the
VM. The problem of String.equals was caused by the bionic C library.
And your advice helped me to locate and fix the issue.


On 49 24 fadden <> wrote:


Other Threads

1. Drawings of View.onDraw() sometimes not shown when canvas was rotated

I have create a subclass of View and overwritten onDraw() - see some
test code below.
It draws a line consisting of some points. Before the line is drawn
the canvas is rotated and restore after the drawing.
The angle by which the canvas is rotated increases by 5 degrees every
time onDraw() is called.
The view is invalidated about once a second causing the view to be
Due to the rotated canvas the line drawn looks like a clock hand
rotating counter-clockwise.
This works - but not always. Sometimes the line is not drawn for one
or more seconds, although I know from the log statement that onDraw()
was called. Sometimes means: The line may be not shown after 8
seconds, then again after 35 seconds and so on.
If the canvas is not rotated the problem does not occur.
This also happens when I use a SurfaceView instead of a View.
It does not only occur in the simulator but also on my G1 - both using
Android 1.6.


public class NoMapView extends View {
    private int angle;
    private Paint paint;

    public NoMapView(Context context) {

    public NoMapView(Context context, AttributeSet attrs, int
defStyle) {
        super(context, attrs, defStyle);

    public NoMapView(Context context, AttributeSet attrs) {
        super(context, attrs);

    protected void onDraw(Canvas canvas) {

        if(paint == null) {
            paint = new Paint(Paint.ANTI_ALIAS_FLAG);

        Point center = new Point(getWidth() / 2, getHeight() / 2);;

        canvas.rotate(-angle, center.x, center.y);
        for(int i=160; i<180; i++) {
            canvas.drawPoint(i, i, paint);

//    "angle=" + angle);

        if(angle == 360) {
            angle = 0;


2. Agnes ngambek sama spica 2.1

Sejak spica saya berisikan eclair, saya pakai TSEL untuk koneksi. Tadi
malam saya coba pakaikan si agnes (3) ke spica tapi alhasil ngambek.
Ngga mau konek sama sekali, saya udah edit APN, udah nambah APN baru,
restore default APN, ganti security dari PAP, CHAP sampai None. Tetap
si agnes ngambek. Gimana yah cara bikin ngambeknya hilang? Kalau lihat
di menu testing sih user not authenticated tapi saya yakin dengan
sangat benat isian APN saya

APN 3data
User 3data
Password 3data

Ip & port kosong (udah diisi ttp aja gak bisa)

Apakah ada settingan lain yang saya kurang isi? Kartu yang sama saya
masukkan ke mifi no problem. Mohon bantuannya

Tambahan : sewaktu masih 1.5 pake si agnes gak masalah


Sent from my mobile device

"Indonesian Android Community [id-android]" 

3. Siang ini Gathering Komunitas Android, kolaborasi ISAT-Android & ID-Android, Minggu 7 Maret 2010

4. can any1 help me ... how to upgrade G1 android version from 1.0 to 1.6 ?

5. Siang ini Gathering Komunitas Android, kolaborasi ISAT-Android & ID-Android, Minggu 7 Maret 2010

6. Need List of email addresses of Android Developers

7. Andriod with XML-RPC weirdness