rev 47761 : 8186209: Tool support for ConstantDynamic
8186046: Minimal ConstantDynamic support
Reviewed-by: acorn
Contributed-by: lois.foltan@oracle.com, john.r.rose@oracle.com, paul.sandoz@oracle.com
* * *
Minor Hotspot code cleanup changes resulting from condy review
Summary: Addressed missing DynamicInError condition, removed unused TraceDynamicConstants
Reviewed-by: acorn, psandoz
rev 47762 : 8187742: Minimal set of bootstrap methods for constant dynamic
Contributed-by: brian.goetz@oracle.com, john.r.rose@oracle.com, paul.sandoz@oracle.com
Reviewed-by: forax

   1 /*
   2  * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 package jdk.experimental.bytecode;
  25 
  26 import java.lang.invoke.MethodHandles;
  27 import java.lang.invoke.MethodHandles.Lookup;
  28 import java.lang.reflect.Field;
  29 import java.lang.reflect.Method;
  30 import java.nio.ByteBuffer;
  31 import java.util.Arrays;
  32 import java.util.HashMap;
  33 import java.util.Map;
  34 import java.util.function.Consumer;
  35 import java.util.function.ToIntFunction;
  36 
  37 public class IsolatedMethodBuilder extends MethodBuilder<Class<?>, String, Object[]> {
  38 
  39     public IsolatedMethodBuilder(Lookup lookup, String name, String type) {
  40         super(null, name, type, new IsolatedMethodPoolHelper(lookup), null);
  41     }
  42 
  43     static class IsolatedMethodPoolHelper implements PoolHelper<Class<?>, String, Object[]> {
  44         Map<Object, Integer> constants = new HashMap<>();
  45         Lookup lookup;
  46 
  47         private IsolatedMethodPoolHelper(Lookup lookup) {
  48             this.lookup = lookup;
  49         }
  50 
  51         @Override
  52         public int putClass(Class<?> symbol) {
  53             return putIfAbsent(symbol);
  54         }
  55 
  56         @Override
  57         public int putFieldRef(Class<?> owner, CharSequence name, String type) {
  58             try {
  59                 Field f = owner.getDeclaredField(name.toString()); //TODO: we should unreflect for a var handle
  60                 return putIfAbsent(lookup.unreflectGetter(f));
  61             } catch (Throwable ex) {
  62                 ex.printStackTrace();
  63                 return -1;
  64             }
  65         }
  66 
  67         @Override
  68         public int putMethodRef(Class<?> owner, CharSequence name, String type, boolean isInterface) {
  69             try {
  70                 Method m = owner.getDeclaredMethod(name.toString()); //we should unreflect according to method vs. constructor
  71                 //and static vs. private etc.
  72                 return putIfAbsent(lookup.unreflect(m));
  73             } catch (Throwable ex) {
  74                 ex.printStackTrace();
  75                 return -1;
  76             }
  77         }
  78 
  79         @Override
  80         public int putInt(int i) {
  81             return putIfAbsent(i);
  82         }
  83 
  84         @Override
  85         public int putFloat(float f) {
  86             return putIfAbsent(f);
  87         }
  88 
  89         @Override
  90         public int putLong(long l) {
  91             return putIfAbsent(l);
  92         }
  93 
  94         @Override
  95         public int putDouble(double d) {
  96             return putIfAbsent(d);
  97         }
  98 
  99         @Override
 100         public int putString(String s) {
 101             return putIfAbsent(s);
 102         }
 103 
 104         @Override
 105         public int putInvokeDynamic(CharSequence invokedName, String invokedType, Class<?> bsmClass, CharSequence bsmName, String bsmType, Consumer<StaticArgListBuilder<Class<?>, String, Object[]>> staticArgs) {
 106             return 0; //???
 107         }
 108 
 109         @Override
 110         public int putDynamicConstant(CharSequence constName, String constType, Class<?> bsmClass, CharSequence bsmName, String bsmType, Consumer<StaticArgListBuilder<Class<?>, String, Object[]>> staticArgs) {
 111             return 0; //???
 112         }
 113 
 114         @Override
 115         public int putHandle(int refKind, Class<?> owner, CharSequence name, String type) {
 116             return 0; //???
 117         }
 118 
 119         @Override





 120         public int putMethodType(String s) {
 121             return 0; //???
 122         }
 123 
 124         @Override
 125         public int putUtf8(CharSequence s) {
 126             return putIfAbsent(s);
 127         }
 128 
 129         @Override
 130         public int putType(String s) {
 131             return putIfAbsent(s);
 132         }
 133 
 134         @Override
 135         public int size() {
 136             return constants.size();
 137         }
 138 
 139         @Override
 140         public Object[] entries() {
 141             return constants.keySet().toArray();
 142         }
 143 
 144         int putIfAbsent(Object o) {
 145             int nextIndex = constants.size() + 1;
 146             Object res = constants.putIfAbsent(o, nextIndex);
 147             return res == null ?
 148                     nextIndex : (Integer)res;
 149         }
 150     }
 151 
 152     public Object[] entries() {
 153         return poolHelper.entries();
 154     }
 155 
 156     @Override
 157     public byte[] build() {
 158         byte[] arr = super.build();
 159         int codelength_offset = 2 + 2 + 2 + 2 +
 160                 2 + 4 + 2 + 2;
 161         int code_offset = codelength_offset + 4;
 162         int length = ByteBuffer.wrap(arr).getInt(codelength_offset);
 163         byte[] opcodes = new byte[length];
 164         System.arraycopy(arr, code_offset, opcodes, 0, length);
 165         return opcodes;
 166     }
 167 
 168     public static void main(String[] args) {
 169         IsolatedMethodBuilder imb =  new IsolatedMethodBuilder(MethodHandles.lookup(), "foo", "(java/lang/String;)I");
 170         imb.withCode(C ->
 171                     C.aload_0()
 172                      .invokevirtual(String.class, "length", "()I", false)
 173                      .ireturn());
 174         byte[] opcodes = imb.build();
 175         System.out.println(Arrays.toString(opcodes));
 176     }
 177 }
--- EOF ---