Openj9: GetStringRegion returns invalid unicode strings when running with 鈥揦X:+CompactStrings

Created on 24 Sep 2020  路  8Comments  路  Source: eclipse/openj9

Hello,

We found the following OpenJ9 issue while debugging our application with German locale on Windows 10.

Here is a sample code:

import java.awt.Dimension;
import java.awt.GraphicsEnvironment;

import javax.swing.JFrame;

public class BugWindowTitleWithCompactStrings {

      public static void main(String[] args) {
            char[] titleChars = "Schriftgr枚脽e".toCharArray();

            // ensure title has Latin1 coder if VM option -XX:+CompactStrings is set
            String title = new String(titleChars);

            JFrame frame = new JFrame(GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration());
            frame.setName("Frame");
            frame.setTitle(title);
            frame.setSize(new Dimension(300, 100));
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
      }
}

when running this sample with -XX:+CompactStrings, the windows's title is garbled:
image

whereas when running without -XX:+CompactStrings, the window's title is correct:
image

Digging into Java's sources, we found that this comes from the JNI call to GetStringRegion in the java.desktop\windows\native\libawt\windows\awt_Window.cpp method:

void AwtWindow::_SetTitle(void *param)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    SetTitleStruct *sts = (SetTitleStruct *)param;
    jobject self = sts->window;
    jstring title = sts->title;

    AwtWindow *w = NULL;

    PDATA pData;
    JNI_CHECK_PEER_GOTO(self, ret);
    JNI_CHECK_NULL_GOTO(title, "null title", ret);

    w = (AwtWindow *)pData;
    if (::IsWindow(w->GetHWnd()))
    {
        int length = env->GetStringLength(title);
        TCHAR *buffer = new TCHAR[length + 1];
        env->GetStringRegion(title, 0, length, reinterpret_cast<jchar*>(buffer));
        buffer[length] = L'\0';
        VERIFY(::SetWindowText(w->GetHWnd(), buffer));
        delete[] buffer;
    }
ret:
    env->DeleteGlobalRef(self);
    if (title != NULL) {
        env->DeleteGlobalRef(title);
    }
    delete sts;
}

when the title string is compacted, it returns the invalid Unicode string:

0053 0063 0068 0072 0069 0066 0074 0067 0072 FFF6 FFDF 0065

instead of the expected correct one:

0053 0063 0068 0072 0069 0066 0074 0067 0072 00F6 00DF 0065

We guess that this bug can impact other Java methods than the AWT-related ones used to reproduce this issue.

It is worth noting that we do not have this issue with HotSpot version of AdoptOpenJDK 11, the problem is specific to OpenJ9.

bug vm userRaised

Most helpful comment

Hello,

I confirm that this issue was fixed in recent AdoptOpenJDK 11 openJ9 nightly builds.
Thank you very much to OpenJ9 community for this very fast fix !

Kind regards,
Alexandre

All 8 comments

Looks like a sign extension problem. @fjeremic

Probable fix is here:

https://github.com/eclipse/openj9/blob/3ed57f5b52b46b36ab39f0e6ed3fa6eb8f2a4cb1/runtime/vm/jnimisc.cpp#L948

Adding a U_16 (or better yet U_8) cast before the cast to jchar will likely fix it. The problem is that the array load macro evaluates to an I_8, not a U_8.

I suspect there will be other occurrences of this problem.

As suspected, searching for (jchar)J9JAVAARRAYOFBYTE_LOAD yields more results. The GC code is correct (if potentially inefficient) because it masks the result with (jchar)0xFF before the assignment. I'd be tempted to do it a single way (with the U_8 cast preferrably) all throughout.

@dmitripivkine

Hello,

Thank you very much, that was a fast one :)

May I ask on which AdoptOpenJDK nightly build this fix should be testable on my side ?

Kind regards,
Alexandre

It's not in the Sept 24 build, so it should be in the next one.

Actually the fix was merged late in the day, so we should either check if the next build contains it, or wait for the Sep 26 nightly.

@pshipton thanks for your answer, I'm going to check early next week (Monday 28th of Sep) with most recent nightly build

Kind regards,
Alexandre

Hello,

I confirm that this issue was fixed in recent AdoptOpenJDK 11 openJ9 nightly builds.
Thank you very much to OpenJ9 community for this very fast fix !

Kind regards,
Alexandre

Was this page helpful?
0 / 5 - 0 ratings