Soot中的SmartLocalDefs代码浅析

今天读了读Soot中的SmartLocalDefs类,因为在其mailing list里面至少有2封邮件[1][2]推荐看看这个类,慕名而来 可惜的是,这个类相关的注释/文档太少,所以特此记录,以备后用。

首先这个类的成员包括5个域, 4个方法和1个内部类,下面就按次序简单描述一下各个部分。

一. 域
1)
private final Map<Cons, ArrayList<Unit>> answer;

answer用于存储该类所做分析的最终结果:将(cons Unit Local)映射到其所有可能的def所在的Units

2)
private final Map<Local, HashSet<Unit>> localToDefs;

localToDefs将每个Local映射到定义它的所有Units

3)
private final UnitGraph graph;

graph是分析过程中所用的流图

4)
private final LocalDefsAnalysis analysis;

analysis是内部类LocalDefsAnalysis的一个引用,稍后具体介绍LocalDefsAnalysis

5)
private final Map<Unit, HashSet> unitToMask;

unitToMask将Unit映射到在该Unit之后依然live的Locals

二. 方法
1)
public SmartLocalDefs(UnitGraph g, LiveLocals live)

类的构造函数,这个类的主要逻辑集中在该方法中(一大部分分析由内部类完成)。除了打印log之外,它干的活主要包括如下几个步骤:
  • 初始化graph, localToDefs,unitToMask
  • 将graph作为参数生成内部类LocalDefsAnalysis的一个实例。其实内部类在其构造函数被调用后,它已经默默的把主要的数据流分析都做完了
  • 对于每个Unit(记为u),首先找出它use的Locals,然后将每一个Local(记为v)能到达该Unit的defs取出,最后构建一个(cons u v)并将其连同对应的defs放入answer.


2)
private Local localDef(Unit u)

返回u当中定义的Local(即local变量)。 注意,方法里一个隐含的assertion是一个Unit至多能定义一个Local。

3)
private HashSet<Unit> defsOf( Local l )

返回l所有可能的defs。这个方法直接将l作为key从localToDefs里面去找value了,如果找不到就先put一个空的HashSet,然后将其返回。所以该方法的返回值总是non-null。

4)
public List<Unit> getDefsOfAt(Local l, Unit s)

这个方法就是client使用SmartLocalDefs的主要途径,即提供一个Local和一个Unit,获取在这个Unit中所有l的defs。

三. 内部类
终于轮到苦工内部类LocalDefsAnalysis了。该类扩展了Soot框架提供的ForwardFlowAnalysis类,实现了一系列Soot进行数据流分析所需要的方法(关于这些方法的细节,可参考[3])。
这里就记录当前还没看太明白的问题:

protected void flowThrough(Object inValue, Object unit, Object outValue) {
  Unit u = (Unit) unit;
  HashSet in = (HashSet) inValue;
  HashSet<Unit> out = (HashSet<Unit>) outValue;
  out.clear();
  Set mask = unitToMask.get(u);
  Local l = localDef(u);
  HashSet<Unit> allDefUnits = null;
  
  if (l == null)
  {//add all units contained in mask
    for( Iterator inUIt = in.iterator(); inUIt.hasNext(); ) {
      final Unit inU = (Unit) inUIt.next();
        if( mask.contains(localDef(inU)) ){
	  out.add(inU);
	}
    }
  }else
  {//check unit whether contained in allDefUnits before add into out set.
    allDefUnits = defsOf(l);
				
    for( Iterator inUIt = in.iterator(); inUIt.hasNext(); ) {
      final Unit inU = (Unit) inUIt.next();
      if( mask.contains(localDef(inU)) )
      {//only add unit not contained in allDefUnits
	if ( allDefUnits.contains(inU)){
	  out.remove(inU);
	} else {
	  out.add(inU);
	}
       }
     }
   
     out.removeAll(allDefUnits);
     if(mask.contains(l)) out.add(u);
  }
}

1)为什么倒数第2行还要removeAll?
2)为什么最后1行在out.add(u)之前还要判断l是否在mask中?

其实还有一个大问题:这个SmartLocalDefs和SimpleLocalDefs有什么具体区别?
等回头有时间了,再仔细琢磨琢磨吧

[1] http://www.sable.mcgill.ca/pipermail/soot-list/2008-July/001872.html
[2] http://www.sable.mcgill.ca/pipermail/soot-list/2007-March/001084.html
[3] http://www.sable.mcgill.ca/soot/tutorial/analysis/index.html

你可能感兴趣的:(html,框架)