Use Java based table-switch for type switches
Predicates that use different clauses for different types of terms use
a type switch on the first argument/register. Rewrite this as a
proper table switch in Java so the JVM can emit an efficient switch
statement. Use a virtual method and lightweight ints enumerated from
0 to N in the order the switch was previously written in to get an
efficient implementation for the JIT.
Change-Id: If7274ec8776479afe70bbec0882768d7a28b4c64
diff --git a/src/lang/ClosureTerm.java b/src/lang/ClosureTerm.java
index 001f509..053035c 100644
--- a/src/lang/ClosureTerm.java
+++ b/src/lang/ClosureTerm.java
@@ -18,7 +18,11 @@
/** Returns the Prolog goal of this <code>ClosureTerm</code>. */
public Predicate getCode() { return code; }
- /* Term */
+ @Override
+ public int type() {
+ return TYPE_CLOSURE;
+ }
+
public boolean unify(Term t, Trail trail) {
// t = t.dereference();
if (t instanceof VariableTerm)
diff --git a/src/lang/DoubleTerm.java b/src/lang/DoubleTerm.java
index 588d815..dbb80f7 100644
--- a/src/lang/DoubleTerm.java
+++ b/src/lang/DoubleTerm.java
@@ -33,7 +33,11 @@
*/
public double value() { return val; }
- /* Term */
+ @Override
+ public int type() {
+ return TYPE_DOUBLE;
+ }
+
public boolean unify(Term t, Trail trail) {
if (t instanceof VariableTerm)
return ((VariableTerm)t).unify(this, trail);
diff --git a/src/lang/IntegerTerm.java b/src/lang/IntegerTerm.java
index e64c9b0..d9e1596 100644
--- a/src/lang/IntegerTerm.java
+++ b/src/lang/IntegerTerm.java
@@ -29,6 +29,11 @@
*/
public int value() { return val; }
+ @Override
+ public int type() {
+ return TYPE_INTEGER;
+ }
+
/* Term */
public boolean unify(Term t, Trail trail) {
if (t instanceof VariableTerm)
diff --git a/src/lang/JavaObjectTerm.java b/src/lang/JavaObjectTerm.java
index 3076f80..89c946f 100644
--- a/src/lang/JavaObjectTerm.java
+++ b/src/lang/JavaObjectTerm.java
@@ -37,7 +37,11 @@
public String toQuotedString() { return toString(); }
- /* Term */
+ @Override
+ public int type() {
+ return TYPE_JAVA_OBJECT;
+ }
+
public boolean unify(Term t, Trail trail) {
if (t instanceof VariableTerm)
return ((VariableTerm)t).unify(this, trail);
diff --git a/src/lang/ListTerm.java b/src/lang/ListTerm.java
index 5d733db..e1ead71 100644
--- a/src/lang/ListTerm.java
+++ b/src/lang/ListTerm.java
@@ -75,6 +75,11 @@
*/
public void setCdr(Term t) { cdr = t; }
+ @Override
+ public int type() {
+ return TYPE_LIST;
+ }
+
/* Term */
public boolean unify(Term t, Trail trail) {
t = t.dereference();
diff --git a/src/lang/Prolog.java b/src/lang/Prolog.java
index e3c059b..be73553 100644
--- a/src/lang/Prolog.java
+++ b/src/lang/Prolog.java
@@ -206,20 +206,22 @@
Operation con,
Operation str,
Operation lis) {
- Term arg1 = r1.dereference();
- if (arg1 instanceof VariableTerm)
- return var;
- if (arg1 instanceof IntegerTerm)
- return Int;
- if (arg1 instanceof DoubleTerm)
- return flo;
- if (arg1 instanceof SymbolTerm)
- return con;
- if (arg1 instanceof StructureTerm)
- return str;
- if (arg1 instanceof ListTerm)
- return lis;
- return var;
+ switch (r1.dereference().type()) {
+ case Term.TYPE_VARIABLE:
+ return var;
+ case Term.TYPE_INTEGER:
+ return Int;
+ case Term.TYPE_DOUBLE:
+ return flo;
+ case Term.TYPE_SYMBOL:
+ return con;
+ case Term.TYPE_STRUCTURE:
+ return str;
+ case Term.TYPE_LIST:
+ return lis;
+ default:
+ return var;
+ }
}
/**
diff --git a/src/lang/StructureTerm.java b/src/lang/StructureTerm.java
index cfd9c12..17e8864 100644
--- a/src/lang/StructureTerm.java
+++ b/src/lang/StructureTerm.java
@@ -78,6 +78,11 @@
public Term arg(int nth) { return args[nth]; }
+ @Override
+ public int type() {
+ return TYPE_STRUCTURE;
+ }
+
public boolean unify(Term t, Trail trail) {
t = t.dereference();
if (t instanceof VariableTerm) {
diff --git a/src/lang/SymbolTerm.java b/src/lang/SymbolTerm.java
index 347a103..9c6e4cf 100644
--- a/src/lang/SymbolTerm.java
+++ b/src/lang/SymbolTerm.java
@@ -179,7 +179,11 @@
*/
public String name() { return name; }
- /* Term */
+ @Override
+ public int type() {
+ return TYPE_SYMBOL;
+ }
+
public boolean unify(Term t, Trail trail) {
t = t.dereference();
if (t instanceof VariableTerm) {
diff --git a/src/lang/Term.java b/src/lang/Term.java
index 960e156..c3e86c1 100644
--- a/src/lang/Term.java
+++ b/src/lang/Term.java
@@ -17,6 +17,18 @@
/** Holds an integer value <code>-1</code>. */
public static final int BEFORE = -1;
+ public static final int TYPE_VARIABLE = 0;
+ public static final int TYPE_INTEGER = 1;
+ public static final int TYPE_DOUBLE = 2;
+ public static final int TYPE_SYMBOL = 3;
+ public static final int TYPE_STRUCTURE = 4;
+ public static final int TYPE_LIST = 5;
+ public static final int TYPE_CLOSURE = 6;
+ public static final int TYPE_JAVA_OBJECT = 7;
+
+ /** One of the {@code TYPE_*} constants from {@code Term}. */
+ public abstract int type();
+
/**
* Checks whether the argument term is unified with this one.
* @param t the term to be unified with.
diff --git a/src/lang/VariableTerm.java b/src/lang/VariableTerm.java
index 3cfd339..5bb4085 100644
--- a/src/lang/VariableTerm.java
+++ b/src/lang/VariableTerm.java
@@ -42,7 +42,11 @@
/** Returns a string representation of this object.*/
protected String variableName() { return "_" + Integer.toHexString(hashCode()).toUpperCase(); }
- /* Term */
+ @Override
+ public int type() {
+ return TYPE_VARIABLE;
+ }
+
/**
* Checks whether the argument term is unified with this one.
* If this is an unbound variable, the <code>unify</code> method binds this to