aa
Types.java
Go to the documentation of this file.
1 package com.cliffc.aa.type;
2 
3 import com.cliffc.aa.util.Ary;
4 import com.cliffc.aa.util.IHashMap;
5 import java.util.Arrays;
6 
7 // Class to make hashcons Type[].
8 // Bug to change after interning.
9 public class Types {
10  // Lazy expanding list of TypeAry customed to handle various Type[] lengths.
11  private static final Ary<Types> TYPEARY = new Ary<>(new Types[1],0);
12 
13  // Make a TypeAry to handle Type[] of length 'len'
14  private static Types tary( int len) {
15  Types tary = TYPEARY.atX(len);
16  return tary==null ? TYPEARY.setX(len,new Types(len)) : tary;
17  }
18 
19  private static final Key K = new Key(null,0);
20 
21  // Wrapper to customize array.equals
22  private static class Key {
23  Type[] _ts;
24  int _hash;
25  private Key(Type[] ts, int hash) { _ts=ts; _hash = hash; }
26  private static int hash( Type[] ts ) {
27  int hash = 0;
28  for( Type t : ts ) hash += t._hash;
29  return hash;
30  }
31  @Override public int hashCode() { return _hash; }
32  @Override public boolean equals(Object o) {
33  if( !(o instanceof Key) ) return false;
34  Type[] ts = ((Key)o)._ts;
35  // This series of tests is NOT the same as Arrays.equals(), since it
36  // bottoms out in a pointer-equality test instead of 'equals'.
37  if( _ts==ts ) return true;
38  if( _ts.length != ts.length ) return false;
39  for( int i=0; i<ts.length; i++ )
40  if( _ts[i]!=ts[i] )
41  return false;
42  return true;
43  }
44  }
45 
46  private final int _len; // Length of arrays being handled
47  private final IHashMap _intern = new IHashMap();
48  private final Ary<Type[]> _free = new Ary<>(new Type[1][],0);
49  private Types( int len ) { _len=len; }
50 
51  private Types check() { assert check_(); return this; }
52  private boolean check_() {
53  //for( Object k : _intern.keySet() )
54  // assert Key.hash(((Key)k)._ts)==((Key)k)._hash; // Basically asserting array not hacked
55  return true;
56  }
57  private boolean check_(Type[] ts) {
58  K._ts=ts;
59  K._hash = Key.hash(ts);
60  Key k2 = _intern.get(K);
61  return k2._ts==ts;
62  }
63 
64 
65  // Return a free Type[]
66  private Type[] get() {
67  if( _free.isEmpty() )
68  _free.push(new Type[_len]);
69  return _free.pop();
70  }
71 
72  private Type[] hash_cons_(Type[] ts) {
73  K._ts=ts;
74  K._hash = Key.hash(ts);
75  Key k2 = _intern.get(K);
76  if( k2 != null ) {
77  if( k2._ts!=ts ) _free.push(ts);
78  return k2._ts;
79  }
80  _intern.put(new Key(ts,K._hash));
81  return ts;
82  }
83 
84  public static Type[] get(int len) { return tary(len).check().get(); }
85  public static void free(Type[] ts) { tary(ts.length)._free.push(ts); }
86  public static Type[] hash_cons(Type[] ts) { return tary(ts.length).check().hash_cons_(ts); }
87  // Why is this API not auto-interning? Because it is used to make cyclic
88  // types in TypeStructs, which means the fields will change over
89  // time... until the intern point.
90  public static Type[] ts(Type t0) {
91  Types t1 = tary(1).check();
92  Type[] ts = t1.get();
93  ts[0] = t0;
94  return ts;
95  }
96  public static Type[] ts(Type t0, Type t1) {
97  Types t2 = tary(2).check();
98  Type[] ts = t2.get();
99  ts[0] = t0;
100  ts[1] = t1;
101  return ts;
102  }
103  public static Type[] ts(Type t0, Type t1, Type t2) {
104  Types t3 = tary(3).check();
105  Type[] ts = t3.get();
106  ts[0] = t0;
107  ts[1] = t1;
108  ts[2] = t2;
109  return ts;
110  }
111  public static Type[] ts(Type t0, Type t1, Type t2, Type t3) {
112  Types t4 = tary(4).check();
113  Type[] ts = t4.get();
114  ts[0] = t0;
115  ts[1] = t1;
116  ts[2] = t2;
117  ts[3] = t3;
118  return ts;
119  }
120  public static Type[] ts(Type t0, Type t1, Type t2, Type t3, Type t4) {
121  Types t5 = tary(5).check();
122  Type[] ts = t5.get();
123  ts[0] = t0;
124  ts[1] = t1;
125  ts[2] = t2;
126  ts[3] = t3;
127  ts[4] = t4;
128  return ts;
129  }
130  public static Type[] ts(Type t0, Type t1, Type t2, Type t3, Type t4, Type t5) {
131  Types t6 = tary(6).check();
132  Type[] ts = t6.get();
133  ts[0] = t0;
134  ts[1] = t1;
135  ts[2] = t2;
136  ts[3] = t3;
137  ts[4] = t4;
138  ts[5] = t5;
139  return ts;
140  }
141 
142  // Result not interned; suitable for direct hacking.
143  // Original assumed in-use, not freed.
144  public static Type[] clone(Type[] ts) {
145  Type[] ts2 = tary(ts.length).check().get();
146  System.arraycopy(ts,0,ts2,0,ts.length);
147  return ts2;
148  }
149  // Result not interned; suitable for direct hacking.
150  // Original assumed in-use, not freed.
151  public static Type[] copyOf(Type[] ts, int len) {
152  Type[] ts2 = tary(len).check().get();
153  int minlen = Math.min(len,ts.length);
154  System.arraycopy(ts,0,ts2,0,minlen);
155  Arrays.fill(ts2,minlen,len,null);
156  return ts2;
157  }
158  public static boolean eq( Type[] ts0, Type[] ts1 ) {
159  if( ts0==ts1 ) return true;
160  if( ts0==null || ts1==null ) return false;
161  //assert tary(ts0.length).check().check_(ts0);
162  //assert ts0.length == ts1.length || tary(ts1.length).check().check_(ts1);
163  return false; // No need for deep check, since interned
164  }
165 }
com.cliffc.aa.util.IHashMap.get
public< T > T get(T key)
Definition: IHashMap.java:11
com.cliffc.aa.type.Types.Key._ts
Type[] _ts
Definition: Types.java:23
com.cliffc
com.cliffc.aa.type.Types.eq
static boolean eq(Type[] ts0, Type[] ts1)
Definition: Types.java:158
com.cliffc.aa.util
Definition: AbstractEntry.java:1
com.cliffc.aa.type.Types.ts
static Type[] ts(Type t0, Type t1)
Definition: Types.java:96
com.cliffc.aa.type.Types.check
Types check()
Definition: Types.java:51
com.cliffc.aa.type.Type
an implementation of language AA
Definition: Type.java:94
com.cliffc.aa.util.Ary
Definition: Ary.java:11
com.cliffc.aa.util.IHashMap
Definition: IHashMap.java:7
com.cliffc.aa.type.Types.ts
static Type[] ts(Type t0, Type t1, Type t2, Type t3, Type t4)
Definition: Types.java:120
com.cliffc.aa.type.Types.ts
static Type[] ts(Type t0, Type t1, Type t2, Type t3)
Definition: Types.java:111
com.cliffc.aa.type.Types._len
final int _len
Definition: Types.java:46
com.cliffc.aa.type.Types.free
static void free(Type[] ts)
Definition: Types.java:85
com.cliffc.aa.type.Types.hash_cons
static Type[] hash_cons(Type[] ts)
Definition: Types.java:86
com.cliffc.aa.type.Types
Definition: Types.java:9
com.cliffc.aa.type.Types.check_
boolean check_(Type[] ts)
Definition: Types.java:57
com.cliffc.aa.type.Types.ts
static Type[] ts(Type t0)
Definition: Types.java:90
com.cliffc.aa.type.Types.Key._hash
int _hash
Definition: Types.java:24
com.cliffc.aa.type.Types._intern
final IHashMap _intern
Definition: Types.java:47
com.cliffc.aa.type.Types.clone
static Type[] clone(Type[] ts)
Definition: Types.java:144
com.cliffc.aa.type.Types.tary
static Types tary(int len)
Definition: Types.java:14
com.cliffc.aa.type.Types._free
final Ary< Type[]> _free
Definition: Types.java:48
com.cliffc.aa.type.Types.ts
static Type[] ts(Type t0, Type t1, Type t2, Type t3, Type t4, Type t5)
Definition: Types.java:130
com.cliffc.aa.type.Types.copyOf
static Type[] copyOf(Type[] ts, int len)
Definition: Types.java:151
com.cliffc.aa.type.Types.get
Type[] get()
Definition: Types.java:66
com.cliffc.aa.type.Types.K
static final Key K
Definition: Types.java:19
com.cliffc.aa.type.Types.Key.Key
Key(Type[] ts, int hash)
Definition: Types.java:25
com.cliffc.aa.type.Types.Types
Types(int len)
Definition: Types.java:49
com.cliffc.aa.type.Types.hash_cons_
Type[] hash_cons_(Type[] ts)
Definition: Types.java:72
com.cliffc.aa
Definition: AA.java:1
com.cliffc.aa.type.Types.Key.hash
static int hash(Type[] ts)
Definition: Types.java:26
com.cliffc.aa.type.Types.check_
boolean check_()
Definition: Types.java:52
com.cliffc.aa.type.Types.Key
Definition: Types.java:22
com.cliffc.aa.type.Types.TYPEARY
static final Ary< Types > TYPEARY
Definition: Types.java:11
com.cliffc.aa.type.Types.Key.equals
boolean equals(Object o)
Definition: Types.java:32
com.cliffc.aa.type.Types.Key.hashCode
int hashCode()
Definition: Types.java:31
com
com.cliffc.aa.util.IHashMap.put
public< T > T put(T kv)
Definition: IHashMap.java:9
com.cliffc.aa.type.Types.ts
static Type[] ts(Type t0, Type t1, Type t2)
Definition: Types.java:103