1 /* 2 * Copyright (c) 2018, 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. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 Pseudo Java code: 26 27 class CondyNestedResolution { 28 public static Object bsm1arg(MethodHandles$Lookup p1, String p2, Object p3, Object p4) { 29 System.out.println("In bsm1arg"); 30 System.out.println(p4); 31 return p4; 32 } 33 public static Object bsm2arg(MethodHandles$Lookup p1, String p2, Object p3, Object p4, Object p5) { 34 System.out.println("In bsm2arg"); 35 System.out.println(p4); 36 System.out.println(p5); 37 return p4; 38 } 39 public static Object bsm3arg(MethodHandles$Lookup p1, String p2, Object p3, Object p4, Object p5, Object p6) { 40 System.out.println("In bsm3arg"); 41 System.out.println(p4); 42 System.out.println(p5); 43 System.out.println(p6); 44 return p4; 45 } 46 public static Object bsm4arg(MethodHandles$Lookup p1, String p2, Object p3, Object p4, Object p5, Object p6, Object p7) { 47 System.out.println("In bsm4arg"); 48 System.out.println(p4); 49 System.out.println(p5); 50 System.out.println(p6); 51 System.out.println(p7); 52 return p4; 53 } 54 55 public static void test_condy() { 56 // The following condy of BSM#8 results in the invocation of bootstrap method bsm4arg with the following 57 // parameters: 58 // bsm4arg(bsm1arg("hello1"), 59 // bsm1arg("hello2"), 60 // bsm3arg(bsm1arg("hello4"), bsm2arg(bsm1arg("hello6"), (circular reference to BSM#8)), bsm1arg("hello5")), 61 // bsm1arg("hello3")); 62 // JVMS 5.4.3.6 Dynamically-Computed Constant and Call Site Resolution 63 // Ensure that calls to bsm1arg("hello5") and bsm1arg("hello3") are never resolved due to the nested condy circularity 64 // which results in a StackOverflowError. 65 // 66 ldc Dynamic BSM#8; 67 } 68 public static void main(String args[]) { 69 CondyNestedResolution.test_condy(); 70 } 71 } 72 73 BootstrapMethods: 74 BSM0=invokestatic CondyNestedResolution.bsm1arg("hello1"); 75 BSM1=invokestatic CondyNestedResolution.bsm1arg("hello2"); 76 BSM2=invokestatic CondyNestedResolution.bsm1arg("hello4"); 77 BSM3=invokestatic CondyNestedResolution.bsm1arg("hello6"); 78 BSM4=invokestatic CondyNestedResolution.bsm2arg(BSM#3, BSM#8); 79 BSM5=invokestatic CondyNestedResolution.bsm1arg("hello5"); 80 BSM6=invokestatic CondyNestedResolution.bsm3arg(BSM#2, BSM#4, BSM#5); 81 BSM7=invokestatic CondyNestedResolution.bsm1arg("hello3"); 82 BSM8=invokestatic CondyNestedResolution.bsm4arg(BSM#0, BSM#1, BSM#6, BSM#7); 83 84 Expected output: 85 In bsm1arg 86 hello1 87 In bsm1arg 88 hello2 89 In bsm1arg 90 hello4 91 In bsm1arg 92 hello6 93 Exception in thread "main" java.lang.StackOverflowError 94 at java.base/java.lang.invoke.MethodHandleNatives.copyOutBootstrapArguments(Native Method) 95 */ 96 97 98 class CondyNestedResolution { 99 0xCAFEBABE; 100 0; // minor version 101 55; // version 102 [85] { // Constant Pool 103 ; // first element is empty 104 String #22; // #1 at 0x0A 105 String #61; // #2 at 0x0D 106 String #11; // #3 at 0x10 107 Dynamic 8s #12; // #4 at 0x13 108 Method #51 #10; // #5 at 0x18 109 Method #13 #39; // #6 at 0x1D 110 Field #50 #81; // #7 at 0x22 111 Method #84 #45; // #8 at 0x27 112 Utf8 "java/io/PrintStream"; // #9 at 0x2C 113 NameAndType #71 #47; // #10 at 0x42 114 Utf8 "In bsm1arg"; // #11 at 0x47 115 NameAndType #18 #17; // #12 at 0x54 116 class #9; // #13 at 0x59 117 Utf8 "SourceFile"; // #14 at 0x5C 118 Utf8 "bsm3arg"; // #15 at 0x69 119 Utf8 "CondyNestedResolution.jasm"; // #16 at 0x73 120 Utf8 "Ljava/lang/String;"; // #17 at 0x90 121 Utf8 "name"; // #18 at 0xA5 122 Utf8 "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"; // #19 at 0xAC 123 Utf8 "test_condy"; // #20 at 0x0144 124 NameAndType #15 #19; // #21 at 0x0151 125 Utf8 "In bsm2arg"; // #22 at 0x0156 126 Utf8 "Code"; // #23 at 0x0163 127 Utf8 "([Ljava/lang/String;)V"; // #24 at 0x016A 128 Utf8 "bsm4arg"; // #25 at 0x0183 129 Utf8 "out"; // #26 at 0x018D 130 NameAndType #69 #55; // #27 at 0x0193 131 Utf8 "BootstrapMethods"; // #28 at 0x0198 132 MethodHandle 6b #44; // #29 at 0x01AB 133 Method #84 #63; // #30 at 0x01AF 134 Utf8 "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"; // #31 at 0x01B4 135 Method #84 #27; // #32 at 0x0228 136 MethodHandle 6b #30; // #33 at 0x022D 137 MethodHandle 6b #30; // #34 at 0x0231 138 MethodHandle 6b #30; // #35 at 0x0235 139 MethodHandle 6b #30; // #36 at 0x0239 140 MethodHandle 6b #30; // #37 at 0x023D 141 MethodHandle 6b #30; // #38 at 0x0241 142 NameAndType #40 #41; // #39 at 0x0245 143 Utf8 "println"; // #40 at 0x024A 144 Utf8 "(Ljava/lang/Object;)V"; // #41 at 0x0254 145 Utf8 "java/lang/Object"; // #42 at 0x026C 146 Utf8 "java/lang/System"; // #43 at 0x027F 147 Method #84 #21; // #44 at 0x0292 148 NameAndType #20 #47; // #45 at 0x0297 149 MethodHandle 6b #82; // #46 at 0x029C 150 Utf8 "()V"; // #47 at 0x02A0 151 String #62; // #48 at 0x02A6 152 String #64; // #49 at 0x02A9 153 class #43; // #50 at 0x02AC 154 class #42; // #51 at 0x02AF 155 String #65; // #52 at 0x02B2 156 String #66; // #53 at 0x02B5 157 String #67; // #54 at 0x02B8 158 Utf8 "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"; // #55 at 0x02BB 159 Utf8 "main"; // #56 at 0x0341 160 String #68; // #57 at 0x0348 161 MethodHandle 6b #32; // #58 at 0x034B 162 Utf8 "bsm1arg"; // #59 at 0x034F 163 NameAndType #25 #83; // #60 at 0x0359 164 Utf8 "In bsm4arg"; // #61 at 0x035E 165 Utf8 "hello6"; // #62 at 0x036B 166 NameAndType #59 #31; // #63 at 0x0374 167 Utf8 "hello5"; // #64 at 0x0379 168 Utf8 "hello4"; // #65 at 0x0382 169 Utf8 "hello3"; // #66 at 0x038B 170 Utf8 "hello2"; // #67 at 0x0394 171 Utf8 "hello1"; // #68 at 0x039D 172 Utf8 "bsm2arg"; // #69 at 0x03A6 173 Utf8 "Ljava/io/PrintStream;"; // #70 at 0x03B0 174 Utf8 "<init>"; // #71 at 0x03C8 175 Utf8 "CondyNestedResolution"; // #72 at 0x03D1 176 Dynamic 7s #12; // #73 at 0x03E9 177 Dynamic 6s #12; // #74 at 0x03EE 178 Dynamic 5s #12; // #75 at 0x03F3 179 Dynamic 4s #12; // #76 at 0x03F8 180 Dynamic 3s #12; // #77 at 0x03FD 181 Dynamic 0s #12; // #78 at 0x0402 182 Dynamic 1s #12; // #79 at 0x0407 183 Dynamic 2s #12; // #80 at 0x040C 184 NameAndType #26 #70; // #81 at 0x0411 185 Method #84 #60; // #82 at 0x0416 186 Utf8 "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"; // #83 at 0x041B 187 class #72; // #84 at 0x04C5 188 } // Constant Pool 189 190 0x0000; // access [ ] 191 #84;// this_cpx 192 #51;// super_cpx 193 194 [0] { // Interfaces 195 } // Interfaces 196 197 [0] { // fields 198 } // fields 199 200 [7] { // methods 201 { // Member at 0x04D4 202 0x0001; // access 203 #71; // name_cpx 204 #47; // sig_cpx 205 [1] { // Attributes 206 Attr(#23, 17) { // Code at 0x04DC 207 1; // max_stack 208 1; // max_locals 209 Bytes[5]{ 210 0x2AB70005B1; 211 } 212 [0] { // Traps 213 } // end Traps 214 [0] { // Attributes 215 } // Attributes 216 } // end Code 217 } // Attributes 218 } // Member 219 ; 220 { // Member at 0x04F3 221 0x0009; // access 222 #59; // name_cpx 223 #31; // sig_cpx 224 [1] { // Attributes 225 Attr(#23, 29) { // Code at 0x04FB 226 4; // max_stack 227 4; // max_locals 228 Bytes[17]{ 229 0xB200071203B60006; 230 0xB200072DB600062D; 231 0xB0; 232 } 233 [0] { // Traps 234 } // end Traps 235 [0] { // Attributes 236 } // Attributes 237 } // end Code 238 } // Attributes 239 } // Member 240 ; 241 { // Member at 0x051E 242 0x0009; // access 243 #69; // name_cpx 244 #55; // sig_cpx 245 [1] { // Attributes 246 Attr(#23, 37) { // Code at 0x0526 247 8; // max_stack 248 8; // max_locals 249 Bytes[25]{ 250 0xB200071201B60006; 251 0xB200072DB60006B2; 252 0x00071904B600062D; 253 0xB0; 254 } 255 [0] { // Traps 256 } // end Traps 257 [0] { // Attributes 258 } // Attributes 259 } // end Code 260 } // Attributes 261 } // Member 262 ; 263 { // Member at 0x0551 264 0x0009; // access 265 #15; // name_cpx 266 #19; // sig_cpx 267 [1] { // Attributes 268 Attr(#23, 45) { // Code at 0x0559 269 19; // max_stack 270 19; // max_locals 271 Bytes[33]{ 272 0xB200071202B60006; 273 0xB200072DB60006B2; 274 0x00071904B60006B2; 275 0x00071905B600062D; 276 0xB0; 277 } 278 [0] { // Traps 279 } // end Traps 280 [0] { // Attributes 281 } // Attributes 282 } // end Code 283 } // Attributes 284 } // Member 285 ; 286 { // Member at 0x058C 287 0x0009; // access 288 #25; // name_cpx 289 #83; // sig_cpx 290 [1] { // Attributes 291 Attr(#23, 53) { // Code at 0x0594 292 19; // max_stack 293 19; // max_locals 294 Bytes[41]{ 295 0xB200071202B60006; 296 0xB200072DB60006B2; 297 0x00071904B60006B2; 298 0x00071905B60006B2; 299 0x00071906B600062D; 300 0xB0; 301 } 302 [0] { // Traps 303 } // end Traps 304 [0] { // Attributes 305 } // Attributes 306 } // end Code 307 } // Attributes 308 } // Member 309 ; 310 { // Member at 0x05CF 311 0x0009; // access 312 #20; // name_cpx 313 #47; // sig_cpx 314 [1] { // Attributes 315 Attr(#23, 15) { // Code at 0x05D7 316 12; // max_stack 317 12; // max_locals 318 Bytes[3]{ 319 0x1204B1; 320 } 321 [0] { // Traps 322 } // end Traps 323 [0] { // Attributes 324 } // Attributes 325 } // end Code 326 } // Attributes 327 } // Member 328 ; 329 { // Member at 0x05EC 330 0x0009; // access 331 #56; // name_cpx 332 #24; // sig_cpx 333 [1] { // Attributes 334 Attr(#23, 16) { // Code at 0x05F4 335 2; // max_stack 336 2; // max_locals 337 Bytes[4]{ 338 0xB80008B1; 339 } 340 [0] { // Traps 341 } // end Traps 342 [0] { // Attributes 343 } // Attributes 344 } // end Code 345 } // Attributes 346 } // Member 347 } // methods 348 349 [2] { // Attributes 350 Attr(#14, 2) { // SourceFile at 0x060C 351 #16; 352 } // end SourceFile 353 ; 354 Attr(#28, 68) { // BootstrapMethods at 0x0614 355 [9] { // bootstrap_methods 356 { // bootstrap_method 357 #36; // bootstrap_method_ref 358 [1] { // bootstrap_arguments 359 #57; // at 0x0622 360 } // bootstrap_arguments 361 } // bootstrap_method 362 ; 363 { // bootstrap_method 364 #37; // bootstrap_method_ref 365 [1] { // bootstrap_arguments 366 #54; // at 0x0628 367 } // bootstrap_arguments 368 } // bootstrap_method 369 ; 370 { // bootstrap_method 371 #38; // bootstrap_method_ref 372 [1] { // bootstrap_arguments 373 #52; // at 0x062E 374 } // bootstrap_arguments 375 } // bootstrap_method 376 ; 377 { // bootstrap_method 378 #35; // bootstrap_method_ref 379 [1] { // bootstrap_arguments 380 #48; // at 0x0634 381 } // bootstrap_arguments 382 } // bootstrap_method 383 ; 384 { // bootstrap_method 385 #58; // bootstrap_method_ref 386 [2] { // bootstrap_arguments 387 #77; // at 0x063A 388 #4; // at 0x063C 389 } // bootstrap_arguments 390 } // bootstrap_method 391 ; 392 { // bootstrap_method 393 #34; // bootstrap_method_ref 394 [1] { // bootstrap_arguments 395 #49; // at 0x0642 396 } // bootstrap_arguments 397 } // bootstrap_method 398 ; 399 { // bootstrap_method 400 #29; // bootstrap_method_ref 401 [3] { // bootstrap_arguments 402 #80; // at 0x0648 403 #76; // at 0x064A 404 #75; // at 0x064C 405 } // bootstrap_arguments 406 } // bootstrap_method 407 ; 408 { // bootstrap_method 409 #33; // bootstrap_method_ref 410 [1] { // bootstrap_arguments 411 #53; // at 0x0652 412 } // bootstrap_arguments 413 } // bootstrap_method 414 ; 415 { // bootstrap_method 416 #46; // bootstrap_method_ref 417 [4] { // bootstrap_arguments 418 #78; // at 0x0658 419 #79; // at 0x065A 420 #74; // at 0x065C 421 #73; // at 0x065E 422 } // bootstrap_arguments 423 } // bootstrap_method 424 } 425 } // end BootstrapMethods 426 } // Attributes 427 } // end class CondyNestedResolution