1 /* 2 * Copyright (c) 2011, 2013, 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 26 package java.lang.invoke; 27 28 import java.lang.annotation.*; 29 import java.lang.reflect.Method; 30 import java.util.List; 31 import java.util.Arrays; 32 import java.util.HashMap; 33 34 import sun.invoke.util.Wrapper; 35 import java.lang.reflect.Field; 36 37 import static java.lang.invoke.LambdaForm.BasicType.*; 38 import static java.lang.invoke.MethodHandleStatics.*; 39 import static java.lang.invoke.MethodHandleNatives.Constants.*; 40 41 /** 42 * The symbolic, non-executable form of a method handle's invocation semantics. 43 * It consists of a series of names. 44 * The first N (N=arity) names are parameters, 45 * while any remaining names are temporary values. 46 * Each temporary specifies the application of a function to some arguments. 47 * The functions are method handles, while the arguments are mixes of 48 * constant values and local names. 49 * The result of the lambda is defined as one of the names, often the last one. 50 * <p> 51 * Here is an approximate grammar: 52 * <blockquote><pre>{@code 53 * LambdaForm = "(" ArgName* ")=>{" TempName* Result "}" 54 * ArgName = "a" N ":" T 55 * TempName = "t" N ":" T "=" Function "(" Argument* ");" 56 * Function = ConstantValue 57 * Argument = NameRef | ConstantValue 58 * Result = NameRef | "void" 59 * NameRef = "a" N | "t" N 60 * N = (any whole number) 61 * T = "L" | "I" | "J" | "F" | "D" | "V" 62 * }</pre></blockquote> 63 * Names are numbered consecutively from left to right starting at zero. 64 * (The letters are merely a taste of syntax sugar.) 65 * Thus, the first temporary (if any) is always numbered N (where N=arity). 66 * Every occurrence of a name reference in an argument list must refer to 67 * a name previously defined within the same lambda. 68 * A lambda has a void result if and only if its result index is -1. 69 * If a temporary has the type "V", it cannot be the subject of a NameRef, 70 * even though possesses a number. 71 * Note that all reference types are erased to "L", which stands for {@code Object}. 72 * All subword types (boolean, byte, short, char) are erased to "I" which is {@code int}. 73 * The other types stand for the usual primitive types. 74 * <p> 75 * Function invocation closely follows the static rules of the Java verifier. 76 * Arguments and return values must exactly match when their "Name" types are 77 * considered. 78 * Conversions are allowed only if they do not change the erased type. 79 * <ul> 80 * <li>L = Object: casts are used freely to convert into and out of reference types 81 * <li>I = int: subword types are forcibly narrowed when passed as arguments (see {@code explicitCastArguments}) 82 * <li>J = long: no implicit conversions 83 * <li>F = float: no implicit conversions 84 * <li>D = double: no implicit conversions 85 * <li>V = void: a function result may be void if and only if its Name is of type "V" 86 * </ul> 87 * Although implicit conversions are not allowed, explicit ones can easily be 88 * encoded by using temporary expressions which call type-transformed identity functions. 89 * <p> 90 * Examples: 91 * <blockquote><pre>{@code 92 * (a0:J)=>{ a0 } 93 * == identity(long) 94 * (a0:I)=>{ t1:V = System.out#println(a0); void } 95 * == System.out#println(int) 96 * (a0:L)=>{ t1:V = System.out#println(a0); a0 } 97 * == identity, with printing side-effect 98 * (a0:L, a1:L)=>{ t2:L = BoundMethodHandle#argument(a0); 99 * t3:L = BoundMethodHandle#target(a0); 100 * t4:L = MethodHandle#invoke(t3, t2, a1); t4 } 101 * == general invoker for unary insertArgument combination 102 * (a0:L, a1:L)=>{ t2:L = FilterMethodHandle#filter(a0); 103 * t3:L = MethodHandle#invoke(t2, a1); 104 * t4:L = FilterMethodHandle#target(a0); 105 * t5:L = MethodHandle#invoke(t4, t3); t5 } 106 * == general invoker for unary filterArgument combination 107 * (a0:L, a1:L)=>{ ...(same as previous example)... 108 * t5:L = MethodHandle#invoke(t4, t3, a1); t5 } 109 * == general invoker for unary/unary foldArgument combination 110 * (a0:L, a1:I)=>{ t2:I = identity(long).asType((int)->long)(a1); t2 } 111 * == invoker for identity method handle which performs i2l 112 * (a0:L, a1:L)=>{ t2:L = BoundMethodHandle#argument(a0); 113 * t3:L = Class#cast(t2,a1); t3 } 114 * == invoker for identity method handle which performs cast 115 * }</pre></blockquote> 116 * <p> 117 * @author John Rose, JSR 292 EG 118 */ 119 class LambdaForm { 120 final int arity; 121 final int result; 122 final boolean forceInline; 123 final MethodHandle customized; 124 @Stable final Name[] names; 125 final String debugName; 126 MemberName vmentry; // low-level behavior, or null if not yet prepared 127 private boolean isCompiled; 128 129 volatile Object transformCache; // managed by LambdaFormEditor 130 131 public static final int VOID_RESULT = -1, LAST_RESULT = -2; 132 133 enum BasicType { 134 L_TYPE('L', Object.class, Wrapper.OBJECT), // all reference types 135 I_TYPE('I', int.class, Wrapper.INT), 136 J_TYPE('J', long.class, Wrapper.LONG), 137 F_TYPE('F', float.class, Wrapper.FLOAT), 138 D_TYPE('D', double.class, Wrapper.DOUBLE), // all primitive types 139 V_TYPE('V', void.class, Wrapper.VOID); // not valid in all contexts 140 141 static final BasicType[] ALL_TYPES = BasicType.values(); 142 static final BasicType[] ARG_TYPES = Arrays.copyOf(ALL_TYPES, ALL_TYPES.length-1); 143 144 static final int ARG_TYPE_LIMIT = ARG_TYPES.length; 145 static final int TYPE_LIMIT = ALL_TYPES.length; 146 147 private final char btChar; 148 private final Class<?> btClass; 149 private final Wrapper btWrapper; 150 151 private BasicType(char btChar, Class<?> btClass, Wrapper wrapper) { 152 this.btChar = btChar; 153 this.btClass = btClass; 154 this.btWrapper = wrapper; 155 } 156 157 char basicTypeChar() { 158 return btChar; 159 } 160 Class<?> basicTypeClass() { 161 return btClass; 162 } 163 Wrapper basicTypeWrapper() { 164 return btWrapper; 165 } 166 int basicTypeSlots() { 167 return btWrapper.stackSlots(); 168 } 169 170 static BasicType basicType(byte type) { 171 return ALL_TYPES[type]; 172 } 173 static BasicType basicType(char type) { 174 switch (type) { 175 case 'L': return L_TYPE; 176 case 'I': return I_TYPE; 177 case 'J': return J_TYPE; 178 case 'F': return F_TYPE; 179 case 'D': return D_TYPE; 180 case 'V': return V_TYPE; 181 // all subword types are represented as ints 182 case 'Z': 183 case 'B': 184 case 'S': 185 case 'C': 186 return I_TYPE; 187 default: 188 throw newInternalError("Unknown type char: '"+type+"'"); 189 } 190 } 191 static BasicType basicType(Wrapper type) { 192 char c = type.basicTypeChar(); 193 return basicType(c); 194 } 195 static BasicType basicType(Class<?> type) { 196 if (!type.isPrimitive()) return L_TYPE; 197 return basicType(Wrapper.forPrimitiveType(type)); 198 } 199 200 static char basicTypeChar(Class<?> type) { 201 return basicType(type).btChar; 202 } 203 static BasicType[] basicTypes(List<Class<?>> types) { 204 BasicType[] btypes = new BasicType[types.size()]; 205 for (int i = 0; i < btypes.length; i++) { 206 btypes[i] = basicType(types.get(i)); 207 } 208 return btypes; 209 } 210 static BasicType[] basicTypes(String types) { 211 BasicType[] btypes = new BasicType[types.length()]; 212 for (int i = 0; i < btypes.length; i++) { 213 btypes[i] = basicType(types.charAt(i)); 214 } 215 return btypes; 216 } 217 static byte[] basicTypesOrd(BasicType[] btypes) { 218 byte[] ords = new byte[btypes.length]; 219 for (int i = 0; i < btypes.length; i++) { 220 ords[i] = (byte)btypes[i].ordinal(); 221 } 222 return ords; 223 } 224 static boolean isBasicTypeChar(char c) { 225 return "LIJFDV".indexOf(c) >= 0; 226 } 227 static boolean isArgBasicTypeChar(char c) { 228 return "LIJFD".indexOf(c) >= 0; 229 } 230 231 static { assert(checkBasicType()); } 232 private static boolean checkBasicType() { 233 for (int i = 0; i < ARG_TYPE_LIMIT; i++) { 234 assert ARG_TYPES[i].ordinal() == i; 235 assert ARG_TYPES[i] == ALL_TYPES[i]; 236 } 237 for (int i = 0; i < TYPE_LIMIT; i++) { 238 assert ALL_TYPES[i].ordinal() == i; 239 } 240 assert ALL_TYPES[TYPE_LIMIT - 1] == V_TYPE; 241 assert !Arrays.asList(ARG_TYPES).contains(V_TYPE); 242 return true; 243 } 244 } 245 246 LambdaForm(String debugName, 247 int arity, Name[] names, int result) { 248 this(debugName, arity, names, result, /*forceInline=*/true, /*customized=*/null); 249 } 250 LambdaForm(String debugName, 251 int arity, Name[] names, int result, boolean forceInline, MethodHandle customized) { 252 assert(namesOK(arity, names)); 253 this.arity = arity; 254 this.result = fixResult(result, names); 255 this.names = names.clone(); 256 this.debugName = fixDebugName(debugName); 257 this.forceInline = forceInline; 258 this.customized = customized; 259 int maxOutArity = normalize(); 260 if (maxOutArity > MethodType.MAX_MH_INVOKER_ARITY) { 261 // Cannot use LF interpreter on very high arity expressions. 262 assert(maxOutArity <= MethodType.MAX_JVM_ARITY); 263 compileToBytecode(); 264 } 265 } 266 LambdaForm(String debugName, 267 int arity, Name[] names) { 268 this(debugName, arity, names, LAST_RESULT, /*forceInline=*/true, /*customized=*/null); 269 } 270 LambdaForm(String debugName, 271 int arity, Name[] names, boolean forceInline) { 272 this(debugName, arity, names, LAST_RESULT, forceInline, /*customized=*/null); 273 } 274 LambdaForm(String debugName, 275 Name[] formals, Name[] temps, Name result) { 276 this(debugName, 277 formals.length, buildNames(formals, temps, result), LAST_RESULT, /*forceInline=*/true, /*customized=*/null); 278 } 279 LambdaForm(String debugName, 280 Name[] formals, Name[] temps, Name result, boolean forceInline) { 281 this(debugName, 282 formals.length, buildNames(formals, temps, result), LAST_RESULT, forceInline, /*customized=*/null); 283 } 284 285 private static Name[] buildNames(Name[] formals, Name[] temps, Name result) { 286 int arity = formals.length; 287 int length = arity + temps.length + (result == null ? 0 : 1); 288 Name[] names = Arrays.copyOf(formals, length); 289 System.arraycopy(temps, 0, names, arity, temps.length); 290 if (result != null) 291 names[length - 1] = result; 292 return names; 293 } 294 295 private LambdaForm(String sig) { 296 // Make a blank lambda form, which returns a constant zero or null. 297 // It is used as a template for managing the invocation of similar forms that are non-empty. 298 // Called only from getPreparedForm. 299 assert(isValidSignature(sig)); 300 this.arity = signatureArity(sig); 301 this.result = (signatureReturn(sig) == V_TYPE ? -1 : arity); 302 this.names = buildEmptyNames(arity, sig); 303 this.debugName = "LF.zero"; 304 this.forceInline = true; 305 this.customized = null; 306 assert(nameRefsAreLegal()); 307 assert(isEmpty()); 308 assert(sig.equals(basicTypeSignature())) : sig + " != " + basicTypeSignature(); 309 } 310 311 private static Name[] buildEmptyNames(int arity, String basicTypeSignature) { 312 assert(isValidSignature(basicTypeSignature)); 313 int resultPos = arity + 1; // skip '_' 314 if (arity < 0 || basicTypeSignature.length() != resultPos+1) 315 throw new IllegalArgumentException("bad arity for "+basicTypeSignature); 316 int numRes = (basicType(basicTypeSignature.charAt(resultPos)) == V_TYPE ? 0 : 1); 317 Name[] names = arguments(numRes, basicTypeSignature.substring(0, arity)); 318 for (int i = 0; i < numRes; i++) { 319 Name zero = new Name(constantZero(basicType(basicTypeSignature.charAt(resultPos + i)))); 320 names[arity + i] = zero.newIndex(arity + i); 321 } 322 return names; 323 } 324 325 private static int fixResult(int result, Name[] names) { 326 if (result == LAST_RESULT) 327 result = names.length - 1; // might still be void 328 if (result >= 0 && names[result].type == V_TYPE) 329 result = VOID_RESULT; 330 return result; 331 } 332 333 private static String fixDebugName(String debugName) { 334 if (DEBUG_NAME_COUNTERS != null) { 335 int under = debugName.indexOf('_'); 336 int length = debugName.length(); 337 if (under < 0) under = length; 338 String debugNameStem = debugName.substring(0, under); 339 Integer ctr; 340 synchronized (DEBUG_NAME_COUNTERS) { 341 ctr = DEBUG_NAME_COUNTERS.get(debugNameStem); 342 if (ctr == null) ctr = 0; 343 DEBUG_NAME_COUNTERS.put(debugNameStem, ctr+1); 344 } 345 StringBuilder buf = new StringBuilder(debugNameStem); 346 buf.append('_'); 347 int leadingZero = buf.length(); 348 buf.append((int) ctr); 349 for (int i = buf.length() - leadingZero; i < 3; i++) 350 buf.insert(leadingZero, '0'); 351 if (under < length) { 352 ++under; // skip "_" 353 while (under < length && Character.isDigit(debugName.charAt(under))) { 354 ++under; 355 } 356 if (under < length && debugName.charAt(under) == '_') ++under; 357 if (under < length) 358 buf.append('_').append(debugName, under, length); 359 } 360 return buf.toString(); 361 } 362 return debugName; 363 } 364 365 private static boolean namesOK(int arity, Name[] names) { 366 for (int i = 0; i < names.length; i++) { 367 Name n = names[i]; 368 assert(n != null) : "n is null"; 369 if (i < arity) 370 assert( n.isParam()) : n + " is not param at " + i; 371 else 372 assert(!n.isParam()) : n + " is param at " + i; 373 } 374 return true; 375 } 376 377 /** Renumber and/or replace params so that they are interned and canonically numbered. 378 * @return maximum argument list length among the names (since we have to pass over them anyway) 379 */ 380 private int normalize() { 381 Name[] oldNames = null; 382 int maxOutArity = 0; 383 int changesStart = 0; 384 for (int i = 0; i < names.length; i++) { 385 Name n = names[i]; 386 if (!n.initIndex(i)) { 387 if (oldNames == null) { 388 oldNames = names.clone(); 389 changesStart = i; 390 } 391 names[i] = n.cloneWithIndex(i); 392 } 393 if (n.arguments != null && maxOutArity < n.arguments.length) 394 maxOutArity = n.arguments.length; 395 } 396 if (oldNames != null) { 397 int startFixing = arity; 398 if (startFixing <= changesStart) 399 startFixing = changesStart+1; 400 for (int i = startFixing; i < names.length; i++) { 401 Name fixed = names[i].replaceNames(oldNames, names, changesStart, i); 402 names[i] = fixed.newIndex(i); 403 } 404 } 405 assert(nameRefsAreLegal()); 406 int maxInterned = Math.min(arity, INTERNED_ARGUMENT_LIMIT); 407 boolean needIntern = false; 408 for (int i = 0; i < maxInterned; i++) { 409 Name n = names[i], n2 = internArgument(n); 410 if (n != n2) { 411 names[i] = n2; 412 needIntern = true; 413 } 414 } 415 if (needIntern) { 416 for (int i = arity; i < names.length; i++) { 417 names[i].internArguments(); 418 } 419 } 420 assert(nameRefsAreLegal()); 421 return maxOutArity; 422 } 423 424 /** 425 * Check that all embedded Name references are localizable to this lambda, 426 * and are properly ordered after their corresponding definitions. 427 * <p> 428 * Note that a Name can be local to multiple lambdas, as long as 429 * it possesses the same index in each use site. 430 * This allows Name references to be freely reused to construct 431 * fresh lambdas, without confusion. 432 */ 433 boolean nameRefsAreLegal() { 434 assert(arity >= 0 && arity <= names.length); 435 assert(result >= -1 && result < names.length); 436 // Do all names possess an index consistent with their local definition order? 437 for (int i = 0; i < arity; i++) { 438 Name n = names[i]; 439 assert(n.index() == i) : Arrays.asList(n.index(), i); 440 assert(n.isParam()); 441 } 442 // Also, do all local name references 443 for (int i = arity; i < names.length; i++) { 444 Name n = names[i]; 445 assert(n.index() == i); 446 for (Object arg : n.arguments) { 447 if (arg instanceof Name) { 448 Name n2 = (Name) arg; 449 int i2 = n2.index; 450 assert(0 <= i2 && i2 < names.length) : n.debugString() + ": 0 <= i2 && i2 < names.length: 0 <= " + i2 + " < " + names.length; 451 assert(names[i2] == n2) : Arrays.asList("-1-", i, "-2-", n.debugString(), "-3-", i2, "-4-", n2.debugString(), "-5-", names[i2].debugString(), "-6-", this); 452 assert(i2 < i); // ref must come after def! 453 } 454 } 455 } 456 return true; 457 } 458 459 /** Invoke this form on the given arguments. */ 460 // final Object invoke(Object... args) throws Throwable { 461 // // NYI: fit this into the fast path? 462 // return interpretWithArguments(args); 463 // } 464 465 /** Report the return type. */ 466 BasicType returnType() { 467 if (result < 0) return V_TYPE; 468 Name n = names[result]; 469 return n.type; 470 } 471 472 /** Report the N-th argument type. */ 473 BasicType parameterType(int n) { 474 return parameter(n).type; 475 } 476 477 /** Report the N-th argument name. */ 478 Name parameter(int n) { 479 assert(n < arity); 480 Name param = names[n]; 481 assert(param.isParam()); 482 return param; 483 } 484 485 /** Report the N-th argument type constraint. */ 486 Object parameterConstraint(int n) { 487 return parameter(n).constraint; 488 } 489 490 /** Report the arity. */ 491 int arity() { 492 return arity; 493 } 494 495 /** Report the number of expressions (non-parameter names). */ 496 int expressionCount() { 497 return names.length - arity; 498 } 499 500 /** Return the method type corresponding to my basic type signature. */ 501 MethodType methodType() { 502 return signatureType(basicTypeSignature()); 503 } 504 /** Return ABC_Z, where the ABC are parameter type characters, and Z is the return type character. */ 505 final String basicTypeSignature() { 506 StringBuilder buf = new StringBuilder(arity() + 3); 507 for (int i = 0, a = arity(); i < a; i++) 508 buf.append(parameterType(i).basicTypeChar()); 509 return buf.append('_').append(returnType().basicTypeChar()).toString(); 510 } 511 static int signatureArity(String sig) { 512 assert(isValidSignature(sig)); 513 return sig.indexOf('_'); 514 } 515 static BasicType signatureReturn(String sig) { 516 return basicType(sig.charAt(signatureArity(sig) + 1)); 517 } 518 static boolean isValidSignature(String sig) { 519 int arity = sig.indexOf('_'); 520 if (arity < 0) return false; // must be of the form *_* 521 int siglen = sig.length(); 522 if (siglen != arity + 2) return false; // *_X 523 for (int i = 0; i < siglen; i++) { 524 if (i == arity) continue; // skip '_' 525 char c = sig.charAt(i); 526 if (c == 'V') 527 return (i == siglen - 1 && arity == siglen - 2); 528 if (!isArgBasicTypeChar(c)) return false; // must be [LIJFD] 529 } 530 return true; // [LIJFD]*_[LIJFDV] 531 } 532 static MethodType signatureType(String sig) { 533 Class<?>[] ptypes = new Class<?>[signatureArity(sig)]; 534 for (int i = 0; i < ptypes.length; i++) 535 ptypes[i] = basicType(sig.charAt(i)).btClass; 536 Class<?> rtype = signatureReturn(sig).btClass; 537 return MethodType.methodType(rtype, ptypes); 538 } 539 540 /* 541 * Code generation issues: 542 * 543 * Compiled LFs should be reusable in general. 544 * The biggest issue is how to decide when to pull a name into 545 * the bytecode, versus loading a reified form from the MH data. 546 * 547 * For example, an asType wrapper may require execution of a cast 548 * after a call to a MH. The target type of the cast can be placed 549 * as a constant in the LF itself. This will force the cast type 550 * to be compiled into the bytecodes and native code for the MH. 551 * Or, the target type of the cast can be erased in the LF, and 552 * loaded from the MH data. (Later on, if the MH as a whole is 553 * inlined, the data will flow into the inlined instance of the LF, 554 * as a constant, and the end result will be an optimal cast.) 555 * 556 * This erasure of cast types can be done with any use of 557 * reference types. It can also be done with whole method 558 * handles. Erasing a method handle might leave behind 559 * LF code that executes correctly for any MH of a given 560 * type, and load the required MH from the enclosing MH's data. 561 * Or, the erasure might even erase the expected MT. 562 * 563 * Also, for direct MHs, the MemberName of the target 564 * could be erased, and loaded from the containing direct MH. 565 * As a simple case, a LF for all int-valued non-static 566 * field getters would perform a cast on its input argument 567 * (to non-constant base type derived from the MemberName) 568 * and load an integer value from the input object 569 * (at a non-constant offset also derived from the MemberName). 570 * Such MN-erased LFs would be inlinable back to optimized 571 * code, whenever a constant enclosing DMH is available 572 * to supply a constant MN from its data. 573 * 574 * The main problem here is to keep LFs reasonably generic, 575 * while ensuring that hot spots will inline good instances. 576 * "Reasonably generic" means that we don't end up with 577 * repeated versions of bytecode or machine code that do 578 * not differ in their optimized form. Repeated versions 579 * of machine would have the undesirable overheads of 580 * (a) redundant compilation work and (b) extra I$ pressure. 581 * To control repeated versions, we need to be ready to 582 * erase details from LFs and move them into MH data, 583 * whevener those details are not relevant to significant 584 * optimization. "Significant" means optimization of 585 * code that is actually hot. 586 * 587 * Achieving this may require dynamic splitting of MHs, by replacing 588 * a generic LF with a more specialized one, on the same MH, 589 * if (a) the MH is frequently executed and (b) the MH cannot 590 * be inlined into a containing caller, such as an invokedynamic. 591 * 592 * Compiled LFs that are no longer used should be GC-able. 593 * If they contain non-BCP references, they should be properly 594 * interlinked with the class loader(s) that their embedded types 595 * depend on. This probably means that reusable compiled LFs 596 * will be tabulated (indexed) on relevant class loaders, 597 * or else that the tables that cache them will have weak links. 598 */ 599 600 /** 601 * Make this LF directly executable, as part of a MethodHandle. 602 * Invariant: Every MH which is invoked must prepare its LF 603 * before invocation. 604 * (In principle, the JVM could do this very lazily, 605 * as a sort of pre-invocation linkage step.) 606 */ 607 public void prepare() { 608 if (COMPILE_THRESHOLD == 0) { 609 compileToBytecode(); 610 } 611 if (this.vmentry != null) { 612 // already prepared (e.g., a primitive DMH invoker form) 613 return; 614 } 615 LambdaForm prep = getPreparedForm(basicTypeSignature()); 616 this.vmentry = prep.vmentry; 617 // TO DO: Maybe add invokeGeneric, invokeWithArguments 618 } 619 620 /** Generate optimizable bytecode for this form. */ 621 MemberName compileToBytecode() { 622 MethodType invokerType = methodType(); 623 assert(vmentry == null || vmentry.getMethodType().basicType().equals(invokerType)); 624 if (vmentry != null && isCompiled) { 625 return vmentry; // already compiled somehow 626 } 627 try { 628 vmentry = InvokerBytecodeGenerator.generateCustomizedCode(this, invokerType); 629 if (TRACE_INTERPRETER) 630 traceInterpreter("compileToBytecode", this); 631 isCompiled = true; 632 return vmentry; 633 } catch (Error | Exception ex) { 634 throw newInternalError(this.toString(), ex); 635 } 636 } 637 638 private static void computeInitialPreparedForms() { 639 // Find all predefined invokers and associate them with canonical empty lambda forms. 640 for (MemberName m : MemberName.getFactory().getMethods(LambdaForm.class, false, null, null, null)) { 641 if (!m.isStatic() || !m.isPackage()) continue; 642 MethodType mt = m.getMethodType(); 643 if (mt.parameterCount() > 0 && 644 mt.parameterType(0) == MethodHandle.class && 645 m.getName().startsWith("interpret_")) { 646 String sig = basicTypeSignature(mt); 647 assert(m.getName().equals("interpret" + sig.substring(sig.indexOf('_')))); 648 LambdaForm form = new LambdaForm(sig); 649 form.vmentry = m; 650 form = mt.form().setCachedLambdaForm(MethodTypeForm.LF_INTERPRET, form); 651 } 652 } 653 } 654 655 // Set this false to disable use of the interpret_L methods defined in this file. 656 private static final boolean USE_PREDEFINED_INTERPRET_METHODS = true; 657 658 // The following are predefined exact invokers. The system must build 659 // a separate invoker for each distinct signature. 660 static Object interpret_L(MethodHandle mh) throws Throwable { 661 Object[] av = {mh}; 662 String sig = null; 663 assert(argumentTypesMatch(sig = "L_L", av)); 664 Object res = mh.form.interpretWithArguments(av); 665 assert(returnTypesMatch(sig, av, res)); 666 return res; 667 } 668 static Object interpret_L(MethodHandle mh, Object x1) throws Throwable { 669 Object[] av = {mh, x1}; 670 String sig = null; 671 assert(argumentTypesMatch(sig = "LL_L", av)); 672 Object res = mh.form.interpretWithArguments(av); 673 assert(returnTypesMatch(sig, av, res)); 674 return res; 675 } 676 static Object interpret_L(MethodHandle mh, Object x1, Object x2) throws Throwable { 677 Object[] av = {mh, x1, x2}; 678 String sig = null; 679 assert(argumentTypesMatch(sig = "LLL_L", av)); 680 Object res = mh.form.interpretWithArguments(av); 681 assert(returnTypesMatch(sig, av, res)); 682 return res; 683 } 684 private static LambdaForm getPreparedForm(String sig) { 685 MethodType mtype = signatureType(sig); 686 LambdaForm prep = mtype.form().cachedLambdaForm(MethodTypeForm.LF_INTERPRET); 687 if (prep != null) return prep; 688 assert(isValidSignature(sig)); 689 prep = new LambdaForm(sig); 690 prep.vmentry = InvokerBytecodeGenerator.generateLambdaFormInterpreterEntryPoint(sig); 691 return mtype.form().setCachedLambdaForm(MethodTypeForm.LF_INTERPRET, prep); 692 } 693 694 // The next few routines are called only from assert expressions 695 // They verify that the built-in invokers process the correct raw data types. 696 private static boolean argumentTypesMatch(String sig, Object[] av) { 697 int arity = signatureArity(sig); 698 assert(av.length == arity) : "av.length == arity: av.length=" + av.length + ", arity=" + arity; 699 assert(av[0] instanceof MethodHandle) : "av[0] not instace of MethodHandle: " + av[0]; 700 MethodHandle mh = (MethodHandle) av[0]; 701 MethodType mt = mh.type(); 702 assert(mt.parameterCount() == arity-1); 703 for (int i = 0; i < av.length; i++) { 704 Class<?> pt = (i == 0 ? MethodHandle.class : mt.parameterType(i-1)); 705 assert(valueMatches(basicType(sig.charAt(i)), pt, av[i])); 706 } 707 return true; 708 } 709 private static boolean valueMatches(BasicType tc, Class<?> type, Object x) { 710 // The following line is needed because (...)void method handles can use non-void invokers 711 if (type == void.class) tc = V_TYPE; // can drop any kind of value 712 assert tc == basicType(type) : tc + " == basicType(" + type + ")=" + basicType(type); 713 switch (tc) { 714 case I_TYPE: assert checkInt(type, x) : "checkInt(" + type + "," + x +")"; break; 715 case J_TYPE: assert x instanceof Long : "instanceof Long: " + x; break; 716 case F_TYPE: assert x instanceof Float : "instanceof Float: " + x; break; 717 case D_TYPE: assert x instanceof Double : "instanceof Double: " + x; break; 718 case L_TYPE: assert checkRef(type, x) : "checkRef(" + type + "," + x + ")"; break; 719 case V_TYPE: break; // allow anything here; will be dropped 720 default: assert(false); 721 } 722 return true; 723 } 724 private static boolean returnTypesMatch(String sig, Object[] av, Object res) { 725 MethodHandle mh = (MethodHandle) av[0]; 726 return valueMatches(signatureReturn(sig), mh.type().returnType(), res); 727 } 728 private static boolean checkInt(Class<?> type, Object x) { 729 assert(x instanceof Integer); 730 if (type == int.class) return true; 731 Wrapper w = Wrapper.forBasicType(type); 732 assert(w.isSubwordOrInt()); 733 Object x1 = Wrapper.INT.wrap(w.wrap(x)); 734 return x.equals(x1); 735 } 736 private static boolean checkRef(Class<?> type, Object x) { 737 assert(!type.isPrimitive()); 738 if (x == null) return true; 739 if (type.isInterface()) return true; 740 return type.isInstance(x); 741 } 742 743 /** If the invocation count hits the threshold we spin bytecodes and call that subsequently. */ 744 private static final int COMPILE_THRESHOLD; 745 static { 746 COMPILE_THRESHOLD = Math.max(-1, MethodHandleStatics.COMPILE_THRESHOLD); 747 } 748 private int invocationCounter = 0; 749 750 @Hidden 751 @DontInline 752 /** Interpretively invoke this form on the given arguments. */ 753 Object interpretWithArguments(Object... argumentValues) throws Throwable { 754 if (TRACE_INTERPRETER) 755 return interpretWithArgumentsTracing(argumentValues); 756 checkInvocationCounter(); 757 assert(arityCheck(argumentValues)); 758 Object[] values = Arrays.copyOf(argumentValues, names.length); 759 for (int i = argumentValues.length; i < values.length; i++) { 760 values[i] = interpretName(names[i], values); 761 } 762 Object rv = (result < 0) ? null : values[result]; 763 assert(resultCheck(argumentValues, rv)); 764 return rv; 765 } 766 767 @Hidden 768 @DontInline 769 /** Evaluate a single Name within this form, applying its function to its arguments. */ 770 Object interpretName(Name name, Object[] values) throws Throwable { 771 if (TRACE_INTERPRETER) 772 traceInterpreter("| interpretName", name.debugString(), (Object[]) null); 773 Object[] arguments = Arrays.copyOf(name.arguments, name.arguments.length, Object[].class); 774 for (int i = 0; i < arguments.length; i++) { 775 Object a = arguments[i]; 776 if (a instanceof Name) { 777 int i2 = ((Name)a).index(); 778 assert(names[i2] == a); 779 a = values[i2]; 780 arguments[i] = a; 781 } 782 } 783 return name.function.invokeWithArguments(arguments); 784 } 785 786 private void checkInvocationCounter() { 787 if (COMPILE_THRESHOLD != 0 && 788 invocationCounter < COMPILE_THRESHOLD) { 789 invocationCounter++; // benign race 790 if (invocationCounter >= COMPILE_THRESHOLD) { 791 // Replace vmentry with a bytecode version of this LF. 792 compileToBytecode(); 793 } 794 } 795 } 796 Object interpretWithArgumentsTracing(Object... argumentValues) throws Throwable { 797 traceInterpreter("[ interpretWithArguments", this, argumentValues); 798 if (invocationCounter < COMPILE_THRESHOLD) { 799 int ctr = invocationCounter++; // benign race 800 traceInterpreter("| invocationCounter", ctr); 801 if (invocationCounter >= COMPILE_THRESHOLD) { 802 compileToBytecode(); 803 } 804 } 805 Object rval; 806 try { 807 assert(arityCheck(argumentValues)); 808 Object[] values = Arrays.copyOf(argumentValues, names.length); 809 for (int i = argumentValues.length; i < values.length; i++) { 810 values[i] = interpretName(names[i], values); 811 } 812 rval = (result < 0) ? null : values[result]; 813 } catch (Throwable ex) { 814 traceInterpreter("] throw =>", ex); 815 throw ex; 816 } 817 traceInterpreter("] return =>", rval); 818 return rval; 819 } 820 821 static void traceInterpreter(String event, Object obj, Object... args) { 822 if (TRACE_INTERPRETER) { 823 System.out.println("LFI: "+event+" "+(obj != null ? obj : "")+(args != null && args.length != 0 ? Arrays.asList(args) : "")); 824 } 825 } 826 static void traceInterpreter(String event, Object obj) { 827 traceInterpreter(event, obj, (Object[])null); 828 } 829 private boolean arityCheck(Object[] argumentValues) { 830 assert(argumentValues.length == arity) : arity+"!="+Arrays.asList(argumentValues)+".length"; 831 // also check that the leading (receiver) argument is somehow bound to this LF: 832 assert(argumentValues[0] instanceof MethodHandle) : "not MH: " + argumentValues[0]; 833 MethodHandle mh = (MethodHandle) argumentValues[0]; 834 assert(mh.internalForm() == this); 835 // note: argument #0 could also be an interface wrapper, in the future 836 argumentTypesMatch(basicTypeSignature(), argumentValues); 837 return true; 838 } 839 private boolean resultCheck(Object[] argumentValues, Object result) { 840 MethodHandle mh = (MethodHandle) argumentValues[0]; 841 MethodType mt = mh.type(); 842 assert(valueMatches(returnType(), mt.returnType(), result)); 843 return true; 844 } 845 846 private boolean isEmpty() { 847 if (result < 0) 848 return (names.length == arity); 849 else if (result == arity && names.length == arity + 1) 850 return names[arity].isConstantZero(); 851 else 852 return false; 853 } 854 855 public String toString() { 856 StringBuilder buf = new StringBuilder(debugName+"=Lambda("); 857 for (int i = 0; i < names.length; i++) { 858 if (i == arity) buf.append(")=>{"); 859 Name n = names[i]; 860 if (i >= arity) buf.append("\n "); 861 buf.append(n.paramString()); 862 if (i < arity) { 863 if (i+1 < arity) buf.append(","); 864 continue; 865 } 866 buf.append("=").append(n.exprString()); 867 buf.append(";"); 868 } 869 if (arity == names.length) buf.append(")=>{"); 870 buf.append(result < 0 ? "void" : names[result]).append("}"); 871 if (TRACE_INTERPRETER) { 872 // Extra verbosity: 873 buf.append(":").append(basicTypeSignature()); 874 buf.append("/").append(vmentry); 875 } 876 return buf.toString(); 877 } 878 879 @Override 880 public boolean equals(Object obj) { 881 return obj instanceof LambdaForm && equals((LambdaForm)obj); 882 } 883 public boolean equals(LambdaForm that) { 884 if (this.result != that.result) return false; 885 return Arrays.equals(this.names, that.names); 886 } 887 public int hashCode() { 888 return result + 31 * Arrays.hashCode(names); 889 } 890 LambdaFormEditor editor() { 891 return LambdaFormEditor.lambdaFormEditor(this); 892 } 893 894 boolean contains(Name name) { 895 int pos = name.index(); 896 if (pos >= 0) { 897 return pos < names.length && name.equals(names[pos]); 898 } 899 for (int i = arity; i < names.length; i++) { 900 if (name.equals(names[i])) 901 return true; 902 } 903 return false; 904 } 905 906 LambdaForm addArguments(int pos, BasicType... types) { 907 // names array has MH in slot 0; skip it. 908 int argpos = pos + 1; 909 assert(argpos <= arity); 910 int length = names.length; 911 int inTypes = types.length; 912 Name[] names2 = Arrays.copyOf(names, length + inTypes); 913 int arity2 = arity + inTypes; 914 int result2 = result; 915 if (result2 >= argpos) 916 result2 += inTypes; 917 // Note: The LF constructor will rename names2[argpos...]. 918 // Make space for new arguments (shift temporaries). 919 System.arraycopy(names, argpos, names2, argpos + inTypes, length - argpos); 920 for (int i = 0; i < inTypes; i++) { 921 names2[argpos + i] = new Name(types[i]); 922 } 923 return new LambdaForm(debugName, arity2, names2, result2); 924 } 925 926 LambdaForm addArguments(int pos, List<Class<?>> types) { 927 return addArguments(pos, basicTypes(types)); 928 } 929 930 LambdaForm permuteArguments(int skip, int[] reorder, BasicType[] types) { 931 // Note: When inArg = reorder[outArg], outArg is fed by a copy of inArg. 932 // The types are the types of the new (incoming) arguments. 933 int length = names.length; 934 int inTypes = types.length; 935 int outArgs = reorder.length; 936 assert(skip+outArgs == arity); 937 assert(permutedTypesMatch(reorder, types, names, skip)); 938 int pos = 0; 939 // skip trivial first part of reordering: 940 while (pos < outArgs && reorder[pos] == pos) pos += 1; 941 Name[] names2 = new Name[length - outArgs + inTypes]; 942 System.arraycopy(names, 0, names2, 0, skip+pos); 943 // copy the body: 944 int bodyLength = length - arity; 945 System.arraycopy(names, skip+outArgs, names2, skip+inTypes, bodyLength); 946 int arity2 = names2.length - bodyLength; 947 int result2 = result; 948 if (result2 >= 0) { 949 if (result2 < skip+outArgs) { 950 // return the corresponding inArg 951 result2 = reorder[result2-skip]; 952 } else { 953 result2 = result2 - outArgs + inTypes; 954 } 955 } 956 // rework names in the body: 957 for (int j = pos; j < outArgs; j++) { 958 Name n = names[skip+j]; 959 int i = reorder[j]; 960 // replace names[skip+j] by names2[skip+i] 961 Name n2 = names2[skip+i]; 962 if (n2 == null) 963 names2[skip+i] = n2 = new Name(types[i]); 964 else 965 assert(n2.type == types[i]); 966 for (int k = arity2; k < names2.length; k++) { 967 names2[k] = names2[k].replaceName(n, n2); 968 } 969 } 970 // some names are unused, but must be filled in 971 for (int i = skip+pos; i < arity2; i++) { 972 if (names2[i] == null) 973 names2[i] = argument(i, types[i - skip]); 974 } 975 for (int j = arity; j < names.length; j++) { 976 int i = j - arity + arity2; 977 // replace names2[i] by names[j] 978 Name n = names[j]; 979 Name n2 = names2[i]; 980 if (n != n2) { 981 for (int k = i+1; k < names2.length; k++) { 982 names2[k] = names2[k].replaceName(n, n2); 983 } 984 } 985 } 986 return new LambdaForm(debugName, arity2, names2, result2); 987 } 988 989 static boolean permutedTypesMatch(int[] reorder, BasicType[] types, Name[] names, int skip) { 990 int inTypes = types.length; 991 int outArgs = reorder.length; 992 for (int i = 0; i < outArgs; i++) { 993 assert(names[skip+i].isParam()); 994 assert(names[skip+i].type == types[reorder[i]]); 995 } 996 return true; 997 } 998 999 static class NamedFunction { 1000 final MemberName member; 1001 @Stable MethodHandle resolvedHandle; 1002 @Stable MethodHandle invoker; 1003 1004 NamedFunction(MethodHandle resolvedHandle) { 1005 this(resolvedHandle.internalMemberName(), resolvedHandle); 1006 } 1007 NamedFunction(MemberName member, MethodHandle resolvedHandle) { 1008 this.member = member; 1009 this.resolvedHandle = resolvedHandle; 1010 // The following assert is almost always correct, but will fail for corner cases, such as PrivateInvokeTest. 1011 //assert(!isInvokeBasic()); 1012 } 1013 NamedFunction(MethodType basicInvokerType) { 1014 assert(basicInvokerType == basicInvokerType.basicType()) : basicInvokerType; 1015 if (basicInvokerType.parameterSlotCount() < MethodType.MAX_MH_INVOKER_ARITY) { 1016 this.resolvedHandle = basicInvokerType.invokers().basicInvoker(); 1017 this.member = resolvedHandle.internalMemberName(); 1018 } else { 1019 // necessary to pass BigArityTest 1020 this.member = Invokers.invokeBasicMethod(basicInvokerType); 1021 } 1022 assert(isInvokeBasic()); 1023 } 1024 1025 private boolean isInvokeBasic() { 1026 return member != null && 1027 member.isMethodHandleInvoke() && 1028 "invokeBasic".equals(member.getName()); 1029 } 1030 1031 // The next 3 constructors are used to break circular dependencies on MH.invokeStatic, etc. 1032 // Any LambdaForm containing such a member is not interpretable. 1033 // This is OK, since all such LFs are prepared with special primitive vmentry points. 1034 // And even without the resolvedHandle, the name can still be compiled and optimized. 1035 NamedFunction(Method method) { 1036 this(new MemberName(method)); 1037 } 1038 NamedFunction(Field field) { 1039 this(new MemberName(field)); 1040 } 1041 NamedFunction(MemberName member) { 1042 this.member = member; 1043 this.resolvedHandle = null; 1044 } 1045 1046 MethodHandle resolvedHandle() { 1047 if (resolvedHandle == null) resolve(); 1048 return resolvedHandle; 1049 } 1050 1051 void resolve() { 1052 resolvedHandle = DirectMethodHandle.make(member); 1053 } 1054 1055 @Override 1056 public boolean equals(Object other) { 1057 if (this == other) return true; 1058 if (other == null) return false; 1059 if (!(other instanceof NamedFunction)) return false; 1060 NamedFunction that = (NamedFunction) other; 1061 return this.member != null && this.member.equals(that.member); 1062 } 1063 1064 @Override 1065 public int hashCode() { 1066 if (member != null) 1067 return member.hashCode(); 1068 return super.hashCode(); 1069 } 1070 1071 // Put the predefined NamedFunction invokers into the table. 1072 static void initializeInvokers() { 1073 for (MemberName m : MemberName.getFactory().getMethods(NamedFunction.class, false, null, null, null)) { 1074 if (!m.isStatic() || !m.isPackage()) continue; 1075 MethodType type = m.getMethodType(); 1076 if (type.equals(INVOKER_METHOD_TYPE) && 1077 m.getName().startsWith("invoke_")) { 1078 String sig = m.getName().substring("invoke_".length()); 1079 int arity = LambdaForm.signatureArity(sig); 1080 MethodType srcType = MethodType.genericMethodType(arity); 1081 if (LambdaForm.signatureReturn(sig) == V_TYPE) 1082 srcType = srcType.changeReturnType(void.class); 1083 MethodTypeForm typeForm = srcType.form(); 1084 typeForm.setCachedMethodHandle(MethodTypeForm.MH_NF_INV, DirectMethodHandle.make(m)); 1085 } 1086 } 1087 } 1088 1089 // The following are predefined NamedFunction invokers. The system must build 1090 // a separate invoker for each distinct signature. 1091 /** void return type invokers. */ 1092 @Hidden 1093 static Object invoke__V(MethodHandle mh, Object[] a) throws Throwable { 1094 assert(arityCheck(0, void.class, mh, a)); 1095 mh.invokeBasic(); 1096 return null; 1097 } 1098 @Hidden 1099 static Object invoke_L_V(MethodHandle mh, Object[] a) throws Throwable { 1100 assert(arityCheck(1, void.class, mh, a)); 1101 mh.invokeBasic(a[0]); 1102 return null; 1103 } 1104 @Hidden 1105 static Object invoke_LL_V(MethodHandle mh, Object[] a) throws Throwable { 1106 assert(arityCheck(2, void.class, mh, a)); 1107 mh.invokeBasic(a[0], a[1]); 1108 return null; 1109 } 1110 @Hidden 1111 static Object invoke_LLL_V(MethodHandle mh, Object[] a) throws Throwable { 1112 assert(arityCheck(3, void.class, mh, a)); 1113 mh.invokeBasic(a[0], a[1], a[2]); 1114 return null; 1115 } 1116 @Hidden 1117 static Object invoke_LLLL_V(MethodHandle mh, Object[] a) throws Throwable { 1118 assert(arityCheck(4, void.class, mh, a)); 1119 mh.invokeBasic(a[0], a[1], a[2], a[3]); 1120 return null; 1121 } 1122 @Hidden 1123 static Object invoke_LLLLL_V(MethodHandle mh, Object[] a) throws Throwable { 1124 assert(arityCheck(5, void.class, mh, a)); 1125 mh.invokeBasic(a[0], a[1], a[2], a[3], a[4]); 1126 return null; 1127 } 1128 /** Object return type invokers. */ 1129 @Hidden 1130 static Object invoke__L(MethodHandle mh, Object[] a) throws Throwable { 1131 assert(arityCheck(0, mh, a)); 1132 return mh.invokeBasic(); 1133 } 1134 @Hidden 1135 static Object invoke_L_L(MethodHandle mh, Object[] a) throws Throwable { 1136 assert(arityCheck(1, mh, a)); 1137 return mh.invokeBasic(a[0]); 1138 } 1139 @Hidden 1140 static Object invoke_LL_L(MethodHandle mh, Object[] a) throws Throwable { 1141 assert(arityCheck(2, mh, a)); 1142 return mh.invokeBasic(a[0], a[1]); 1143 } 1144 @Hidden 1145 static Object invoke_LLL_L(MethodHandle mh, Object[] a) throws Throwable { 1146 assert(arityCheck(3, mh, a)); 1147 return mh.invokeBasic(a[0], a[1], a[2]); 1148 } 1149 @Hidden 1150 static Object invoke_LLLL_L(MethodHandle mh, Object[] a) throws Throwable { 1151 assert(arityCheck(4, mh, a)); 1152 return mh.invokeBasic(a[0], a[1], a[2], a[3]); 1153 } 1154 @Hidden 1155 static Object invoke_LLLLL_L(MethodHandle mh, Object[] a) throws Throwable { 1156 assert(arityCheck(5, mh, a)); 1157 return mh.invokeBasic(a[0], a[1], a[2], a[3], a[4]); 1158 } 1159 private static boolean arityCheck(int arity, MethodHandle mh, Object[] a) { 1160 return arityCheck(arity, Object.class, mh, a); 1161 } 1162 private static boolean arityCheck(int arity, Class<?> rtype, MethodHandle mh, Object[] a) { 1163 assert(a.length == arity) 1164 : Arrays.asList(a.length, arity); 1165 assert(mh.type().basicType() == MethodType.genericMethodType(arity).changeReturnType(rtype)) 1166 : Arrays.asList(mh, rtype, arity); 1167 MemberName member = mh.internalMemberName(); 1168 if (member != null && member.getName().equals("invokeBasic") && member.isMethodHandleInvoke()) { 1169 assert(arity > 0); 1170 assert(a[0] instanceof MethodHandle); 1171 MethodHandle mh2 = (MethodHandle) a[0]; 1172 assert(mh2.type().basicType() == MethodType.genericMethodType(arity-1).changeReturnType(rtype)) 1173 : Arrays.asList(member, mh2, rtype, arity); 1174 } 1175 return true; 1176 } 1177 1178 static final MethodType INVOKER_METHOD_TYPE = 1179 MethodType.methodType(Object.class, MethodHandle.class, Object[].class); 1180 1181 private static MethodHandle computeInvoker(MethodTypeForm typeForm) { 1182 typeForm = typeForm.basicType().form(); // normalize to basic type 1183 MethodHandle mh = typeForm.cachedMethodHandle(MethodTypeForm.MH_NF_INV); 1184 if (mh != null) return mh; 1185 MemberName invoker = InvokerBytecodeGenerator.generateNamedFunctionInvoker(typeForm); // this could take a while 1186 mh = DirectMethodHandle.make(invoker); 1187 MethodHandle mh2 = typeForm.cachedMethodHandle(MethodTypeForm.MH_NF_INV); 1188 if (mh2 != null) return mh2; // benign race 1189 if (!mh.type().equals(INVOKER_METHOD_TYPE)) 1190 throw newInternalError(mh.debugString()); 1191 return typeForm.setCachedMethodHandle(MethodTypeForm.MH_NF_INV, mh); 1192 } 1193 1194 @Hidden 1195 Object invokeWithArguments(Object... arguments) throws Throwable { 1196 // If we have a cached invoker, call it right away. 1197 // NOTE: The invoker always returns a reference value. 1198 if (TRACE_INTERPRETER) return invokeWithArgumentsTracing(arguments); 1199 assert(checkArgumentTypes(arguments, methodType())); 1200 return invoker().invokeBasic(resolvedHandle(), arguments); 1201 } 1202 1203 @Hidden 1204 Object invokeWithArgumentsTracing(Object[] arguments) throws Throwable { 1205 Object rval; 1206 try { 1207 traceInterpreter("[ call", this, arguments); 1208 if (invoker == null) { 1209 traceInterpreter("| getInvoker", this); 1210 invoker(); 1211 } 1212 if (resolvedHandle == null) { 1213 traceInterpreter("| resolve", this); 1214 resolvedHandle(); 1215 } 1216 assert(checkArgumentTypes(arguments, methodType())); 1217 rval = invoker().invokeBasic(resolvedHandle(), arguments); 1218 } catch (Throwable ex) { 1219 traceInterpreter("] throw =>", ex); 1220 throw ex; 1221 } 1222 traceInterpreter("] return =>", rval); 1223 return rval; 1224 } 1225 1226 private MethodHandle invoker() { 1227 if (invoker != null) return invoker; 1228 // Get an invoker and cache it. 1229 return invoker = computeInvoker(methodType().form()); 1230 } 1231 1232 private static boolean checkArgumentTypes(Object[] arguments, MethodType methodType) { 1233 if (true) return true; // FIXME 1234 MethodType dstType = methodType.form().erasedType(); 1235 MethodType srcType = dstType.basicType().wrap(); 1236 Class<?>[] ptypes = new Class<?>[arguments.length]; 1237 for (int i = 0; i < arguments.length; i++) { 1238 Object arg = arguments[i]; 1239 Class<?> ptype = arg == null ? Object.class : arg.getClass(); 1240 // If the dest. type is a primitive we keep the 1241 // argument type. 1242 ptypes[i] = dstType.parameterType(i).isPrimitive() ? ptype : Object.class; 1243 } 1244 MethodType argType = MethodType.methodType(srcType.returnType(), ptypes).wrap(); 1245 assert(argType.isConvertibleTo(srcType)) : "wrong argument types: cannot convert " + argType + " to " + srcType; 1246 return true; 1247 } 1248 1249 MethodType methodType() { 1250 if (resolvedHandle != null) 1251 return resolvedHandle.type(); 1252 else 1253 // only for certain internal LFs during bootstrapping 1254 return member.getInvocationType(); 1255 } 1256 1257 MemberName member() { 1258 assert(assertMemberIsConsistent()); 1259 return member; 1260 } 1261 1262 // Called only from assert. 1263 private boolean assertMemberIsConsistent() { 1264 if (resolvedHandle instanceof DirectMethodHandle) { 1265 MemberName m = resolvedHandle.internalMemberName(); 1266 assert(m.equals(member)); 1267 } 1268 return true; 1269 } 1270 1271 Class<?> memberDeclaringClassOrNull() { 1272 return (member == null) ? null : member.getDeclaringClass(); 1273 } 1274 1275 BasicType returnType() { 1276 return basicType(methodType().returnType()); 1277 } 1278 1279 BasicType parameterType(int n) { 1280 return basicType(methodType().parameterType(n)); 1281 } 1282 1283 int arity() { 1284 return methodType().parameterCount(); 1285 } 1286 1287 public String toString() { 1288 if (member == null) return String.valueOf(resolvedHandle); 1289 return member.getDeclaringClass().getSimpleName()+"."+member.getName(); 1290 } 1291 1292 public boolean isIdentity() { 1293 return this.equals(identity(returnType())); 1294 } 1295 1296 public boolean isConstantZero() { 1297 return this.equals(constantZero(returnType())); 1298 } 1299 1300 public MethodHandleImpl.Intrinsic intrinsicName() { 1301 return resolvedHandle == null ? MethodHandleImpl.Intrinsic.NONE 1302 : resolvedHandle.intrinsicName(); 1303 } 1304 } 1305 1306 public static String basicTypeSignature(MethodType type) { 1307 char[] sig = new char[type.parameterCount() + 2]; 1308 int sigp = 0; 1309 for (Class<?> pt : type.parameterList()) { 1310 sig[sigp++] = basicTypeChar(pt); 1311 } 1312 sig[sigp++] = '_'; 1313 sig[sigp++] = basicTypeChar(type.returnType()); 1314 assert(sigp == sig.length); 1315 return String.valueOf(sig); 1316 } 1317 public static String shortenSignature(String signature) { 1318 // Hack to make signatures more readable when they show up in method names. 1319 final int NO_CHAR = -1, MIN_RUN = 3; 1320 int c0, c1 = NO_CHAR, c1reps = 0; 1321 StringBuilder buf = null; 1322 int len = signature.length(); 1323 if (len < MIN_RUN) return signature; 1324 for (int i = 0; i <= len; i++) { 1325 // shift in the next char: 1326 c0 = c1; c1 = (i == len ? NO_CHAR : signature.charAt(i)); 1327 if (c1 == c0) { ++c1reps; continue; } 1328 // shift in the next count: 1329 int c0reps = c1reps; c1reps = 1; 1330 // end of a character run 1331 if (c0reps < MIN_RUN) { 1332 if (buf != null) { 1333 while (--c0reps >= 0) 1334 buf.append((char)c0); 1335 } 1336 continue; 1337 } 1338 // found three or more in a row 1339 if (buf == null) 1340 buf = new StringBuilder().append(signature, 0, i - c0reps); 1341 buf.append((char)c0).append(c0reps); 1342 } 1343 return (buf == null) ? signature : buf.toString(); 1344 } 1345 1346 static final class Name { 1347 final BasicType type; 1348 private short index; 1349 final NamedFunction function; 1350 final Object constraint; // additional type information, if not null 1351 @Stable final Object[] arguments; 1352 1353 private Name(int index, BasicType type, NamedFunction function, Object[] arguments) { 1354 this.index = (short)index; 1355 this.type = type; 1356 this.function = function; 1357 this.arguments = arguments; 1358 this.constraint = null; 1359 assert(this.index == index); 1360 } 1361 private Name(Name that, Object constraint) { 1362 this.index = that.index; 1363 this.type = that.type; 1364 this.function = that.function; 1365 this.arguments = that.arguments; 1366 this.constraint = constraint; 1367 assert(constraint == null || isParam()); // only params have constraints 1368 assert(constraint == null || constraint instanceof BoundMethodHandle.SpeciesData || constraint instanceof Class); 1369 } 1370 Name(MethodHandle function, Object... arguments) { 1371 this(new NamedFunction(function), arguments); 1372 } 1373 Name(MethodType functionType, Object... arguments) { 1374 this(new NamedFunction(functionType), arguments); 1375 assert(arguments[0] instanceof Name && ((Name)arguments[0]).type == L_TYPE); 1376 } 1377 Name(MemberName function, Object... arguments) { 1378 this(new NamedFunction(function), arguments); 1379 } 1380 Name(NamedFunction function, Object... arguments) { 1381 this(-1, function.returnType(), function, arguments = Arrays.copyOf(arguments, arguments.length, Object[].class)); 1382 assert(arguments.length == function.arity()) : "arity mismatch: arguments.length=" + arguments.length + " == function.arity()=" + function.arity() + " in " + debugString(); 1383 for (int i = 0; i < arguments.length; i++) 1384 assert(typesMatch(function.parameterType(i), arguments[i])) : "types don't match: function.parameterType(" + i + ")=" + function.parameterType(i) + ", arguments[" + i + "]=" + arguments[i] + " in " + debugString(); 1385 } 1386 /** Create a raw parameter of the given type, with an expected index. */ 1387 Name(int index, BasicType type) { 1388 this(index, type, null, null); 1389 } 1390 /** Create a raw parameter of the given type. */ 1391 Name(BasicType type) { this(-1, type); } 1392 1393 BasicType type() { return type; } 1394 int index() { return index; } 1395 boolean initIndex(int i) { 1396 if (index != i) { 1397 if (index != -1) return false; 1398 index = (short)i; 1399 } 1400 return true; 1401 } 1402 char typeChar() { 1403 return type.btChar; 1404 } 1405 1406 void resolve() { 1407 if (function != null) 1408 function.resolve(); 1409 } 1410 1411 Name newIndex(int i) { 1412 if (initIndex(i)) return this; 1413 return cloneWithIndex(i); 1414 } 1415 Name cloneWithIndex(int i) { 1416 Object[] newArguments = (arguments == null) ? null : arguments.clone(); 1417 return new Name(i, type, function, newArguments).withConstraint(constraint); 1418 } 1419 Name withConstraint(Object constraint) { 1420 if (constraint == this.constraint) return this; 1421 return new Name(this, constraint); 1422 } 1423 Name replaceName(Name oldName, Name newName) { // FIXME: use replaceNames uniformly 1424 if (oldName == newName) return this; 1425 @SuppressWarnings("LocalVariableHidesMemberVariable") 1426 Object[] arguments = this.arguments; 1427 if (arguments == null) return this; 1428 boolean replaced = false; 1429 for (int j = 0; j < arguments.length; j++) { 1430 if (arguments[j] == oldName) { 1431 if (!replaced) { 1432 replaced = true; 1433 arguments = arguments.clone(); 1434 } 1435 arguments[j] = newName; 1436 } 1437 } 1438 if (!replaced) return this; 1439 return new Name(function, arguments); 1440 } 1441 /** In the arguments of this Name, replace oldNames[i] pairwise by newNames[i]. 1442 * Limit such replacements to {@code start<=i<end}. Return possibly changed self. 1443 */ 1444 Name replaceNames(Name[] oldNames, Name[] newNames, int start, int end) { 1445 if (start >= end) return this; 1446 @SuppressWarnings("LocalVariableHidesMemberVariable") 1447 Object[] arguments = this.arguments; 1448 boolean replaced = false; 1449 eachArg: 1450 for (int j = 0; j < arguments.length; j++) { 1451 if (arguments[j] instanceof Name) { 1452 Name n = (Name) arguments[j]; 1453 int check = n.index; 1454 // harmless check to see if the thing is already in newNames: 1455 if (check >= 0 && check < newNames.length && n == newNames[check]) 1456 continue eachArg; 1457 // n might not have the correct index: n != oldNames[n.index]. 1458 for (int i = start; i < end; i++) { 1459 if (n == oldNames[i]) { 1460 if (n == newNames[i]) 1461 continue eachArg; 1462 if (!replaced) { 1463 replaced = true; 1464 arguments = arguments.clone(); 1465 } 1466 arguments[j] = newNames[i]; 1467 continue eachArg; 1468 } 1469 } 1470 } 1471 } 1472 if (!replaced) return this; 1473 return new Name(function, arguments); 1474 } 1475 void internArguments() { 1476 @SuppressWarnings("LocalVariableHidesMemberVariable") 1477 Object[] arguments = this.arguments; 1478 for (int j = 0; j < arguments.length; j++) { 1479 if (arguments[j] instanceof Name) { 1480 Name n = (Name) arguments[j]; 1481 if (n.isParam() && n.index < INTERNED_ARGUMENT_LIMIT) 1482 arguments[j] = internArgument(n); 1483 } 1484 } 1485 } 1486 boolean isParam() { 1487 return function == null; 1488 } 1489 boolean isConstantZero() { 1490 return !isParam() && arguments.length == 0 && function.isConstantZero(); 1491 } 1492 1493 public String toString() { 1494 return (isParam()?"a":"t")+(index >= 0 ? index : System.identityHashCode(this))+":"+typeChar(); 1495 } 1496 public String debugString() { 1497 String s = paramString(); 1498 return (function == null) ? s : s + "=" + exprString(); 1499 } 1500 public String paramString() { 1501 String s = toString(); 1502 Object c = constraint; 1503 if (c == null) 1504 return s; 1505 if (c instanceof Class) c = ((Class<?>)c).getSimpleName(); 1506 return s + "/" + c; 1507 } 1508 public String exprString() { 1509 if (function == null) return toString(); 1510 StringBuilder buf = new StringBuilder(function.toString()); 1511 buf.append("("); 1512 String cma = ""; 1513 for (Object a : arguments) { 1514 buf.append(cma); cma = ","; 1515 if (a instanceof Name || a instanceof Integer) 1516 buf.append(a); 1517 else 1518 buf.append("(").append(a).append(")"); 1519 } 1520 buf.append(")"); 1521 return buf.toString(); 1522 } 1523 1524 static boolean typesMatch(BasicType parameterType, Object object) { 1525 if (object instanceof Name) { 1526 return ((Name)object).type == parameterType; 1527 } 1528 switch (parameterType) { 1529 case I_TYPE: return object instanceof Integer; 1530 case J_TYPE: return object instanceof Long; 1531 case F_TYPE: return object instanceof Float; 1532 case D_TYPE: return object instanceof Double; 1533 } 1534 assert(parameterType == L_TYPE); 1535 return true; 1536 } 1537 1538 /** Return the index of the last occurrence of n in the argument array. 1539 * Return -1 if the name is not used. 1540 */ 1541 int lastUseIndex(Name n) { 1542 if (arguments == null) return -1; 1543 for (int i = arguments.length; --i >= 0; ) { 1544 if (arguments[i] == n) return i; 1545 } 1546 return -1; 1547 } 1548 1549 /** Return the number of occurrences of n in the argument array. 1550 * Return 0 if the name is not used. 1551 */ 1552 int useCount(Name n) { 1553 if (arguments == null) return 0; 1554 int count = 0; 1555 for (int i = arguments.length; --i >= 0; ) { 1556 if (arguments[i] == n) ++count; 1557 } 1558 return count; 1559 } 1560 1561 boolean contains(Name n) { 1562 return this == n || lastUseIndex(n) >= 0; 1563 } 1564 1565 public boolean equals(Name that) { 1566 if (this == that) return true; 1567 if (isParam()) 1568 // each parameter is a unique atom 1569 return false; // this != that 1570 return 1571 //this.index == that.index && 1572 this.type == that.type && 1573 this.function.equals(that.function) && 1574 Arrays.equals(this.arguments, that.arguments); 1575 } 1576 @Override 1577 public boolean equals(Object x) { 1578 return x instanceof Name && equals((Name)x); 1579 } 1580 @Override 1581 public int hashCode() { 1582 if (isParam()) 1583 return index | (type.ordinal() << 8); 1584 return function.hashCode() ^ Arrays.hashCode(arguments); 1585 } 1586 } 1587 1588 /** Return the index of the last name which contains n as an argument. 1589 * Return -1 if the name is not used. Return names.length if it is the return value. 1590 */ 1591 int lastUseIndex(Name n) { 1592 int ni = n.index, nmax = names.length; 1593 assert(names[ni] == n); 1594 if (result == ni) return nmax; // live all the way beyond the end 1595 for (int i = nmax; --i > ni; ) { 1596 if (names[i].lastUseIndex(n) >= 0) 1597 return i; 1598 } 1599 return -1; 1600 } 1601 1602 /** Return the number of times n is used as an argument or return value. */ 1603 int useCount(Name n) { 1604 int ni = n.index, nmax = names.length; 1605 int end = lastUseIndex(n); 1606 if (end < 0) return 0; 1607 int count = 0; 1608 if (end == nmax) { count++; end--; } 1609 int beg = n.index() + 1; 1610 if (beg < arity) beg = arity; 1611 for (int i = beg; i <= end; i++) { 1612 count += names[i].useCount(n); 1613 } 1614 return count; 1615 } 1616 1617 static Name argument(int which, char type) { 1618 return argument(which, basicType(type)); 1619 } 1620 static Name argument(int which, BasicType type) { 1621 if (which >= INTERNED_ARGUMENT_LIMIT) 1622 return new Name(which, type); 1623 return INTERNED_ARGUMENTS[type.ordinal()][which]; 1624 } 1625 static Name internArgument(Name n) { 1626 assert(n.isParam()) : "not param: " + n; 1627 assert(n.index < INTERNED_ARGUMENT_LIMIT); 1628 if (n.constraint != null) return n; 1629 return argument(n.index, n.type); 1630 } 1631 static Name[] arguments(int extra, String types) { 1632 int length = types.length(); 1633 Name[] names = new Name[length + extra]; 1634 for (int i = 0; i < length; i++) 1635 names[i] = argument(i, types.charAt(i)); 1636 return names; 1637 } 1638 static Name[] arguments(int extra, char... types) { 1639 int length = types.length; 1640 Name[] names = new Name[length + extra]; 1641 for (int i = 0; i < length; i++) 1642 names[i] = argument(i, types[i]); 1643 return names; 1644 } 1645 static Name[] arguments(int extra, List<Class<?>> types) { 1646 int length = types.size(); 1647 Name[] names = new Name[length + extra]; 1648 for (int i = 0; i < length; i++) 1649 names[i] = argument(i, basicType(types.get(i))); 1650 return names; 1651 } 1652 static Name[] arguments(int extra, Class<?>... types) { 1653 int length = types.length; 1654 Name[] names = new Name[length + extra]; 1655 for (int i = 0; i < length; i++) 1656 names[i] = argument(i, basicType(types[i])); 1657 return names; 1658 } 1659 static Name[] arguments(int extra, MethodType types) { 1660 int length = types.parameterCount(); 1661 Name[] names = new Name[length + extra]; 1662 for (int i = 0; i < length; i++) 1663 names[i] = argument(i, basicType(types.parameterType(i))); 1664 return names; 1665 } 1666 static final int INTERNED_ARGUMENT_LIMIT = 10; 1667 private static final Name[][] INTERNED_ARGUMENTS 1668 = new Name[ARG_TYPE_LIMIT][INTERNED_ARGUMENT_LIMIT]; 1669 static { 1670 for (BasicType type : BasicType.ARG_TYPES) { 1671 int ord = type.ordinal(); 1672 for (int i = 0; i < INTERNED_ARGUMENTS[ord].length; i++) { 1673 INTERNED_ARGUMENTS[ord][i] = new Name(i, type); 1674 } 1675 } 1676 } 1677 1678 private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory(); 1679 1680 static LambdaForm identityForm(BasicType type) { 1681 return LF_identityForm[type.ordinal()]; 1682 } 1683 static LambdaForm zeroForm(BasicType type) { 1684 return LF_zeroForm[type.ordinal()]; 1685 } 1686 static NamedFunction identity(BasicType type) { 1687 return NF_identity[type.ordinal()]; 1688 } 1689 static NamedFunction constantZero(BasicType type) { 1690 return NF_zero[type.ordinal()]; 1691 } 1692 private static final LambdaForm[] LF_identityForm = new LambdaForm[TYPE_LIMIT]; 1693 private static final LambdaForm[] LF_zeroForm = new LambdaForm[TYPE_LIMIT]; 1694 private static final NamedFunction[] NF_identity = new NamedFunction[TYPE_LIMIT]; 1695 private static final NamedFunction[] NF_zero = new NamedFunction[TYPE_LIMIT]; 1696 private static void createIdentityForms() { 1697 for (BasicType type : BasicType.ALL_TYPES) { 1698 int ord = type.ordinal(); 1699 char btChar = type.basicTypeChar(); 1700 boolean isVoid = (type == V_TYPE); 1701 Class<?> btClass = type.btClass; 1702 MethodType zeType = MethodType.methodType(btClass); 1703 MethodType idType = isVoid ? zeType : zeType.appendParameterTypes(btClass); 1704 1705 // Look up some symbolic names. It might not be necessary to have these, 1706 // but if we need to emit direct references to bytecodes, it helps. 1707 // Zero is built from a call to an identity function with a constant zero input. 1708 MemberName idMem = new MemberName(LambdaForm.class, "identity_"+btChar, idType, REF_invokeStatic); 1709 MemberName zeMem = new MemberName(LambdaForm.class, "zero_"+btChar, zeType, REF_invokeStatic); 1710 try { 1711 zeMem = IMPL_NAMES.resolveOrFail(REF_invokeStatic, zeMem, null, NoSuchMethodException.class); 1712 idMem = IMPL_NAMES.resolveOrFail(REF_invokeStatic, idMem, null, NoSuchMethodException.class); 1713 } catch (IllegalAccessException|NoSuchMethodException ex) { 1714 throw newInternalError(ex); 1715 } 1716 1717 NamedFunction idFun = new NamedFunction(idMem); 1718 LambdaForm idForm; 1719 if (isVoid) { 1720 Name[] idNames = new Name[] { argument(0, L_TYPE) }; 1721 idForm = new LambdaForm(idMem.getName(), 1, idNames, VOID_RESULT); 1722 } else { 1723 Name[] idNames = new Name[] { argument(0, L_TYPE), argument(1, type) }; 1724 idForm = new LambdaForm(idMem.getName(), 2, idNames, 1); 1725 } 1726 LF_identityForm[ord] = idForm; 1727 NF_identity[ord] = idFun; 1728 1729 NamedFunction zeFun = new NamedFunction(zeMem); 1730 LambdaForm zeForm; 1731 if (isVoid) { 1732 zeForm = idForm; 1733 } else { 1734 Object zeValue = Wrapper.forBasicType(btChar).zero(); 1735 Name[] zeNames = new Name[] { argument(0, L_TYPE), new Name(idFun, zeValue) }; 1736 zeForm = new LambdaForm(zeMem.getName(), 1, zeNames, 1); 1737 } 1738 LF_zeroForm[ord] = zeForm; 1739 NF_zero[ord] = zeFun; 1740 1741 assert(idFun.isIdentity()); 1742 assert(zeFun.isConstantZero()); 1743 assert(new Name(zeFun).isConstantZero()); 1744 } 1745 1746 // Do this in a separate pass, so that SimpleMethodHandle.make can see the tables. 1747 for (BasicType type : BasicType.ALL_TYPES) { 1748 int ord = type.ordinal(); 1749 NamedFunction idFun = NF_identity[ord]; 1750 LambdaForm idForm = LF_identityForm[ord]; 1751 MemberName idMem = idFun.member; 1752 idFun.resolvedHandle = SimpleMethodHandle.make(idMem.getInvocationType(), idForm); 1753 1754 NamedFunction zeFun = NF_zero[ord]; 1755 LambdaForm zeForm = LF_zeroForm[ord]; 1756 MemberName zeMem = zeFun.member; 1757 zeFun.resolvedHandle = SimpleMethodHandle.make(zeMem.getInvocationType(), zeForm); 1758 1759 assert(idFun.isIdentity()); 1760 assert(zeFun.isConstantZero()); 1761 assert(new Name(zeFun).isConstantZero()); 1762 } 1763 } 1764 1765 // Avoid appealing to ValueConversions at bootstrap time: 1766 private static int identity_I(int x) { return x; } 1767 private static long identity_J(long x) { return x; } 1768 private static float identity_F(float x) { return x; } 1769 private static double identity_D(double x) { return x; } 1770 private static Object identity_L(Object x) { return x; } 1771 private static void identity_V() { return; } // same as zeroV, but that's OK 1772 private static int zero_I() { return 0; } 1773 private static long zero_J() { return 0; } 1774 private static float zero_F() { return 0; } 1775 private static double zero_D() { return 0; } 1776 private static Object zero_L() { return null; } 1777 private static void zero_V() { return; } 1778 1779 /** 1780 * Internal marker for byte-compiled LambdaForms. 1781 */ 1782 /*non-public*/ 1783 @Target(ElementType.METHOD) 1784 @Retention(RetentionPolicy.RUNTIME) 1785 @interface Compiled { 1786 } 1787 1788 /** 1789 * Internal marker for LambdaForm interpreter frames. 1790 */ 1791 /*non-public*/ 1792 @Target(ElementType.METHOD) 1793 @Retention(RetentionPolicy.RUNTIME) 1794 @interface Hidden { 1795 } 1796 1797 /** 1798 * Internal marker which signals JIT that gathered profile is mostly useless. 1799 */ 1800 /*non-public*/ 1801 @Target(ElementType.METHOD) 1802 @Retention(RetentionPolicy.RUNTIME) 1803 @interface Shared { 1804 } 1805 1806 private static final HashMap<String,Integer> DEBUG_NAME_COUNTERS; 1807 static { 1808 if (debugEnabled()) 1809 DEBUG_NAME_COUNTERS = new HashMap<>(); 1810 else 1811 DEBUG_NAME_COUNTERS = null; 1812 } 1813 1814 // Put this last, so that previous static inits can run before. 1815 static { 1816 createIdentityForms(); 1817 if (USE_PREDEFINED_INTERPRET_METHODS) 1818 computeInitialPreparedForms(); 1819 NamedFunction.initializeInvokers(); 1820 } 1821 1822 // The following hack is necessary in order to suppress TRACE_INTERPRETER 1823 // during execution of the static initializes of this class. 1824 // Turning on TRACE_INTERPRETER too early will cause 1825 // stack overflows and other misbehavior during attempts to trace events 1826 // that occur during LambdaForm.<clinit>. 1827 // Therefore, do not move this line higher in this file, and do not remove. 1828 private static final boolean TRACE_INTERPRETER = MethodHandleStatics.TRACE_INTERPRETER; 1829 }