Skip to content

Commit 1f185f5

Browse files
[GR-38490] Query performance counters via Polyglot Native API.
PullRequest: graal/12384
2 parents afbbfd0 + 9e39f56 commit 1f185f5

File tree

13 files changed

+298
-10
lines changed

13 files changed

+298
-10
lines changed

sdk/src/org.graalvm.nativeimage/snapshot.sigtest

+1
Original file line numberDiff line numberDiff line change
@@ -818,6 +818,7 @@ meth public static byte toCBoolean(boolean)
818818
meth public static java.lang.String toJavaString(org.graalvm.nativeimage.c.type.CCharPointer)
819819
meth public static java.lang.String toJavaString(org.graalvm.nativeimage.c.type.CCharPointer,org.graalvm.word.UnsignedWord)
820820
meth public static java.lang.String toJavaString(org.graalvm.nativeimage.c.type.CCharPointer,org.graalvm.word.UnsignedWord,java.nio.charset.Charset)
821+
meth public static java.lang.String utf8ToJavaString(org.graalvm.nativeimage.c.type.CCharPointer)
821822
meth public static java.nio.ByteBuffer asByteBuffer(org.graalvm.word.PointerBase,int)
822823
meth public static org.graalvm.nativeimage.c.type.CTypeConversion$CCharPointerHolder toCBytes(byte[])
823824
meth public static org.graalvm.nativeimage.c.type.CTypeConversion$CCharPointerHolder toCString(java.lang.CharSequence)

sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/c/type/CTypeConversion.java

+12
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,18 @@ public static String toJavaString(CCharPointer cString, UnsignedWord length, Cha
167167
return ImageSingletons.lookup(CTypeConversionSupport.class).toJavaString(cString, length, charset);
168168
}
169169

170+
/**
171+
* Decodes a UTF-8 encoded, 0 terminated C {@code char*} to a Java string.
172+
*
173+
* @param utf8String the pointer to a UTF-8 encoded, 0 terminated C string
174+
* @return a Java string
175+
*
176+
* @since 22.3
177+
*/
178+
public static String utf8ToJavaString(CCharPointer utf8String) {
179+
return ImageSingletons.lookup(CTypeConversionSupport.class).utf8ToJavaString(utf8String);
180+
}
181+
170182
/**
171183
* Converts a Java boolean into a C int containing boolean values.
172184
*

sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/impl/CTypeConversionSupport.java

+2
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ public interface CTypeConversionSupport {
6262

6363
String toJavaString(CCharPointer cString, UnsignedWord length, Charset charset);
6464

65+
String utf8ToJavaString(CCharPointer utf8String);
66+
6567
CCharPointerHolder toCBytes(byte[] bytes);
6668

6769
ByteBuffer asByteBuffer(PointerBase address, int size);

substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/GCImpl.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -1225,7 +1225,7 @@ private static class CollectionVMOperation extends NativeVMOperation {
12251225

12261226
@Override
12271227
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
1228-
protected boolean isGC() {
1228+
public boolean isGC() {
12291229
return true;
12301230
}
12311231

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/c/CTypeConversionSupportImpl.java

+11
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
import java.nio.ByteBuffer;
2828
import java.nio.charset.Charset;
29+
import java.nio.charset.StandardCharsets;
2930
import java.util.Arrays;
3031

3132
import com.oracle.svm.core.jdk.Target_java_nio_DirectByteBuffer;
@@ -85,6 +86,16 @@ public String toJavaString(CCharPointer cString, UnsignedWord length, Charset ch
8586
}
8687
}
8788

89+
@Override
90+
public String utf8ToJavaString(CCharPointer utf8String) {
91+
if (utf8String.isNull()) {
92+
return null;
93+
} else {
94+
// UTF-8 does not break zero-terminated strings.
95+
return toJavaStringWithCharset(utf8String, SubstrateUtil.strlen(utf8String), StandardCharsets.UTF_8);
96+
}
97+
}
98+
8899
private static String toJavaStringWithCharset(CCharPointer cString, UnsignedWord length, Charset charset) {
89100
byte[] bytes = new byte[(int) length.rawValue()];
90101
for (int i = 0; i < bytes.length; i++) {

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jvmstat/PerfDataSupport.java

+8
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.graalvm.nativeimage.ImageSingletons;
3030
import org.graalvm.nativeimage.Platform;
3131
import org.graalvm.nativeimage.Platforms;
32+
import org.graalvm.nativeimage.c.type.CLongPointer;
3233
import org.graalvm.nativeimage.hosted.Feature;
3334

3435
import com.oracle.svm.core.annotate.AutomaticFeature;
@@ -45,6 +46,8 @@ public interface PerfDataSupport {
4546
ByteBuffer createLong(String name, int variability, int units, long value);
4647

4748
ByteBuffer createByteArray(String name, int variability, int units, byte[] value, int maxLength);
49+
50+
CLongPointer getLong(String name);
4851
}
4952

5053
class NoPerfDataSupport implements PerfDataSupport {
@@ -81,6 +84,11 @@ public ByteBuffer createLong(String name, int variability, int units, long value
8184
public ByteBuffer createByteArray(String name, int variability, int units, byte[] value, int maxLength) {
8285
throw new IllegalArgumentException("Performance data is not supported.");
8386
}
87+
88+
@Override
89+
public CLongPointer getLong(String name) {
90+
throw new IllegalArgumentException("Performance data is not supported.");
91+
}
8492
}
8593

8694
@AutomaticFeature

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/VMOperation.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ public final String getName() {
6363
}
6464

6565
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
66-
protected boolean isGC() {
66+
public boolean isGC() {
6767
return false;
6868
}
6969

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/VMOperationControl.java

+2
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,8 @@ void setInProgress(VMOperation operation, IsolateThread queueingThread, IsolateT
255255
inProgress.executingThread = executingThread;
256256
inProgress.operation = operation;
257257
inProgress.queueingThread = queueingThread;
258+
259+
VMOperationListenerSupport.get().vmOperationChanged(operation);
258260
}
259261

260262
void enqueue(JavaVMOperation operation) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright (c) 2020, 2020, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
package com.oracle.svm.core.thread;
26+
27+
import com.oracle.svm.core.annotate.Uninterruptible;
28+
29+
public interface VMOperationListener {
30+
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
31+
void vmOperationChanged(VMOperation operation);
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright (c) 2020, 2020, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
package com.oracle.svm.core.thread;
26+
27+
import org.graalvm.nativeimage.ImageSingletons;
28+
import org.graalvm.nativeimage.hosted.Feature;
29+
30+
import com.oracle.svm.core.annotate.AutomaticFeature;
31+
32+
@AutomaticFeature
33+
public class VMOperationListenerFeature implements Feature {
34+
@Override
35+
public void afterRegistration(AfterRegistrationAccess access) {
36+
ImageSingletons.add(VMOperationListenerSupport.class, new VMOperationListenerSupport());
37+
}
38+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Copyright (c) 2020, 2020, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
package com.oracle.svm.core.thread;
26+
27+
import java.util.Arrays;
28+
29+
import org.graalvm.compiler.api.replacements.Fold;
30+
import org.graalvm.nativeimage.ImageSingletons;
31+
import org.graalvm.nativeimage.Platform;
32+
import org.graalvm.nativeimage.Platforms;
33+
34+
import com.oracle.svm.core.annotate.Uninterruptible;
35+
36+
public class VMOperationListenerSupport {
37+
private VMOperationListener[] listeners;
38+
39+
@Platforms(Platform.HOSTED_ONLY.class)
40+
public VMOperationListenerSupport() {
41+
listeners = new VMOperationListener[0];
42+
}
43+
44+
@Platforms(Platform.HOSTED_ONLY.class)
45+
public synchronized void register(VMOperationListener listener) {
46+
assert listener != null;
47+
int oldLength = listeners.length;
48+
// We expect a very small number of listeners, so only increase the size by 1.
49+
listeners = Arrays.copyOf(listeners, oldLength + 1);
50+
listeners[oldLength] = listener;
51+
}
52+
53+
@Fold
54+
public static VMOperationListenerSupport get() {
55+
return ImageSingletons.lookup(VMOperationListenerSupport.class);
56+
}
57+
58+
@Uninterruptible(reason = "Force that all listeners are uninterruptible.")
59+
public void vmOperationChanged(VMOperation operation) {
60+
for (int i = 0; i < listeners.length; i++) {
61+
listeners[i].vmOperationChanged(operation);
62+
}
63+
}
64+
}

substratevm/src/org.graalvm.polyglot.nativeapi/src/org/graalvm/polyglot/nativeapi/PolyglotNativeAPI.java

+26-8
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
import org.graalvm.polyglot.nativeapi.types.CInt16Pointer;
7474
import org.graalvm.polyglot.nativeapi.types.CInt32Pointer;
7575
import org.graalvm.polyglot.nativeapi.types.CInt64Pointer;
76+
import org.graalvm.polyglot.nativeapi.types.CInt64PointerPointer;
7677
import org.graalvm.polyglot.nativeapi.types.CInt8Pointer;
7778
import org.graalvm.polyglot.nativeapi.types.CUnsignedBytePointer;
7879
import org.graalvm.polyglot.nativeapi.types.CUnsignedIntPointer;
@@ -111,6 +112,7 @@
111112
import com.oracle.svm.core.c.CUnsigned;
112113
import com.oracle.svm.core.handles.ObjectHandlesImpl;
113114
import com.oracle.svm.core.handles.ThreadLocalHandles;
115+
import com.oracle.svm.core.jvmstat.PerfDataSupport;
114116
import com.oracle.svm.core.thread.ThreadingSupportImpl;
115117
import com.oracle.svm.core.threadlocal.FastThreadLocalFactory;
116118
import com.oracle.svm.core.threadlocal.FastThreadLocalObject;
@@ -335,7 +337,7 @@ public static PolyglotStatus poly_context_builder_engine(PolyglotIsolateThread t
335337
public static PolyglotStatus poly_context_builder_option(PolyglotIsolateThread thread, PolyglotContextBuilder context_builder, @CConst CCharPointer key_utf8, @CConst CCharPointer value_utf8) {
336338
resetErrorState();
337339
Context.Builder contextBuilder = fetchHandle(context_builder);
338-
contextBuilder.option(CTypeConversion.toJavaString(key_utf8), CTypeConversion.toJavaString(value_utf8));
340+
contextBuilder.option(CTypeConversion.utf8ToJavaString(key_utf8), CTypeConversion.utf8ToJavaString(value_utf8));
339341
return poly_ok;
340342
}
341343

@@ -533,8 +535,8 @@ public static PolyglotStatus poly_context_eval(PolyglotIsolateThread thread, Pol
533535
resetErrorState();
534536
Context c = fetchHandle(context);
535537
String languageName = CTypeConversion.toJavaString(language_id);
536-
String jName = CTypeConversion.toJavaString(name_utf8);
537-
String jCode = CTypeConversion.toJavaString(source_utf8);
538+
String jName = CTypeConversion.utf8ToJavaString(name_utf8);
539+
String jCode = CTypeConversion.utf8ToJavaString(source_utf8);
538540

539541
Source sourceCode = Source.newBuilder(languageName, jCode, jName).build();
540542
Value evalResult = c.eval(sourceCode);
@@ -663,7 +665,7 @@ public static PolyglotStatus poly_value_execute(PolyglotIsolateThread thread, Po
663665
public static PolyglotStatus poly_value_get_member(PolyglotIsolateThread thread, PolyglotValue value, @CConst CCharPointer utf8_identifier, PolyglotValuePointer result) {
664666
resetErrorState();
665667
Value jObject = fetchHandle(value);
666-
result.write(createHandle(jObject.getMember(CTypeConversion.toJavaString(utf8_identifier))));
668+
result.write(createHandle(jObject.getMember(CTypeConversion.utf8ToJavaString(utf8_identifier))));
667669
return poly_ok;
668670
}
669671

@@ -680,7 +682,7 @@ public static PolyglotStatus poly_value_put_member(PolyglotIsolateThread thread,
680682
resetErrorState();
681683
Value jObject = fetchHandle(value);
682684
Value jMember = fetchHandle(member);
683-
jObject.putMember(CTypeConversion.toJavaString(utf8_identifier), jMember);
685+
jObject.putMember(CTypeConversion.utf8ToJavaString(utf8_identifier), jMember);
684686
return poly_ok;
685687
}
686688

@@ -696,7 +698,7 @@ public static PolyglotStatus poly_value_put_member(PolyglotIsolateThread thread,
696698
public static PolyglotStatus poly_value_has_member(PolyglotIsolateThread thread, PolyglotValue value, @CConst CCharPointer utf8_identifier, CBoolPointer result) {
697699
resetErrorState();
698700
Value jObject = fetchHandle(value);
699-
result.write(CTypeConversion.toCBoolean(jObject.hasMember(CTypeConversion.toJavaString(utf8_identifier))));
701+
result.write(CTypeConversion.toCBoolean(jObject.hasMember(CTypeConversion.utf8ToJavaString(utf8_identifier))));
700702
return poly_ok;
701703
}
702704

@@ -1603,7 +1605,7 @@ public static PolyglotStatus poly_get_callback_info(PolyglotIsolateThread thread
16031605
@CEntryPoint(name = "poly_throw_exception", exceptionHandler = ExceptionHandler.class, documentation = {
16041606
"Raises an exception in a C callback.",
16051607
"",
1606-
"Invocation of this method does not interrupt control-flow so it is neccesarry to return from a function after ",
1608+
"Invocation of this method does not interrupt control-flow so it is necessary to return from a function after ",
16071609
"the exception has been raised. If this method is called multiple times only the last exception will be thrown in",
16081610
"in the guest language.",
16091611
"",
@@ -1612,7 +1614,7 @@ public static PolyglotStatus poly_get_callback_info(PolyglotIsolateThread thread
16121614
})
16131615
public static PolyglotStatus poly_throw_exception(PolyglotIsolateThread thread, @CConst CCharPointer utf8_message) {
16141616
resetErrorState();
1615-
exceptionsTL.set(new CallbackException(CTypeConversion.toJavaString(utf8_message)));
1617+
exceptionsTL.set(new CallbackException(CTypeConversion.utf8ToJavaString(utf8_message)));
16161618
return poly_ok;
16171619
}
16181620

@@ -1864,6 +1866,22 @@ private static class PolyglotCallbackInfoInternal {
18641866
}
18651867
}
18661868

1869+
@CEntryPoint(name = "poly_perf_data_get_address_of_int64_t", exceptionHandler = ExceptionHandler.class, documentation = {
1870+
"Gets the address of the int64_t value for a performance data entry of type long. Performance data support must be enabled.",
1871+
"",
1872+
" @param utf8_key UTF8-encoded, 0 terminated key that identifies the performance data entry.",
1873+
" @param result a pointer to which the address of the int64_t value will be written.",
1874+
" @return poly_ok if everything went ok, otherwise an error occurred.",
1875+
" @since 22.3",
1876+
})
1877+
public static PolyglotStatus poly_perf_data_get_address_of_int64_t(PolyglotIsolateThread thread, CCharPointer utf8Key, CInt64PointerPointer result) {
1878+
resetErrorState();
1879+
String key = CTypeConversion.utf8ToJavaString(utf8Key);
1880+
CInt64Pointer ptr = (CInt64Pointer) ImageSingletons.lookup(PerfDataSupport.class).getLong(key);
1881+
result.write(ptr);
1882+
return poly_ok;
1883+
}
1884+
18671885
private static void writeString(String valueString, CCharPointer buffer, UnsignedWord length, SizeTPointer result, Charset charset) {
18681886
UnsignedWord stringLength = WordFactory.unsigned(valueString.getBytes(charset).length);
18691887
if (buffer.isNull()) {

0 commit comments

Comments
 (0)