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