Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4363175

Missing JVMPI_EVENT_METHOD_ENTRY in -Xcomp, -Xmixed modes

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P2 P2
    • 1.3.1
    • 2.0
    • hotspot
    • beta
    • sparc
    • solaris_8



        Name: cl74495 Date: 08/16/2000


        With:

        java version "1.3.0"
        Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-b25)
        Java HotSpot(TM) Client VM (build 1.3.0-b25, mixed mode)

        On Solaris Sparc 2.8, in -Xcomp or -Xmixed (default) modes, the JVM
        fails to send JVMPI_EVENT_METHOD_ENTRY events for some methods,
        presumably as a result of inlining. The event appears to always be
        sent in -Xint mode.

        The following stripped down JVMPI client and and Java program
        demonstrate the problem. The JVMPI client counts METHOD_ENTRY events
        for two specific methods in the Java program. The program should
        execute each method over 1000 times, but in -Xmixed mode reports
        41, and in -Xcomp reports 0. Yes, I know the counts are not guarded
        by a raw monitor, but it happens even if I do (the program is single-
        threaded anyway) and I wanted to keep the client small. And yeah, the
        code is pretty ugly in both of them, but I'll only take the blame for
        the JVMPI client. :-)

        Cut and compile missingenter.cpp and strings.java. Run with
        java -Xrunmissingenter strings

        ---------------- missingenter.cpp ----------------
        #include <jvmpi.h>
        #include <cstring>
        #include <iostream>

        #define JVMPI(m) (jvmpi->m)

        static JVMPI_Interface *jvmpi;
        static void notify(JVMPI_Event *);

        extern "C" JNIEXPORT jint JNICALL
        JVM_OnLoad(JavaVM *jvm, char *options, void *reserved)
        {
                int res = jvm->GetEnv((void **)&jvmpi, JVMPI_VERSION_1);

                if (res < 0) {
                        return JNI_ERR;
                }

                jvmpi->NotifyEvent = notify;

                JVMPI(EnableEvent)(JVMPI_EVENT_CLASS_LOAD, NULL);
                JVMPI(EnableEvent)(JVMPI_EVENT_JVM_SHUT_DOWN, NULL);
                JVMPI(EnableEvent)(JVMPI_EVENT_METHOD_ENTRY, NULL);

                return JNI_OK;
        }

        void
        notify(JVMPI_Event * event)
        {
                static jmethodID id1, id2;
                static unsigned long count1, count2;

                switch (event->event_type) {
                case JVMPI_EVENT_CLASS_LOAD:
                        if (strcmp("strings", event->u.class_load.class_name) == 0) {
                                JVMPI_Method * m = event->u.class_load.methods;
                                for (jint i = 0; i < event->u.class_load.num_methods &&
        (!id1 || !id2); ++i) {
                                        if (strcmp(m[i].method_name, "detab_StringBuffer
        ") == 0) {
                                                id1 = m[i].method_id;
                                                cout << "detab_StringBuffer ID: " << (vo
        id *)id1 << endl;
                                        } else if (strcmp(m[i].method_name, "detab_Strin
        g") == 0) {
                                                id2 = m[i].method_id;
                                                cout << "detab_String ID: " << (void *)i
        d2 << endl;
                                        }
                                }
                        }
                        break;
                case JVMPI_EVENT_JVM_SHUT_DOWN:
                        cout << "detab_StringBuffer(): " << count1 << endl;
                        cout << "detab_String(): " << count2 << endl;
                        break;
                case JVMPI_EVENT_METHOD_ENTRY:
                        if (event->u.method.method_id == id1) {
                                ++count1;
                        } else if (event->u.method.method_id == id2) {
                                ++count2;
                        }
                        break;
                default:
                        break;
                }
        }
        ---------------- strings.java ----------------
        public class strings {

        static String detab_String(String s) {
                if (s.indexOf('\t') == -1)
                        return s;
                String res = "";;
                int len = s.length(), pos = 0, i = 0;
                for (; i < len && s.charAt(i) == '\t'; i++) {
                        res += " ";
                        pos += 8;
                }
                for (; i < len; i++) {
                        char c = s.charAt(i);
                        if (c == '\t') {
                                do {
                                        res += " ";
                                        pos++;
                                } while (pos % 8 != 0);
                        }
                        else {
                                res += c;
                                pos++;
                        }
                }
                return res;
        }
                
        static String detab_StringBuffer(String s) {
                if (s.indexOf('\t') == -1)
                        return s;
                StringBuffer sb = new StringBuffer();
                int len = s.length(), pos = 0, i = 0;
                for (; i < len && s.charAt(i) == '\t'; i++) {
                        sb.append(" ");
                        pos += 8;
                }
                for (; i < len; i++) {
                        char c = s.charAt(i);
                        if (c == '\t') {
                                do {
                                        sb.append(' ');
                                        pos++;
                                } while (pos % 8 != 0);
                        }
                        else {
                                sb.append(c);
                                pos++;
                        }
                }
                return sb.toString();
        }
                
        static String testlist[] = {
                "",
                "\t",
                "\t\t\tabc",
                "abc\tdef",
                "1234567\t8",
                "12345678\t9",
                "123456789\t"
        };
                
        public static void main(String args[]) {
                System.out.println("Comparison of String vs. StringBuffer...");
                for (int i = 0; i < testlist.length; i++) {
                        String tc = testlist[i];
                        if (!detab_String(tc).equals(detab_StringBuffer(tc)))
                                System.err.println(tc);
                }
                
                String test_string = "\t\tthis is a test\tof detabbing performance";
                int N = 1000;
                
                System.out.print("" + N + " Strings");
                for (int i = 0; i < N; i++) {
                        if ((i % 100) == 0)
                                System.out.print('.');
                        detab_String(test_string);
                }
                
                System.out.print("\n" + N + " StringBuffers");
                for (int i = 0; i < N; i++) {
                        if ((i % 100) == 0)
                                System.out.print('.');
                        detab_StringBuffer(test_string);
                }
                System.out.println("\nFinished");
        }
        }
        (Review ID: 108510)
        ======================================================================

              mgharahgsunw Mohammad Gharahgouzloo (Inactive)
              clucasius Carlos Lucasius (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

                Created:
                Updated:
                Resolved:
                Imported:
                Indexed: