summaryrefslogtreecommitdiff
path: root/test/jvmti-common/NonStandardExit.java
diff options
context:
space:
mode:
author Alex Light <allight@google.com> 2019-03-20 15:52:13 -0700
committer Treehugger Robot <treehugger-gerrit@google.com> 2019-06-10 18:33:25 +0000
commitb7c640d364d32b79cb52d04750b063667a9a0c86 (patch)
tree9caafc96879f83f8e5dd3cd45b9005be6e2b7deb /test/jvmti-common/NonStandardExit.java
parent3ffb5b1576f8af0c361284ebd8d2d54c70ede3ff (diff)
JVMTI Force early return
Add support for can_force_early_return jvmti capability. This allows one to force java frames to exit early. Exited frames have all of their normal locks released. We implement this by modifying the existing method exit events to allow one to modify the exit value during the callback. This is used to implement ForceEarlyReturn by adding internal-only events that will change the return value of methods once they return (using kForcePopFrame) avoiding the need to modify the actual interpreter very deeply. This also makes it simple to continue to use the standard deoptimization functions to force the actual return. In order to simplify book-keeping the internal event is refcounted, not associated with any specific jvmtiEnv, and only settable on specific threads. The internal event is added by the ForceEarlyReturn function and then removed by the MethodExit event when we update the return value. Bug: 130028055 Test: ./test.py --host Change-Id: Ifa44605b4e8032605f503a654ddf4bd2fc6b60bf
Diffstat (limited to 'test/jvmti-common/NonStandardExit.java')
-rw-r--r--test/jvmti-common/NonStandardExit.java50
1 files changed, 50 insertions, 0 deletions
diff --git a/test/jvmti-common/NonStandardExit.java b/test/jvmti-common/NonStandardExit.java
new file mode 100644
index 0000000000..37f699e01a
--- /dev/null
+++ b/test/jvmti-common/NonStandardExit.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package art;
+
+public class NonStandardExit {
+ public static native void popFrame(Thread thr);
+ public static native void forceEarlyReturnVoid(Thread thr);
+ public static native void forceEarlyReturnFloat(Thread thr, float f);
+ public static native void forceEarlyReturnDouble(Thread thr, double f);
+ public static native void forceEarlyReturnInt(Thread thr, int f);
+ public static native void forceEarlyReturnLong(Thread thr, long f);
+ public static native void forceEarlyReturnObject(Thread thr, Object f);
+
+ public static void forceEarlyReturn(Thread thr, Object o) {
+ if (o instanceof Number && o.getClass().getPackage().equals(Object.class.getPackage())) {
+ Number n = (Number)o;
+ if (n instanceof Integer || n instanceof Short || n instanceof Byte) {
+ forceEarlyReturnInt(thr, n.intValue());
+ } else if (n instanceof Long) {
+ forceEarlyReturnLong(thr, n.longValue());
+ } else if (n instanceof Float) {
+ forceEarlyReturnFloat(thr, n.floatValue());
+ } else if (n instanceof Double) {
+ forceEarlyReturnDouble(thr, n.doubleValue());
+ } else {
+ throw new IllegalArgumentException("Unknown number subtype: " + n.getClass() + " - " + n);
+ }
+ } else if (o instanceof Character) {
+ forceEarlyReturnInt(thr, ((Character)o).charValue());
+ } else if (o instanceof Boolean) {
+ forceEarlyReturnInt(thr, ((Boolean)o).booleanValue() ? 1 : 0);
+ } else {
+ forceEarlyReturnObject(thr, o);
+ }
+ }
+}