Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-2036335 | 1.4.0 | Mohammad Gharahgouzloo | P2 | Resolved | Fixed | beta |
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)
======================================================================
- backported by
-
JDK-2036335 Missing JVMPI_EVENT_METHOD_ENTRY in -Xcomp, -Xmixed modes
-
- Resolved
-
- relates to
-
JDK-4407207 [sparc-c1-lady] jvmpi_method_enter crashes with ScavengeALot
-
- Closed
-