< prev index next >

src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java

Print this page
rev 12327 : 8062543: Replace uses of MethodHandleImpl.castReference with Class.cast
   1 /*
   2  * Copyright (c) 2012, 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


  44 /**
  45  * Code generation backend for LambdaForm.
  46  * <p>
  47  * @author John Rose, JSR 292 EG
  48  */
  49 class InvokerBytecodeGenerator {
  50     /** Define class names for convenience. */
  51     private static final String MH      = "java/lang/invoke/MethodHandle";
  52     private static final String MHI     = "java/lang/invoke/MethodHandleImpl";
  53     private static final String LF      = "java/lang/invoke/LambdaForm";
  54     private static final String LFN     = "java/lang/invoke/LambdaForm$Name";
  55     private static final String CLS     = "java/lang/Class";
  56     private static final String OBJ     = "java/lang/Object";
  57     private static final String OBJARY  = "[Ljava/lang/Object;";
  58 
  59     private static final String MH_SIG  = "L" + MH + ";";
  60     private static final String LF_SIG  = "L" + LF + ";";
  61     private static final String LFN_SIG = "L" + LFN + ";";
  62     private static final String LL_SIG  = "(L" + OBJ + ";)L" + OBJ + ";";
  63     private static final String LLV_SIG = "(L" + OBJ + ";L" + OBJ + ";)V";
  64     private static final String CLL_SIG = "(L" + CLS + ";L" + OBJ + ";)L" + OBJ + ";";
  65 
  66     /** Name of its super class*/
  67     private static final String superName = OBJ;
  68 
  69     /** Name of new class */
  70     private final String className;
  71 
  72     /** Name of the source file (for stack trace printing). */
  73     private final String sourceFile;
  74 
  75     private final LambdaForm lambdaForm;
  76     private final String     invokerName;
  77     private final MethodType invokerType;
  78 
  79     /** Info about local variables in compiled lambda form */
  80     private final int[]       localsMap;    // index
  81     private final BasicType[] localTypes;   // basic type
  82     private final Class<?>[]  localClasses; // type
  83 
  84     /** ASM bytecode generation. */


 554     }
 555 
 556     private void emitReferenceCast(Class<?> cls, Object arg) {
 557         Name writeBack = null;  // local to write back result
 558         if (arg instanceof Name) {
 559             Name n = (Name) arg;
 560             if (assertStaticType(cls, n))
 561                 return;  // this cast was already performed
 562             if (lambdaForm.useCount(n) > 1) {
 563                 // This guy gets used more than once.
 564                 writeBack = n;
 565             }
 566         }
 567         if (isStaticallyNameable(cls)) {
 568             String sig = getInternalName(cls);
 569             mv.visitTypeInsn(Opcodes.CHECKCAST, sig);
 570         } else {
 571             mv.visitLdcInsn(constantPlaceholder(cls));
 572             mv.visitTypeInsn(Opcodes.CHECKCAST, CLS);
 573             mv.visitInsn(Opcodes.SWAP);
 574             mv.visitMethodInsn(Opcodes.INVOKESTATIC, MHI, "castReference", CLL_SIG, false);
 575             if (Object[].class.isAssignableFrom(cls))
 576                 mv.visitTypeInsn(Opcodes.CHECKCAST, OBJARY);
 577             else if (PROFILE_LEVEL > 0)
 578                 mv.visitTypeInsn(Opcodes.CHECKCAST, OBJ);
 579         }
 580         if (writeBack != null) {
 581             mv.visitInsn(Opcodes.DUP);
 582             emitAstoreInsn(writeBack.index());
 583         }
 584     }
 585 
 586     /**
 587      * Emits an actual return instruction conforming to the given return type.
 588      */
 589     private void emitReturnInsn(BasicType type) {
 590         int opcode;
 591         switch (type) {
 592         case I_TYPE:  opcode = Opcodes.IRETURN;  break;
 593         case J_TYPE:  opcode = Opcodes.LRETURN;  break;
 594         case F_TYPE:  opcode = Opcodes.FRETURN;  break;


   1 /*
   2  * Copyright (c) 2012, 2015, 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


  44 /**
  45  * Code generation backend for LambdaForm.
  46  * <p>
  47  * @author John Rose, JSR 292 EG
  48  */
  49 class InvokerBytecodeGenerator {
  50     /** Define class names for convenience. */
  51     private static final String MH      = "java/lang/invoke/MethodHandle";
  52     private static final String MHI     = "java/lang/invoke/MethodHandleImpl";
  53     private static final String LF      = "java/lang/invoke/LambdaForm";
  54     private static final String LFN     = "java/lang/invoke/LambdaForm$Name";
  55     private static final String CLS     = "java/lang/Class";
  56     private static final String OBJ     = "java/lang/Object";
  57     private static final String OBJARY  = "[Ljava/lang/Object;";
  58 
  59     private static final String MH_SIG  = "L" + MH + ";";
  60     private static final String LF_SIG  = "L" + LF + ";";
  61     private static final String LFN_SIG = "L" + LFN + ";";
  62     private static final String LL_SIG  = "(L" + OBJ + ";)L" + OBJ + ";";
  63     private static final String LLV_SIG = "(L" + OBJ + ";L" + OBJ + ";)V";

  64 
  65     /** Name of its super class*/
  66     private static final String superName = OBJ;
  67 
  68     /** Name of new class */
  69     private final String className;
  70 
  71     /** Name of the source file (for stack trace printing). */
  72     private final String sourceFile;
  73 
  74     private final LambdaForm lambdaForm;
  75     private final String     invokerName;
  76     private final MethodType invokerType;
  77 
  78     /** Info about local variables in compiled lambda form */
  79     private final int[]       localsMap;    // index
  80     private final BasicType[] localTypes;   // basic type
  81     private final Class<?>[]  localClasses; // type
  82 
  83     /** ASM bytecode generation. */


 553     }
 554 
 555     private void emitReferenceCast(Class<?> cls, Object arg) {
 556         Name writeBack = null;  // local to write back result
 557         if (arg instanceof Name) {
 558             Name n = (Name) arg;
 559             if (assertStaticType(cls, n))
 560                 return;  // this cast was already performed
 561             if (lambdaForm.useCount(n) > 1) {
 562                 // This guy gets used more than once.
 563                 writeBack = n;
 564             }
 565         }
 566         if (isStaticallyNameable(cls)) {
 567             String sig = getInternalName(cls);
 568             mv.visitTypeInsn(Opcodes.CHECKCAST, sig);
 569         } else {
 570             mv.visitLdcInsn(constantPlaceholder(cls));
 571             mv.visitTypeInsn(Opcodes.CHECKCAST, CLS);
 572             mv.visitInsn(Opcodes.SWAP);
 573             mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, CLS, "cast", LL_SIG, false);
 574             if (Object[].class.isAssignableFrom(cls))
 575                 mv.visitTypeInsn(Opcodes.CHECKCAST, OBJARY);
 576             else if (PROFILE_LEVEL > 0)
 577                 mv.visitTypeInsn(Opcodes.CHECKCAST, OBJ);
 578         }
 579         if (writeBack != null) {
 580             mv.visitInsn(Opcodes.DUP);
 581             emitAstoreInsn(writeBack.index());
 582         }
 583     }
 584 
 585     /**
 586      * Emits an actual return instruction conforming to the given return type.
 587      */
 588     private void emitReturnInsn(BasicType type) {
 589         int opcode;
 590         switch (type) {
 591         case I_TYPE:  opcode = Opcodes.IRETURN;  break;
 592         case J_TYPE:  opcode = Opcodes.LRETURN;  break;
 593         case F_TYPE:  opcode = Opcodes.FRETURN;  break;


< prev index next >