/*
This file is part of JOP, the Java Optimized Processor
see <http://www.jopdesign.com/>
Copyright (C) 2010, Benedikt Huber (benedikt.huber@gmail.com)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program 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 for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* Autogenerated using ERB (tiny ruby, part of ruby distributions) */
/* erb LoadOnReturn.erb > LoadOnReturn.java */
package wcet.devel;
import com.jopdesign.sys.Config;
import com.jopdesign.sys.Const;
import com.jopdesign.sys.Native;
public class ObjectCache {
static int ts, te, to;
static int cs, ce;
/* classes */
public abstract static class Obj1 {
/* self references */
public Obj1 next;
public Obj1[] preds;
/* down references */
public Obj2 sub1;
public Obj3 sub2;
public Obj3[] subs;
/* primitive array and fields */
public int val;
public int[] vals;
public long lval;
public long[] lvals;
public static Obj1 create() {
if(to > 10) return new Obj1a();
else if(to>12) return new Obj1b();
else return new Obj1c();
}
public int test2(Obj1 other, Obj2 sub) {
int v1 = this.next.val; // GF: $this, $this.next
int v2 = other.next.val; // GF: $arg0, $arg0.next
Obj2 ssub = this.selectSub2(other,sub); // ssub = {$0.sub1,$0.next.next.sub1, // Obj1a
// $1.sub1, $1.next.next.sub1, // Obj1b
// $2 } // both
int v3 = ssub.val; // GF: ssub.val
return v1+v2+v3;
}
protected abstract Obj2 selectSub2(Obj1 other, Obj2 def);
}
public static class Obj1a extends Obj1 {
protected Obj2 selectSub2(Obj1 other, Obj2 def) {
Obj2 selected;
if(te > 5) selected = this.sub1;
else if(te > 7) selected = this.next.next.sub1;
else selected = def;
return selected;
}
}
public static class Obj1b extends Obj1 {
protected Obj2 selectSub2(Obj1 other, Obj2 def) {
Obj2 selected;
if(te > 10) selected = other.sub1;
else if(te > 12) selected = other.next.next.sub1;
else selected = def;
return selected;
}
}
public static class Obj1c extends Obj1 {
protected Obj2 selectSub2(Obj1 other, Obj2 def) {
return null;
}
}
public static class Obj2 {
/* primitive array and fields */
public int val;
public int[] vals;
public long lval;
public long[] lvals;
}
public static class Obj3 {
/* primitive array and fields */
public int val;
public int[] vals;
public long lval;
public long[] lvals;
}
/* static references */
static Obj1 obj1a, obj1b;
static Obj2 obj2a, obj2b;
static Obj3 obj3a, obj3b;
/* static arrays */
static int ptr = 0;
static Obj2[] obj2s;
static Obj3[] obj3s;
public static void init()
{
obj1a = Obj1.create(); obj1b = Obj1.create();
obj2a = new Obj2(); obj2b = new Obj2();
obj3a = new Obj3(); obj3b = new Obj3();
obj1a.sub1 = obj2a; obj1b.sub1 = obj2a;
obj1a.sub2 = obj3a; obj1b.sub2 = obj3b;
obj2s = new Obj2[5];
obj3s = new Obj3[7];
}
public static void main(String[] args) {
ts = Native.rdMem(Const.IO_CNT);
te = Native.rdMem(Const.IO_CNT);
to = te-ts;
init();
int v = invoke();
System.out.print("Value: ");
System.out.print(v);
int val = te-ts-to;
int cacheCost = ce-cs;
}
static int invoke() {
if (Config.MEASURE) te = Native.rdMem(Const.IO_CNT);
return measure();
}
static int measure() {
if (Config.MEASURE) ts = Native.rdMem(Const.IO_CNT);
int val = 0;
val += test1();
val += test2();
val += test3();
val += test5();
val += test5();
val += test5();
return val;
}
/* test1: access field of one out of two static objects */
static int test1() {
Obj1 obj1;
if(to > 10) {
obj1 = obj1a;
} else {
obj1 = obj1b;
}
return obj1.sub1.val + obj1.sub2.val;
}
static int test2() {
return obj1a.test2(obj1b,obj2a);
}
// here the number of objects accesses is unbounded [assuming unknown loop
// bounds] in the second part
static int test3() {
Obj1 obj1;
if(to > 10) {
obj1 = obj1a;
} else {
obj1 = obj1b;
}
int v = obj1.val; // {obj1a,ojb1b}.val
Obj1 obj1a = obj1.next; // {obj1a,obj1b}.next
for(int i = 0; i < 100; i++) { //@WCA loop = 100
if(obj1.sub1.val > 0) v += obj1.sub1.val; // top * 4
else v *= obj1a.sub1.val; // obj1a, obj1a.sub1
obj1 = obj1.next; // top
}
return v;
}
// Enhanced bug test case from wolfgang (5.1.2010)
static int test4() {
int v = obj1a.next.val; // GF: obj1a, obj1a.next
if(v == to) obj1a.next = obj1b; // heap modification -> TOP
return v+obj1a.next.val; // GF: top, top
}
static int test5() {
Obj2 x = obj2s[ptr++];
if(ptr == 5) ptr = 0;
Obj2 y = obj2s[ptr++];
if(ptr == 5) ptr = 0;
return x.val
+y.val;
}
}