package com.jopdesign.tools; public class ObjectCacheSim { private static final boolean CACHE_SINGLE_FIELDS = System.getenv("WCET_CACHE_FIELDS_ONLY") != null; private int assoc; private ObjectCacheStat stats; private int osize; private int[] tags; public static class ObjectCacheStat { public int missCount = 0, accessCount = 0; public void reset() { missCount = 0; accessCount = 0; } } public ObjectCacheSim(int assoc, int osize) { this.assoc = assoc; this.osize = osize; this.stats = new ObjectCacheStat(); this.tags = new int[assoc]; for(int i = 0; i < assoc; i++) tags[i] = 0; } public void accessField(int ref, int off) { int addr; if(CACHE_SINGLE_FIELDS) addr = ref+off; else addr = ref; this.stats.accessCount++; if(! CACHE_SINGLE_FIELDS && off > osize) { stats.missCount++; return; } if(! isCached(addr)) { stats.missCount++; } loadObject(addr); } // 0 is first entry private void loadObject(int ref) { if(tags[0] == ref) return; int i = 0; int floating = ref; // Invariant: 'floating' needs to be stored somewhere do { int tmp = tags[i]; tags[i] = floating; floating = tmp; i++; } while(i < assoc && tags[i] != ref); if(i < assoc) { // tags[i] = ref tags[i] = floating; } } private boolean isCached(int ref) { for(int i = 0; i < assoc; i++) { if(tags [i] == ref) return true; } return false; } public void resetStats() { stats.reset(); } public ObjectCacheStat getStats() { return stats; } public void flushCache() { resetStats(); for(int i = 0; i < assoc; i++) tags[i] = 0; } public void dumpStats() { int ac = stats.accessCount; int mc = stats.missCount; System.out.println( String.format("Object Cache: Assoc: %d, Access: %d, Miss: %d, Ration: %.2f %%", assoc, ac,mc,(double)(ac-mc)/(double)(ac)*100.0)); } }