< prev index next >

src/java.base/share/classes/jdk/internal/foreign/abi/CallingSequenceBuilder.java

Print this page

        

@@ -2,13 +2,11 @@
  * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
+ *  published by the Free Software Foundation.
  *
  * This code is distributed in the hope that it will be useful, but WITHOUT
  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * version 2 for more details (a copy is included in the LICENSE file that

@@ -20,136 +18,82 @@
  *
  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-package jdk.internal.foreign.abi.x64;
 
-import jdk.internal.foreign.abi.Storage;
+package jdk.internal.foreign.abi;
 
-import java.foreign.layout.*;
+import java.foreign.layout.Address;
+import java.foreign.layout.Layout;
+import java.util.ArrayList;
+import java.util.EnumMap;
+import java.util.List;
+import java.util.function.BiConsumer;
 
 public abstract class CallingSequenceBuilder {
-    private final String[] integerArgumentRegisterNames;
-    private final String[] integerReturnRegisterNames;
-    private final String[] x87ReturnRegisterNames;
-    private final int maxVectorArgRegisters;
-    private final int maxVectorReturnRegisters;
 
-    protected CallingSequenceBuilder(String[] integerArgumentRegisterNames, String[] integerReturnRegisterNames,
-                                     String[]  x87ReturnRegisterNames, int maxVectorArgRegisters, int maxVectorReturnRegisters) {
-        this.integerArgumentRegisterNames = integerArgumentRegisterNames;
-        this.integerReturnRegisterNames = integerReturnRegisterNames;
-        this.x87ReturnRegisterNames = x87ReturnRegisterNames;
-        this.maxVectorArgRegisters = maxVectorArgRegisters;
-        this.maxVectorReturnRegisters = maxVectorReturnRegisters;
-    }
-
-    protected static long alignUp(long addr, long alignment) {
-        return ((addr - 1) | (alignment - 1)) + 1;
-    }
-
-    protected static long alignDown(long addr, long alignment) {
-        return addr & ~(alignment - 1);
-    }
+    private final EnumMap<StorageClass, List<ArgumentBinding>> bindings = new EnumMap<>(StorageClass.class);
+    private final boolean returnsInMemory;
 
-    protected static long alignmentOfScalar(Value st) {
-        return st.bitsSize() / 8;
-    }
-
-    protected static long alignmentOfArray(Sequence ar, boolean isVar) {
-        if (ar.elementsSize() == 0) {
-            // VLA or incomplete
-            return 16;
-        } else if ((ar.bitsSize() / 8) >= 16 && isVar) {
-            return 16;
-        } else {
-            // align as element type
-            Layout elementType = ar.element();
-            return alignment(elementType, false);
-        }
-    }
+    private int argIndex = 0;
 
-    protected static long alignmentOfContainer(Group ct) {
-        // Most strict member
-        return ct.elements().stream().mapToLong(t -> alignment(t, false)).max().orElse(1);
+    private final BindingsComputer returnBindgingsComputer;
+    private final BindingsComputer argumentBindgingsComputer;
+    private final BindingsComputer varargsBindgingsComputer;
+
+    protected CallingSequenceBuilder(Layout ret,
+                                     BindingsComputer returnBindgingsComputer,
+                                     BindingsComputer argumentBindgingsComputer,
+                                     BindingsComputer varargsBindgingsComputer) {
+        this.returnBindgingsComputer = returnBindgingsComputer;
+        this.argumentBindgingsComputer = argumentBindgingsComputer;
+        this.varargsBindgingsComputer = varargsBindgingsComputer;
+        if (ret != null) {
+            Argument retInfo = makeArgument(ret, -1, "__retval");
+            this.returnsInMemory = retInfo.inMemory();
+            if (returnsInMemory) {
+                retInfo = makeArgument(Address.ofLayout(64, ret), -1, "__retval");
+                addArgumentBindings(retInfo, false);
     }
-
-    /**
-     * The alignment requirement for a given type
-     * @param isVar indicate if the type is a standalone variable. This change how
-     * array is aligned. for example.
-     */
-    protected static long alignment(Layout t, boolean isVar) {
-        if (t instanceof Value) {
-            return alignmentOfScalar((Value) t);
-        } else if (t instanceof Sequence) {
-            // when array is used alone
-            return alignmentOfArray((Sequence) t, isVar);
-        } else if (t instanceof Group) {
-            return alignmentOfContainer((Group) t);
-        } else if (t instanceof Address) {
-            return 8;
-        } else if (t instanceof Padding) {
-            return 1;
+            addReturnBindings(retInfo);
         } else {
-            throw new IllegalArgumentException("Invalid type: " + t);
+            this.returnsInMemory = false;
         }
     }
 
-    /**
-     * Align the specified type from a given address
-     * @return The address the data should be at based on alignment requirement
-     */
-    protected static long align(Layout t, boolean isVar, long addr) {
-        return alignUp(addr, alignment(t, isVar));
+    public final CallingSequenceBuilder addArgument(Layout l) {
+        return addArgument(l, false);
     }
 
-    private static String getVectorRegisterName(long index, long size) {
-        switch ((int)size) {
-            case 8: return "xmm" + index + "_8";
-            case 16: return "xmm" + index;
-            case 32: return "ymm" + index;
-            case 64: return "zmm" + index;
-            default: throw new IllegalArgumentException("Illegal vector size: " + size);
-        }
+    public final CallingSequenceBuilder addArgument(Layout l, boolean isVarargs) {
+        addArgumentBindings(makeArgument(l, argIndex, "arg" + argIndex), isVarargs);
+        argIndex++;
+        return this;
     }
 
-    public String getStorageName(Storage storage) {
-        switch (storage.getStorageClass()) {
-            case INTEGER_ARGUMENT_REGISTER:
-                if (storage.getStorageIndex() > integerArgumentRegisterNames.length) {
-                    throw new IllegalArgumentException("Illegal storage: " + storage);
+    public final CallingSequence build() {
+        return new CallingSequence(returnsInMemory, bindings);
                 }
-                return integerArgumentRegisterNames[(int) storage.getStorageIndex()];
 
-            case VECTOR_ARGUMENT_REGISTER:
-                if (storage.getStorageIndex() > maxVectorArgRegisters) {
-                    throw new IllegalArgumentException("Illegal storage: " + storage);
-                }
-                return getVectorRegisterName(storage.getStorageIndex(), storage.getSize());
+    protected abstract Argument makeArgument(Layout layout, int pos, String name);
 
-            case INTEGER_RETURN_REGISTER:
-                if (storage.getStorageIndex() > integerReturnRegisterNames.length) {
-                    throw new IllegalArgumentException("Illegal storage: " + storage);
+    private void addReturnBindings(Argument a) {
+        returnBindgingsComputer.computeBindings(a, this::addBinding);
                 }
 
-                return integerReturnRegisterNames[(int) storage.getStorageIndex()];
-
-            case VECTOR_RETURN_REGISTER:
-                if (storage.getStorageIndex() > maxVectorReturnRegisters) {
-                    throw new IllegalArgumentException("Illegal storage: " + storage);
+    private void addArgumentBindings(Argument a, boolean isVarargs) {
+        if (isVarargs) {
+            varargsBindgingsComputer.computeBindings(a, this::addBinding);
+        } else {
+            argumentBindgingsComputer.computeBindings(a, this::addBinding);
                 }
-                return getVectorRegisterName(storage.getStorageIndex(), storage.getSize());
-
-            case X87_RETURN_REGISTER:
-                if (storage.getStorageIndex() > x87ReturnRegisterNames.length) {
-                    throw new IllegalArgumentException("Illegal storage: " + storage);
                 }
-                return x87ReturnRegisterNames[(int) storage.getStorageIndex()];
 
-            case STACK_ARGUMENT_SLOT: return "[sp + " + Long.toHexString(8 * storage.getStorageIndex()) + "]";
+    private void addBinding(StorageClass storageClass, ArgumentBinding binding) {
+        bindings.computeIfAbsent(storageClass, _unused -> new ArrayList<>()).add(binding);
         }
 
-        throw new IllegalArgumentException("Unhandled storage type: " + storage.getStorageClass());
+    public interface BindingsComputer {
+        void computeBindings(Argument argument, BiConsumer<StorageClass, ArgumentBinding> bindingConsumer);
     }
 }
< prev index next >