20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @bug 8136421 27 * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64" 28 * @library / /testlibrary /../../test/lib 29 * @compile ../common/CompilerToVMHelper.java 30 * @run main ClassFileInstaller 31 * jdk.vm.ci.hotspot.CompilerToVMHelper 32 * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockExperimentalVMOptions 33 * -XX:+EnableJVMCI compiler.jvmci.compilerToVM.GetNextStackFrameTest 34 */ 35 36 package compiler.jvmci.compilerToVM; 37 38 import compiler.jvmci.common.CTVMUtilities; 39 import java.lang.reflect.Method; 40 import jdk.vm.ci.hotspot.CompilerToVM; 41 import jdk.vm.ci.hotspot.CompilerToVMHelper; 42 import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl; 43 import jdk.vm.ci.hotspot.HotSpotStackFrameReference; 44 import jdk.test.lib.Asserts; 45 46 public class GetNextStackFrameTest { 47 private static final int RECURSION_AMOUNT = 3; 48 private static final HotSpotResolvedJavaMethodImpl REC_FRAME_METHOD; 49 private static final HotSpotResolvedJavaMethodImpl FRAME1_METHOD; 50 private static final HotSpotResolvedJavaMethodImpl FRAME2_METHOD; 51 private static final HotSpotResolvedJavaMethodImpl FRAME3_METHOD; 52 private static final HotSpotResolvedJavaMethodImpl FRAME4_METHOD; 53 private static final HotSpotResolvedJavaMethodImpl RUN_METHOD; 54 55 static { 56 Method method; 57 try { 58 Class<?> aClass = GetNextStackFrameTest.class; 59 method = aClass.getDeclaredMethod("recursiveFrame", int.class); 60 REC_FRAME_METHOD = CTVMUtilities.getResolvedMethod(method); 61 method = aClass.getDeclaredMethod("frame1"); 62 FRAME1_METHOD = CTVMUtilities.getResolvedMethod(method); 63 method = aClass.getDeclaredMethod("frame2"); 64 FRAME2_METHOD = CTVMUtilities.getResolvedMethod(method); 65 method = aClass.getDeclaredMethod("frame3"); 66 FRAME3_METHOD = CTVMUtilities.getResolvedMethod(method); 67 method = aClass.getDeclaredMethod("frame4"); 68 FRAME4_METHOD = CTVMUtilities.getResolvedMethod(method); 69 method = Thread.class.getDeclaredMethod("run"); 70 RUN_METHOD = CTVMUtilities.getResolvedMethod(Thread.class, method); 71 } catch (NoSuchMethodException e) { 72 throw new Error("TEST BUG: can't find a test method", e); 73 } 74 } 75 76 public static void main(String[] args) { 77 new GetNextStackFrameTest().test(); 78 } 79 80 private void test() { 81 // Create new thread to get new clean stack 82 Thread thread = new Thread(() -> recursiveFrame(RECURSION_AMOUNT)); 83 thread.start(); 84 try { 85 thread.join(); 86 } catch (InterruptedException e) { 87 throw new Error("Interrupted while waiting to join", e); 88 } 89 } 90 91 // Helper methods for a longer stack 92 private void recursiveFrame(int recursionAmount) { 109 frame4(); 110 } 111 112 private void frame4() { 113 check(); 114 } 115 116 private void check() { 117 findFirst(); 118 walkThrough(); 119 skipAll(); 120 findNextSkipped(); 121 findYourself(); 122 } 123 124 /** 125 * Finds the first topmost frame from the list of methods to search 126 */ 127 private void findFirst() { 128 checkNextFrameFor(null /* topmost frame */, 129 new HotSpotResolvedJavaMethodImpl[] 130 {FRAME2_METHOD, FRAME3_METHOD, FRAME4_METHOD}, 131 FRAME4_METHOD, 0); 132 } 133 134 /** 135 * Walks through whole stack and checks that every frame could be found 136 * while going down the stack till the end 137 */ 138 private void walkThrough() { 139 // Check that we would get a frame 4 starting from the topmost frame 140 HotSpotStackFrameReference nextStackFrame = checkNextFrameFor( 141 null /* topmost frame */, 142 new HotSpotResolvedJavaMethodImpl[] {FRAME4_METHOD}, 143 FRAME4_METHOD, 0); 144 // Check that we would get a frame 3 starting from frame 4 when we try 145 // to search one of the next two frames 146 nextStackFrame = checkNextFrameFor(nextStackFrame, 147 new HotSpotResolvedJavaMethodImpl[] {FRAME3_METHOD, 148 FRAME2_METHOD}, 149 FRAME3_METHOD, 0); 150 // Check that we would get a frame 1 151 nextStackFrame = checkNextFrameFor(nextStackFrame, 152 new HotSpotResolvedJavaMethodImpl[] {FRAME1_METHOD}, 153 FRAME1_METHOD, 0); 154 // Check that we would skip (RECURSION_AMOUNT - 1) methods and find a 155 // recursionFrame starting from frame 1 156 nextStackFrame = checkNextFrameFor(nextStackFrame, 157 new HotSpotResolvedJavaMethodImpl[] {REC_FRAME_METHOD}, 158 REC_FRAME_METHOD, RECURSION_AMOUNT - 1); 159 // Check that we would get a Thread::run method frame; 160 nextStackFrame = checkNextFrameFor(nextStackFrame, 161 new HotSpotResolvedJavaMethodImpl[] {RUN_METHOD}, 162 RUN_METHOD, 0); 163 // Check that there are no more frames after thread's run method 164 nextStackFrame = CompilerToVMHelper.getNextStackFrame(nextStackFrame, 165 null /* any */, 0); 166 Asserts.assertNull(nextStackFrame, 167 "Found stack frame after Thread::run"); 168 } 169 170 /** 171 * Skips all frames to get null at the end of the stack 172 */ 173 private void skipAll() { 174 // Skip all frames (stack size) + 2 (getNextStackFrame() itself 175 // and from CompilerToVMHelper) 176 int initialSkip = Thread.currentThread().getStackTrace().length + 2; 177 HotSpotStackFrameReference nextStackFrame = CompilerToVMHelper 178 .getNextStackFrame(null /* topmost frame */, null /* any */, 179 initialSkip); 180 Asserts.assertNull(nextStackFrame, "Unexpected frame"); 181 } 182 183 /** 184 * Search for any frame skipping one frame 185 */ 186 private void findNextSkipped() { 187 // Get frame 4 188 HotSpotStackFrameReference nextStackFrame = CompilerToVMHelper 189 .getNextStackFrame(null /* topmost frame */, 190 new HotSpotResolvedJavaMethodImpl[] {FRAME4_METHOD}, 0); 191 // Get frame 2 by skipping one method starting from frame 4 192 checkNextFrameFor(nextStackFrame, null /* any */, 193 FRAME2_METHOD , 1 /* skip one */); 194 } 195 196 /** 197 * Finds test method in the stack 198 */ 199 private void findYourself() { 200 Method method; 201 try { 202 method = CompilerToVM.class.getDeclaredMethod("getNextStackFrame", 203 HotSpotStackFrameReference.class, 204 HotSpotResolvedJavaMethodImpl[].class, int.class); 205 } catch (NoSuchMethodException e) { 206 throw new Error("TEST BUG: can't find getNextStackFrame method"); 207 } 208 HotSpotResolvedJavaMethodImpl self 209 = CTVMUtilities.getResolvedMethod(CompilerToVM.class, method); 210 checkNextFrameFor(null /* topmost frame */, null /* any */, self, 0); 211 } 212 213 /** 214 * Searches next frame and checks that it equals to expected 215 * 216 * @param currentFrame start frame to search from 217 * @param searchMethods a list of methods to search 218 * @param expected expected frame 219 * @param skip amount of frames to be skipped 220 * @return frame reference 221 */ 222 private HotSpotStackFrameReference checkNextFrameFor( 223 HotSpotStackFrameReference currentFrame, 224 HotSpotResolvedJavaMethodImpl[] searchMethods, 225 HotSpotResolvedJavaMethodImpl expected, 226 int skip) { 227 HotSpotStackFrameReference nextStackFrame = CompilerToVMHelper 228 .getNextStackFrame(currentFrame, searchMethods, skip); 229 Asserts.assertNotNull(nextStackFrame); 230 Asserts.assertTrue(nextStackFrame.isMethod(expected), 231 "Unexpected next frame: " + nextStackFrame 232 + " from current frame: " + currentFrame); 233 return nextStackFrame; 234 } 235 } | 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @bug 8136421 27 * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64" 28 * @library / /testlibrary /../../test/lib 29 * @compile ../common/CompilerToVMHelper.java 30 * @run main ClassFileInstaller 31 * jdk.vm.ci.hotspot.CompilerToVMHelper 32 * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockExperimentalVMOptions 33 * -XX:+EnableJVMCI compiler.jvmci.compilerToVM.GetNextStackFrameTest 34 */ 35 36 package compiler.jvmci.compilerToVM; 37 38 import compiler.jvmci.common.CTVMUtilities; 39 import java.lang.reflect.Method; 40 import jdk.vm.ci.hotspot.CompilerToVMHelper; 41 import jdk.vm.ci.hotspot.HotSpotStackFrameReference; 42 import jdk.vm.ci.meta.ResolvedJavaMethod; 43 import jdk.test.lib.Asserts; 44 45 public class GetNextStackFrameTest { 46 private static final int RECURSION_AMOUNT = 3; 47 private static final ResolvedJavaMethod REC_FRAME_METHOD; 48 private static final ResolvedJavaMethod FRAME1_METHOD; 49 private static final ResolvedJavaMethod FRAME2_METHOD; 50 private static final ResolvedJavaMethod FRAME3_METHOD; 51 private static final ResolvedJavaMethod FRAME4_METHOD; 52 private static final ResolvedJavaMethod RUN_METHOD; 53 54 static { 55 Method method; 56 try { 57 Class<?> aClass = GetNextStackFrameTest.class; 58 method = aClass.getDeclaredMethod("recursiveFrame", int.class); 59 REC_FRAME_METHOD = CTVMUtilities.getResolvedMethod(method); 60 method = aClass.getDeclaredMethod("frame1"); 61 FRAME1_METHOD = CTVMUtilities.getResolvedMethod(method); 62 method = aClass.getDeclaredMethod("frame2"); 63 FRAME2_METHOD = CTVMUtilities.getResolvedMethod(method); 64 method = aClass.getDeclaredMethod("frame3"); 65 FRAME3_METHOD = CTVMUtilities.getResolvedMethod(method); 66 method = aClass.getDeclaredMethod("frame4"); 67 FRAME4_METHOD = CTVMUtilities.getResolvedMethod(method); 68 method = Thread.class.getDeclaredMethod("run"); 69 RUN_METHOD = CTVMUtilities.getResolvedMethod(Thread.class, method); 70 } catch (NoSuchMethodException e) { 71 throw new Error("TEST BUG: can't find a test method : " + e, e); 72 } 73 } 74 75 public static void main(String[] args) { 76 new GetNextStackFrameTest().test(); 77 } 78 79 private void test() { 80 // Create new thread to get new clean stack 81 Thread thread = new Thread(() -> recursiveFrame(RECURSION_AMOUNT)); 82 thread.start(); 83 try { 84 thread.join(); 85 } catch (InterruptedException e) { 86 throw new Error("Interrupted while waiting to join", e); 87 } 88 } 89 90 // Helper methods for a longer stack 91 private void recursiveFrame(int recursionAmount) { 108 frame4(); 109 } 110 111 private void frame4() { 112 check(); 113 } 114 115 private void check() { 116 findFirst(); 117 walkThrough(); 118 skipAll(); 119 findNextSkipped(); 120 findYourself(); 121 } 122 123 /** 124 * Finds the first topmost frame from the list of methods to search 125 */ 126 private void findFirst() { 127 checkNextFrameFor(null /* topmost frame */, 128 new ResolvedJavaMethod[] 129 {FRAME2_METHOD, FRAME3_METHOD, FRAME4_METHOD}, 130 FRAME4_METHOD, 0); 131 } 132 133 /** 134 * Walks through whole stack and checks that every frame could be found 135 * while going down the stack till the end 136 */ 137 private void walkThrough() { 138 // Check that we would get a frame 4 starting from the topmost frame 139 HotSpotStackFrameReference nextStackFrame = checkNextFrameFor( 140 null /* topmost frame */, 141 new ResolvedJavaMethod[] {FRAME4_METHOD}, 142 FRAME4_METHOD, 0); 143 // Check that we would get a frame 3 starting from frame 4 when we try 144 // to search one of the next two frames 145 nextStackFrame = checkNextFrameFor(nextStackFrame, 146 new ResolvedJavaMethod[] {FRAME3_METHOD, 147 FRAME2_METHOD}, 148 FRAME3_METHOD, 0); 149 // Check that we would get a frame 1 150 nextStackFrame = checkNextFrameFor(nextStackFrame, 151 new ResolvedJavaMethod[] {FRAME1_METHOD}, 152 FRAME1_METHOD, 0); 153 // Check that we would skip (RECURSION_AMOUNT - 1) methods and find a 154 // recursionFrame starting from frame 1 155 nextStackFrame = checkNextFrameFor(nextStackFrame, 156 new ResolvedJavaMethod[] {REC_FRAME_METHOD}, 157 REC_FRAME_METHOD, RECURSION_AMOUNT - 1); 158 // Check that we would get a Thread::run method frame; 159 nextStackFrame = checkNextFrameFor(nextStackFrame, 160 new ResolvedJavaMethod[] {RUN_METHOD}, 161 RUN_METHOD, 0); 162 // Check that there are no more frames after thread's run method 163 nextStackFrame = CompilerToVMHelper.getNextStackFrame(nextStackFrame, 164 null /* any */, 0); 165 Asserts.assertNull(nextStackFrame, 166 "Found stack frame after Thread::run"); 167 } 168 169 /** 170 * Skips all frames to get null at the end of the stack 171 */ 172 private void skipAll() { 173 // Skip all frames (stack size) + 2 (getNextStackFrame() itself 174 // and from CompilerToVMHelper) 175 int initialSkip = Thread.currentThread().getStackTrace().length + 2; 176 HotSpotStackFrameReference nextStackFrame = CompilerToVMHelper 177 .getNextStackFrame(null /* topmost frame */, null /* any */, 178 initialSkip); 179 Asserts.assertNull(nextStackFrame, "Unexpected frame"); 180 } 181 182 /** 183 * Search for any frame skipping one frame 184 */ 185 private void findNextSkipped() { 186 // Get frame 4 187 HotSpotStackFrameReference nextStackFrame = CompilerToVMHelper 188 .getNextStackFrame(null /* topmost frame */, 189 new ResolvedJavaMethod[] {FRAME4_METHOD}, 0); 190 // Get frame 2 by skipping one method starting from frame 4 191 checkNextFrameFor(nextStackFrame, null /* any */, 192 FRAME2_METHOD , 1 /* skip one */); 193 } 194 195 /** 196 * Finds test method in the stack 197 */ 198 private void findYourself() { 199 Method method; 200 Class<?> aClass = CompilerToVMHelper.CompilerToVMClass(); 201 try { 202 method = aClass.getDeclaredMethod( 203 "getNextStackFrame", 204 HotSpotStackFrameReference.class, 205 ResolvedJavaMethod[].class, 206 int.class); 207 } catch (NoSuchMethodException e) { 208 throw new Error("TEST BUG: can't find getNextStackFrame : " + e, e); 209 } 210 ResolvedJavaMethod self 211 = CTVMUtilities.getResolvedMethod(aClass, method); 212 checkNextFrameFor(null /* topmost frame */, null /* any */, self, 0); 213 } 214 215 /** 216 * Searches next frame and checks that it equals to expected 217 * 218 * @param currentFrame start frame to search from 219 * @param searchMethods a list of methods to search 220 * @param expected expected frame 221 * @param skip amount of frames to be skipped 222 * @return frame reference 223 */ 224 private HotSpotStackFrameReference checkNextFrameFor( 225 HotSpotStackFrameReference currentFrame, 226 ResolvedJavaMethod[] searchMethods, 227 ResolvedJavaMethod expected, 228 int skip) { 229 HotSpotStackFrameReference nextStackFrame = CompilerToVMHelper 230 .getNextStackFrame(currentFrame, searchMethods, skip); 231 Asserts.assertNotNull(nextStackFrame); 232 Asserts.assertTrue(nextStackFrame.isMethod(expected), 233 "Unexpected next frame: " + nextStackFrame 234 + " from current frame: " + currentFrame); 235 return nextStackFrame; 236 } 237 } |