public Frame(HMethod main) { super(); linker = main.getDeclaringClass().getLinker(); tempBuilder = new TempBuilder(); regFileInfo = new RegFileInfo(tempBuilder); instrBuilder = new InstrBuilder(regFileInfo, tempBuilder); harpoon.Backend.Runtime1.AllocationStrategy as = new harpoon.Backend.Runtime1.MallocAllocationStrategy(this, "malloc"); runtime = new harpoon.Backend.Runtime1.Runtime(this, as, main, false); codegen = new CodeGen(this); }
/** * @return the offset of of <code>hm</code> from the initial method. For instance, if <code>hm * </code> is the 3rd method in its class, <code>getMethodOffset()</code> returns 2. */ public int getMethodOffset(HMethod hm) { return m_hcim.get(hm.getDeclaringClass()).getOffset(hm); }
/** Is this a super constructor? Safe to return false if unsure. */ private boolean isSuperConstructor(HMethod hm, HCodeElement me) { return isConstructor(hm) && // assumes this method is precise. hm.getDeclaringClass() .equals(((Quad) me).getFactory().getMethod().getDeclaringClass().getSuperclass()); }
/** returns a map from hfields to classification objects */ private Map doOne(HCode hc) { Map map = mf.makeMap(); HMethod hm = hc.getMethod(); assert isConstructor(hm); HClass thisClass = hm.getDeclaringClass(); // first, get a SimpleConstMap ConstMap cm = new SimpleConstMap(hc); // also create a MustParamOracle MustParamOracle mpo = new MustParamOracle(hc); // look at every SET and CALL. for (Iterator it = hc.getElementsI(); it.hasNext(); ) { Quad q = (Quad) it.next(); if (q instanceof SET) { SET qq = (SET) q; // field set. if (qq.field().getDeclaringClass().equals(thisClass)) { Classification oc = (Classification) map.get(qq.field()); // okay, is the value we're setting a constant? or param? Classification nc = makeClassification(cm, mpo, qq, qq.src()); // XXX: CAN MERGE const with param if the const is // the 'right' value (the one we're optimizing for) if (oc != null) // null means we haven't seen this field yet. nc.merge(oc); map.put(qq.field(), nc); } } if (q instanceof CALL) { // deal with call to 'this' constructor. CALL qq = (CALL) q; if (isThisConstructor(qq.method(), qq)) { // recursively invoke! Map m = classifyMethod(qq.method()); // this should cache. // construct parameter mapping. Classification pc[] = new Classification[qq.paramsLength()]; for (int i = 0; i < pc.length; i++) pc[i] = makeClassification(cm, mpo, qq, qq.params(i)); // filter method's classifications through the mapping and // merge with our previous classifications. for (Iterator it2 = m.entrySet().iterator(); it2.hasNext(); ) { Map.Entry me = (Map.Entry) it2.next(); HField hf = (HField) me.getKey(); Classification oc = (Classification) map.get(hf); Classification nc = (Classification) me.getValue(); // clone nc so we don't modify value in 'm'! nc = (Classification) nc.clone(); // map method's params to this' params. nc.map(pc); if (oc != null) nc.merge(oc); // merge if necessary. map.put(hf, nc); } } } } // collect statistics. if (STATISTICS) { boolean has_const = false, has_param = false; for (Iterator it = map.values().iterator(); it.hasNext(); ) { Classification c = (Classification) it.next(); if (c.param != -1) has_param = true; if (c.isConstant) has_const = true; } if (has_param) one_param_field++; if (has_const) one_const_field++; one_constructor++; } // okay, we're done! return Collections.unmodifiableMap(map); }