diff graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationData.java @ 10597:79041ab43660

Truffle-DSL: API-change: Renamed truffle.api.codegen to truffle.api.dsl for all projects and packages.
author Christian Humer <christian.humer@gmail.com>
date Mon, 01 Jul 2013 20:58:32 +0200
parents
children b8fe1fe004ec
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationData.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,251 @@
+/*
+ * Copyright (c) 2012, 2012, 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.
+ *
+ * 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
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * 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 com.oracle.truffle.dsl.processor.node;
+
+import java.util.*;
+
+import javax.lang.model.type.*;
+
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.dsl.processor.*;
+import com.oracle.truffle.dsl.processor.template.*;
+import com.oracle.truffle.dsl.processor.typesystem.*;
+
+public class SpecializationData extends TemplateMethod {
+
+    private final int order;
+    private final boolean generic;
+    private final boolean polymorphic;
+    private final boolean uninitialized;
+    private final List<SpecializationThrowsData> exceptions;
+    private List<String> guardDefinitions = Collections.emptyList();
+    private List<GuardData> guards = Collections.emptyList();
+    private List<ShortCircuitData> shortCircuits;
+    private List<String> assumptions = Collections.emptyList();
+    private NodeData node;
+    private boolean reachable;
+
+    public SpecializationData(TemplateMethod template, int order, List<SpecializationThrowsData> exceptions) {
+        super(template);
+        this.order = order;
+        this.generic = false;
+        this.uninitialized = false;
+        this.polymorphic = false;
+        this.exceptions = exceptions;
+
+        for (SpecializationThrowsData exception : exceptions) {
+            exception.setSpecialization(this);
+        }
+    }
+
+    public SpecializationData(TemplateMethod template, boolean generic, boolean uninitialized, boolean polymorphic) {
+        super(template);
+        this.order = Specialization.DEFAULT_ORDER;
+        this.generic = generic;
+        this.uninitialized = uninitialized;
+        this.polymorphic = polymorphic;
+        this.exceptions = Collections.emptyList();
+    }
+
+    public void setReachable(boolean reachable) {
+        this.reachable = reachable;
+    }
+
+    public boolean isReachable() {
+        return reachable;
+    }
+
+    public boolean isPolymorphic() {
+        return polymorphic;
+    }
+
+    @Override
+    protected List<MessageContainer> findChildContainers() {
+        List<MessageContainer> sinks = new ArrayList<>();
+        if (exceptions != null) {
+            sinks.addAll(exceptions);
+        }
+        if (guards != null) {
+            sinks.addAll(guards);
+        }
+        return sinks;
+    }
+
+    public boolean isGenericSpecialization(ProcessorContext context) {
+        if (isGeneric()) {
+            return true;
+        }
+        if (hasRewrite(context)) {
+            return false;
+        }
+
+        for (ActualParameter parameter : getParameters()) {
+            if (!parameter.getSpecification().isSignature()) {
+                continue;
+            }
+            NodeChildData child = getNode().findChild(parameter.getSpecification().getName());
+            if (child == null) {
+                continue;
+            }
+            if (!parameter.getTypeSystemType().isGeneric()) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    public boolean hasRewrite(ProcessorContext context) {
+        if (!getExceptions().isEmpty()) {
+            return true;
+        }
+        if (!getGuards().isEmpty()) {
+            return true;
+        }
+        if (!getAssumptions().isEmpty()) {
+            return true;
+        }
+        for (ActualParameter parameter : getParameters()) {
+            NodeChildData child = getNode().findChild(parameter.getSpecification().getName());
+            if (child == null) {
+                continue;
+            }
+            ExecutableTypeData type = child.findExecutableType(context, parameter.getTypeSystemType());
+            if (type.hasUnexpectedValue(context)) {
+                return true;
+            }
+            if (type.getReturnType().getTypeSystemType().needsCastTo(context, parameter.getTypeSystemType())) {
+                return true;
+            }
+
+        }
+        return false;
+    }
+
+    @Override
+    public int compareBySignature(TemplateMethod other) {
+        if (this == other) {
+            return 0;
+        } else if (!(other instanceof SpecializationData)) {
+            return super.compareBySignature(other);
+        }
+
+        SpecializationData m2 = (SpecializationData) other;
+
+        if (getOrder() != Specialization.DEFAULT_ORDER && m2.getOrder() != Specialization.DEFAULT_ORDER) {
+            return getOrder() - m2.getOrder();
+        } else if (isUninitialized() ^ m2.isUninitialized()) {
+            return isUninitialized() ? -1 : 1;
+        } else if (isGeneric() ^ m2.isGeneric()) {
+            return isGeneric() ? 1 : -1;
+        }
+
+        if (getTemplate() != m2.getTemplate()) {
+            throw new UnsupportedOperationException("Cannot compare two specializations with different templates.");
+        }
+
+        return super.compareBySignature(m2);
+    }
+
+    public NodeData getNode() {
+        return node;
+    }
+
+    public void setNode(NodeData node) {
+        this.node = node;
+    }
+
+    public void setGuards(List<GuardData> guards) {
+        this.guards = guards;
+    }
+
+    public void setGuardDefinitions(List<String> guardDefinitions) {
+        this.guardDefinitions = guardDefinitions;
+    }
+
+    public int getOrder() {
+        return order;
+    }
+
+    public boolean isGeneric() {
+        return generic;
+    }
+
+    public boolean isUninitialized() {
+        return uninitialized;
+    }
+
+    public List<SpecializationThrowsData> getExceptions() {
+        return exceptions;
+    }
+
+    public List<String> getGuardDefinitions() {
+        return guardDefinitions;
+    }
+
+    public List<GuardData> getGuards() {
+        return guards;
+    }
+
+    public void setShortCircuits(List<ShortCircuitData> shortCircuits) {
+        this.shortCircuits = shortCircuits;
+    }
+
+    public List<ShortCircuitData> getShortCircuits() {
+        return shortCircuits;
+    }
+
+    public List<String> getAssumptions() {
+        return assumptions;
+    }
+
+    void setAssumptions(List<String> assumptions) {
+        this.assumptions = assumptions;
+    }
+
+    public SpecializationData findNextSpecialization() {
+        List<SpecializationData> specializations = node.getSpecializations();
+        for (int i = 0; i < specializations.size() - 1; i++) {
+            if (specializations.get(i) == this) {
+                return specializations.get(i + 1);
+            }
+        }
+        return null;
+    }
+
+    public boolean hasDynamicGuards() {
+        return !getGuards().isEmpty();
+    }
+
+    @Override
+    public String toString() {
+        return String.format("%s [id = %s, method = %s, guards = %s, signature = %s]", getClass().getSimpleName(), getId(), getMethod(), getGuards(), getSignature());
+    }
+
+    public void forceFrame(TypeMirror frameType) {
+        if (getParameters().isEmpty() || !Utils.typeEquals(getParameters().get(0).getType(), frameType)) {
+            ParameterSpec frameSpec = getSpecification().findParameterSpec("frame");
+            getParameters().add(0, new ActualParameter(frameSpec, frameType, -1, false));
+        }
+    }
+}