harpoon.Analysis.Realtime
Class HeapCheckAdder

java.lang.Object
  extended by harpoon.Analysis.Tree.Simplification
      extended by harpoon.Analysis.Realtime.HeapCheckAdder

public class HeapCheckAdder
extends Simplification

HeapCheckAdder adds checks to see if a NoHeapRealtimeThread is touching the heap.

Author:
Wes Beebee <wbeebee@mit.edu>

Nested Class Summary
 
Nested classes/interfaces inherited from class harpoon.Analysis.Tree.Simplification
Simplification.Rule
 
Field Summary
protected static HashSet seenList
          Have I already dealt with this instruction?
static boolean USE_LOW_BIT
          Should I use the low bit or the high bit?
 
Fields inherited from class harpoon.Analysis.Tree.Simplification
_ADD, _ALIGN, _AND, _BINOP, _CALL, _CJUMP, _CMPEQ, _CMPGE, _CMPGT, _CMPLE, _CMPLT, _CMPNE, _CONST, _CONST0, _CONST1, _CONSTm1, _CONSTNULL, _DATUM, _DIV, _ESEQ, _EXPR, _JUMP, _LABEL, _MEM, _METHOD, _MOVE, _MUL, _NAME, _NATIVECALL, _OR, _REM, _RETURN, _SEGMENT, _SEQ, _SHL, _SHR, _TEMP, _THROW, _UNOP, _USHR, _XOR
 
Constructor Summary
HeapCheckAdder()
          A heap check looks like this: *foo = bar; => heapRef1 = *foo; [env = FNI_GetJNIEnv();] [FNI_MonitorEnter(env, javax.realtime.Stats.class);] [if (javax.realtime.Stats.COLLECT_HEAP_STATS) goto CollectChecks0; else goto NoCollectChecks0;] [CollectChecks0:] [*javax.realtime.Stats.heapChecks = *javax.realtime.Stats.heapChecks + 1;] [*javax.realtime.Stats.WRITE_CHECKS = *javax.realtime.Stats.WRITE_CHECKS + 1;] [NoCollectChecks0:] if (heapRef1&1) goto NoHeap0; else goto TouchedHeap0; TouchedHeap0: [if (javax.realtime.Stats.COLLECT_HEAP_STATS) goto CollectRefs0; else goto NoCollectRefs0;] [CollectRefs0:] [*javax.realtime.Stats.heapRefs = *javax.realtime.Stats.heapRefs + 1;] [*javax.realtime.Stats.WRITE_REFS = *javax.realtime.Stats.WRITE_REFS + 1;] [NoCollectRefs0:] heapCheck(heapRef1); NoHeap0: [env = FNI_GetJNIEnv();] [FNI_MonitorExit(env, javax.realtime.Stats.class);] *foo = bar; bar = *foo; => heapRef1 = *foo; [env = FNI_GetJNIEnv();] [FNI_MonitorEnter(env, javax.realtime.Stats.class);] [if (javax.realtime.Stats.COLLECT_HEAP_STATS) goto CollectChecks0; else goto NoCollectChecks0;] [CollectChecks0:] [*javax.realtime.Stats.heapChecks = *javax.realtime.Stats.heapChecks + 1;] [*javax.realtime.Stats.READ_CHECKS = *javax.realtime.Stats.READ_CHECKS + 1;] [NoCollectChecks0:] if (heapRef1&1) goto NoHeap1; else goto TouchedHeap1; TouchedHeap1: [if (javax.realtime.Stats.COLLECT_HEAP_STATS) goto CollectRefs0; else goto NoCollectRefs0;] [CollectRefs0:] [*javax.realtime.Stats.heapRefs = *javax.realtime.Stats.heapRefs + 1;] [*javax.realtime.Stats.READ_REFS = *javax.realtime.Stats.READ_REFS + 1;] [NoCollectRefs0:] heapCheck(heapRef1); NoHeap1: [env = FNI_GetJNIEnv();] [FNI_MonitorExit(env, javax.realtime.Stats.class);] bar = heapRef1; foo = NATIVECALL(....); => heapRef1 = NATIVECALL(....); [env = FNI_GetJNIEnv();] [FNI_MonitorEnter(env, javax.realtime.Stats.class);] [if (javax.realtime.Stats.COLLECT_HEAP_STATS) goto CollectChecks0; else goto NoCollectChecks0;] [CollectChecks0:] [*javax.realtime.Stats.heapChecks = *javax.realtime.Stats.heapChecks + 1;] [*javax.realtime.Stats.NATIVECALL_CHECKS = *javax.realtime.Stats.NATIVECALL_CHECKS + 1;] [NoCollectChecks0:] if (heapRef1&1) goto NoHeap0; else goto TouchedHeap0; TouchedHeap0: [if (javax.realtime.Stats.COLLECT_HEAP_STATS) goto CollectRefs0; else goto NoCollectRefs0;] [CollectRefs0:] [*javax.realtime.Stats.heapRefs = *javax.realtime.Stats.heapRefs + 1;] [*javax.realtime.Stats.NATIVECALL_REFS = *javax.realtime.Stats.NATIVECALL_REFS + 1;] [NoCollectRefs0:] heapCheck(heapRef1); NoHeap0: [env = FNI_GetJNIEnv();] [FNI_MonitorExit(env, javax.realtime.Stats.class);] foo = heapRef1; foo = CALL(....); heapRef1 = CALL(....); [env = FNI_GetJNIEnv();] [FNI_MonitorEnter(env, javax.realtime.Stats.class);] [if (javax.realtime.Stats.COLLECT_HEAP_STATS) goto CollectChecks0; else goto NoCollectChecks0;] [CollectChecks0:] [*javax.realtime.Stats.heapChecks = *javax.realtime.Stats.heapChecks + 1;] [*javax.realtime.Stats.CALL_CHECKS = *javax.realtime.Stats.CALL_CHECKS + 1;] [NoCollectChecks0:] if (heapRef1&1) goto NoHeap0; else goto TouchedHeap0; TouchedHeap0: [if (javax.realtime.Stats.COLLECT_HEAP_STATS) goto CollectRefs0; else goto NoCollectRefs0;] [CollectRefs0:] [*javax.realtime.Stats.heapRefs = *javax.realtime.Stats.heapRefs + 1;] [*javax.realtime.Stats.CALL_REFS = *javax.realtime.Stats.CALL_REFS + 1;] [NoCollectRefs0:] heapCheck(heapRef1); NoHeap0: [env = FNI_GetJNIEnv();] [FNI_MonitorExit(env, javax.realtime.Stats.class);] foo = heapRef1; METHOD(params[]); => foreach params st. params[i] is of type POINTER: [env = FNI_GetJNIEnv();] [FNI_MonitorEnter(env, javax.realtime.Stats.class);] [if (javax.realtime.Stats.COLLECT_HEAP_STATS) goto CollectChecksi; else goto NoCollectChecksi;] [CollectChecksi:] [*javax.realtime.Stats.heapChecks = *javax.realtime.Stats.heapChecks + 1;] [*javax.realtime.Stats.METHOD_CHECKS = *javax.realtime.Stats.METHOD_CHECKS + 1;] [NoCollectChecksi:] if (params[i]&1) goto NoHeapi; else goto TouchedHeapi; TouchedHeapi: [if (javax.realtime.Stats.COLLECT_HEAP_STATS) goto CollectRefsi; else goto NoCollectRefsi;] [CollectRefsi:] [*javax.realtime.Stats.heapChecks = *javax.realtime.Stats.heapRefs + 1;] [*javax.realtime.Stats.METHOD_REFS = *javax.realtime.Stats.METHOD_REFS + 1;] [NoCollectRefsi:] heapCheck(params[i]); NoHeapi: [env = FNI_GetJNIEnv();] [FNI_MonitorExit(env, javax.realtime.Stats.class);] Isn't that awful?
 
Method Summary
protected static Stm addCheck(TreeFactory tf, Exp e, DerivationGenerator dg, Temp t, String type)
          [env = FNI_GetJNIEnv();] [FNI_MonitorEnter(env, javax.realtime.Stats.class);] [if (javax.realtime.Stats.COLLECT_HEAP_STATS) goto CollectChecks; else goto NoCollectChecks;] [CollectChecks:] [*javax.realtime.Stats.heapChecks = *javax.realtime.Stats.heapChecks + 1;] [*javax.realtime.Stats.
protected static Stm callStatsMonitor(TreeFactory tf, HCodeElement src, DerivationGenerator dg, boolean isEnter)
           
 HCodeFactory codeFactory(HCodeFactory parent)
          Code factory for adding heap checks to the given tree form.
protected static Exp DECLARE(DerivationGenerator dg, Derivation.DList dl, Exp exp)
          Declare a derived pointer.
protected static Exp DECLARE(DerivationGenerator dg, HClass hc, Exp exp)
          Declare the type of an expression.
protected static Exp DECLARE(DerivationGenerator dg, HClass hc, Temp t, Exp exp)
          Declare the type of an expression and the variable associated with it.
protected static MEM fieldRef(TreeFactory tf, HCodeElement e, DerivationGenerator dg, HClass type, int iType, String className, String fieldName)
          foo.bar
protected static Label forField(TreeFactory tf, String className, String fieldName)
          foo.bar
protected static Stm incLongField(TreeFactory tf, HCodeElement e, DerivationGenerator dg, String className, String fieldName)
          foo.bar = *foo.bar + 1;
protected static MEM memRef(TreeFactory tf, MEM e, DerivationGenerator dg, Temp t)
          (t&(~3)), now *t
protected static NATIVECALL nativeCall(TreeFactory tf, Exp e, DerivationGenerator dg, Temp t, String func_name, String type)
          func_name(t)
protected static TEMP tempRef(DerivationGenerator dg, TreeFactory tf, Exp e, Temp t)
          t
protected static Exp UPDATE(DerivationGenerator dg, Exp oldExp, Exp newExp)
           
 
Methods inherited from class harpoon.Analysis.Tree.Simplification
_KIND, _OP, codeFactory, contains, simplify
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

seenList

protected static HashSet seenList
Have I already dealt with this instruction?


USE_LOW_BIT

public static boolean USE_LOW_BIT
Should I use the low bit or the high bit?

Constructor Detail

HeapCheckAdder

public HeapCheckAdder()
A heap check looks like this: *foo = bar; => heapRef1 = *foo; [env = FNI_GetJNIEnv();] [FNI_MonitorEnter(env, javax.realtime.Stats.class);] [if (javax.realtime.Stats.COLLECT_HEAP_STATS) goto CollectChecks0; else goto NoCollectChecks0;] [CollectChecks0:] [*javax.realtime.Stats.heapChecks = *javax.realtime.Stats.heapChecks + 1;] [*javax.realtime.Stats.WRITE_CHECKS = *javax.realtime.Stats.WRITE_CHECKS + 1;] [NoCollectChecks0:] if (heapRef1&1) goto NoHeap0; else goto TouchedHeap0; TouchedHeap0: [if (javax.realtime.Stats.COLLECT_HEAP_STATS) goto CollectRefs0; else goto NoCollectRefs0;] [CollectRefs0:] [*javax.realtime.Stats.heapRefs = *javax.realtime.Stats.heapRefs + 1;] [*javax.realtime.Stats.WRITE_REFS = *javax.realtime.Stats.WRITE_REFS + 1;] [NoCollectRefs0:] heapCheck(heapRef1); NoHeap0: [env = FNI_GetJNIEnv();] [FNI_MonitorExit(env, javax.realtime.Stats.class);] *foo = bar; bar = *foo; => heapRef1 = *foo; [env = FNI_GetJNIEnv();] [FNI_MonitorEnter(env, javax.realtime.Stats.class);] [if (javax.realtime.Stats.COLLECT_HEAP_STATS) goto CollectChecks0; else goto NoCollectChecks0;] [CollectChecks0:] [*javax.realtime.Stats.heapChecks = *javax.realtime.Stats.heapChecks + 1;] [*javax.realtime.Stats.READ_CHECKS = *javax.realtime.Stats.READ_CHECKS + 1;] [NoCollectChecks0:] if (heapRef1&1) goto NoHeap1; else goto TouchedHeap1; TouchedHeap1: [if (javax.realtime.Stats.COLLECT_HEAP_STATS) goto CollectRefs0; else goto NoCollectRefs0;] [CollectRefs0:] [*javax.realtime.Stats.heapRefs = *javax.realtime.Stats.heapRefs + 1;] [*javax.realtime.Stats.READ_REFS = *javax.realtime.Stats.READ_REFS + 1;] [NoCollectRefs0:] heapCheck(heapRef1); NoHeap1: [env = FNI_GetJNIEnv();] [FNI_MonitorExit(env, javax.realtime.Stats.class);] bar = heapRef1; foo = NATIVECALL(....); => heapRef1 = NATIVECALL(....); [env = FNI_GetJNIEnv();] [FNI_MonitorEnter(env, javax.realtime.Stats.class);] [if (javax.realtime.Stats.COLLECT_HEAP_STATS) goto CollectChecks0; else goto NoCollectChecks0;] [CollectChecks0:] [*javax.realtime.Stats.heapChecks = *javax.realtime.Stats.heapChecks + 1;] [*javax.realtime.Stats.NATIVECALL_CHECKS = *javax.realtime.Stats.NATIVECALL_CHECKS + 1;] [NoCollectChecks0:] if (heapRef1&1) goto NoHeap0; else goto TouchedHeap0; TouchedHeap0: [if (javax.realtime.Stats.COLLECT_HEAP_STATS) goto CollectRefs0; else goto NoCollectRefs0;] [CollectRefs0:] [*javax.realtime.Stats.heapRefs = *javax.realtime.Stats.heapRefs + 1;] [*javax.realtime.Stats.NATIVECALL_REFS = *javax.realtime.Stats.NATIVECALL_REFS + 1;] [NoCollectRefs0:] heapCheck(heapRef1); NoHeap0: [env = FNI_GetJNIEnv();] [FNI_MonitorExit(env, javax.realtime.Stats.class);] foo = heapRef1; foo = CALL(....); heapRef1 = CALL(....); [env = FNI_GetJNIEnv();] [FNI_MonitorEnter(env, javax.realtime.Stats.class);] [if (javax.realtime.Stats.COLLECT_HEAP_STATS) goto CollectChecks0; else goto NoCollectChecks0;] [CollectChecks0:] [*javax.realtime.Stats.heapChecks = *javax.realtime.Stats.heapChecks + 1;] [*javax.realtime.Stats.CALL_CHECKS = *javax.realtime.Stats.CALL_CHECKS + 1;] [NoCollectChecks0:] if (heapRef1&1) goto NoHeap0; else goto TouchedHeap0; TouchedHeap0: [if (javax.realtime.Stats.COLLECT_HEAP_STATS) goto CollectRefs0; else goto NoCollectRefs0;] [CollectRefs0:] [*javax.realtime.Stats.heapRefs = *javax.realtime.Stats.heapRefs + 1;] [*javax.realtime.Stats.CALL_REFS = *javax.realtime.Stats.CALL_REFS + 1;] [NoCollectRefs0:] heapCheck(heapRef1); NoHeap0: [env = FNI_GetJNIEnv();] [FNI_MonitorExit(env, javax.realtime.Stats.class);] foo = heapRef1; METHOD(params[]); => foreach params st. params[i] is of type POINTER: [env = FNI_GetJNIEnv();] [FNI_MonitorEnter(env, javax.realtime.Stats.class);] [if (javax.realtime.Stats.COLLECT_HEAP_STATS) goto CollectChecksi; else goto NoCollectChecksi;] [CollectChecksi:] [*javax.realtime.Stats.heapChecks = *javax.realtime.Stats.heapChecks + 1;] [*javax.realtime.Stats.METHOD_CHECKS = *javax.realtime.Stats.METHOD_CHECKS + 1;] [NoCollectChecksi:] if (params[i]&1) goto NoHeapi; else goto TouchedHeapi; TouchedHeapi: [if (javax.realtime.Stats.COLLECT_HEAP_STATS) goto CollectRefsi; else goto NoCollectRefsi;] [CollectRefsi:] [*javax.realtime.Stats.heapChecks = *javax.realtime.Stats.heapRefs + 1;] [*javax.realtime.Stats.METHOD_REFS = *javax.realtime.Stats.METHOD_REFS + 1;] [NoCollectRefsi:] heapCheck(params[i]); NoHeapi: [env = FNI_GetJNIEnv();] [FNI_MonitorExit(env, javax.realtime.Stats.class);] Isn't that awful? - On load (of a base POINTER) - On method call (check formal parameters if POINTER) - Return of a method CALL if POINTER - Return of a NATIVECALL if POINTER - On store (of POINTER type) (possible clobbering of a root during GC ref. forwarding may clobber newly stored value).

Method Detail

addCheck

protected static Stm addCheck(TreeFactory tf,
                              Exp e,
                              DerivationGenerator dg,
                              Temp t,
                              String type)
[env = FNI_GetJNIEnv();] [FNI_MonitorEnter(env, javax.realtime.Stats.class);] [if (javax.realtime.Stats.COLLECT_HEAP_STATS) goto CollectChecks; else goto NoCollectChecks;] [CollectChecks:] [*javax.realtime.Stats.heapChecks = *javax.realtime.Stats.heapChecks + 1;] [*javax.realtime.Stats.##type##Checks = *javax.realtime.Stats.##type##Checks + 1;] [NoCollectChecks:] if (t&1) goto NoHeap; else goto TouchedHeap; TouchedHeap: [if (javax.realtime.Stats.COLLECT_HEAP_STATS) goto CollectRefs; else goto NoCollectRefs;] [CollectRefs:] [*javax.realtime.Stats.heapRefs = *javax.realtime.Stats.heapRefs + 1;] [*javax.realtime.Stats.##type##Refs = *javax.realtime.Stats.##type##Refs + 1;] [NoCollectRefs:] heapCheck(t); NoHeap: [env = FNI_GetJNIEnv();] [FNI_MonitorExit(env, javax.realtime.Stats.class);]


callStatsMonitor

protected static Stm callStatsMonitor(TreeFactory tf,
                                      HCodeElement src,
                                      DerivationGenerator dg,
                                      boolean isEnter)

incLongField

protected static Stm incLongField(TreeFactory tf,
                                  HCodeElement e,
                                  DerivationGenerator dg,
                                  String className,
                                  String fieldName)
foo.bar = *foo.bar + 1;


fieldRef

protected static MEM fieldRef(TreeFactory tf,
                              HCodeElement e,
                              DerivationGenerator dg,
                              HClass type,
                              int iType,
                              String className,
                              String fieldName)
foo.bar


forField

protected static Label forField(TreeFactory tf,
                                String className,
                                String fieldName)
foo.bar


nativeCall

protected static NATIVECALL nativeCall(TreeFactory tf,
                                       Exp e,
                                       DerivationGenerator dg,
                                       Temp t,
                                       String func_name,
                                       String type)
func_name(t)


memRef

protected static MEM memRef(TreeFactory tf,
                            MEM e,
                            DerivationGenerator dg,
                            Temp t)
(t&(~3)), now *t


tempRef

protected static TEMP tempRef(DerivationGenerator dg,
                              TreeFactory tf,
                              Exp e,
                              Temp t)
t


codeFactory

public HCodeFactory codeFactory(HCodeFactory parent)
Code factory for adding heap checks to the given tree form. Clones the tree before processing it in-place.


DECLARE

protected static Exp DECLARE(DerivationGenerator dg,
                             HClass hc,
                             Exp exp)
Declare the type of an expression.


DECLARE

protected static Exp DECLARE(DerivationGenerator dg,
                             HClass hc,
                             Temp t,
                             Exp exp)
Declare the type of an expression and the variable associated with it.


DECLARE

protected static Exp DECLARE(DerivationGenerator dg,
                             Derivation.DList dl,
                             Exp exp)
Declare a derived pointer.


UPDATE

protected static Exp UPDATE(DerivationGenerator dg,
                            Exp oldExp,
                            Exp newExp)