Package org.trifort.rootbeer.generate.bytecode

Source Code of org.trifort.rootbeer.generate.bytecode.VisitorWriteGenStatic

/*
* Copyright 2012 Phil Pratt-Szeliga and other contributors
* http://chirrup.org/
*
* See the file LICENSE for copying permission.
*/

package org.trifort.rootbeer.generate.bytecode;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.trifort.rootbeer.generate.bytecode.permissiongraph.PermissionGraph;
import org.trifort.rootbeer.generate.bytecode.permissiongraph.PermissionGraphNode;
import org.trifort.rootbeer.generate.opencl.ClassConstantNumbers;
import org.trifort.rootbeer.generate.opencl.OpenCLScene;
import org.trifort.rootbeer.generate.opencl.fields.OpenCLField;

import soot.*;
import soot.jimple.ClassConstant;
import soot.jimple.IntConstant;
import soot.jimple.LongConstant;
import soot.jimple.StringConstant;
import soot.rbclassload.RootbeerClassLoader;

public class VisitorWriteGenStatic extends AbstractVisitorGen {
 
  private Local m_Mem;
  private StaticOffsets m_StaticOffsets;
  private Set<String> m_AttachedWriters;
   
  public VisitorWriteGenStatic(BytecodeLanguage bcl){  
    m_bcl.push(bcl);
    m_StaticOffsets = new StaticOffsets();
    m_AttachedWriters = new HashSet<String>();
  }
 
  public void makeMethod(){
    BytecodeLanguage bcl = m_bcl.top();   
    bcl.startMethod("doWriteStaticsToHeap", VoidType.v());
   
    m_thisRef = bcl.refThis();
    m_currThisRef.push(m_thisRef);
    m_gcObjVisitor.push(m_thisRef);
    m_Mem = bcl.refInstanceField(m_thisRef, "mMem")
    m_currMem.push(m_Mem);
   
    BclMemory bcl_mem = new BclMemory(bcl, m_Mem);
    bcl_mem.useInstancePointer();
    bcl_mem.mallocWithSize(IntConstant.v(m_StaticOffsets.getEndIndex()));
    PermissionGraph graph = new PermissionGraph();  
    List<PermissionGraphNode> roots = graph.getRoots();
    for(PermissionGraphNode node : roots){
      SootClass soot_class = node.getSootClass();
      if(soot_class.isApplicationClass()){
        attachAndCallWriter(soot_class, node.getChildren());
      } else {
        //doWriter(soot_class, node.getChildren());
        doWriter(soot_class, new ArrayList<SootClass>());
      }
    }
   
    //write .class's for array types
    Set<ArrayType> array_types = RootbeerClassLoader.v().getDfsInfo().getArrayTypes();
    for(ArrayType type : array_types){
      writeType(type);
    }
   
    bcl_mem.useStaticPointer();
    bcl_mem.setAddress(LongConstant.v(m_StaticOffsets.getLockStart()));
    //write the lock objects for all the classes
    int count = m_StaticOffsets.getClassSize();
    for(int i = 0; i < count; ++i){
      bcl_mem.writeInt(-1);
    }
    int zeros = m_StaticOffsets.getZerosSize();
    for(int i = 0; i < zeros; ++i){
      bcl_mem.writeByte((byte) 0);
    }
    bcl_mem.useInstancePointer();
   
    bcl.returnVoid();   
    bcl.endMethod();
   
    m_gcObjVisitor.pop();
  }
 
  private void attachAndCallWriter(SootClass soot_class, List<SootClass> children){   
    String class_name = soot_class.getName();
    if(m_classesToIgnore.contains(class_name))
      return;
   
    attachWriter(soot_class, children);
    callWriter(soot_class);
  }
 
  private void callWriter(SootClass soot_class){   
    BytecodeLanguage bcl = m_bcl.top();
    String method_name = getWriterName(soot_class);
    SootClass mem = Scene.v().getSootClass("org.trifort.rootbeer.runtime.Memory");
    bcl.pushMethod(soot_class, method_name, VoidType.v(), mem.getType(), m_gcObjVisitor.top().getType());
    bcl.invokeStaticMethodNoRet(m_currMem.top(), m_gcObjVisitor.top());
  }
 
  private String getWriterName(SootClass soot_class){
    return "org_trifort_writeStaticsToHeap"+JavaNameToOpenCL.convert(soot_class.getName())+OpenCLScene.v().getIdent();
  }

  private void attachWriter(SootClass soot_class, List<SootClass> children){   
       
    String method_name = getWriterName(soot_class);
    if(m_AttachedWriters.contains(method_name))
      return;
    m_AttachedWriters.add(method_name);
       
    BytecodeLanguage bcl = new BytecodeLanguage();
    m_bcl.push(bcl);
    bcl.openClass(soot_class);
    SootClass mem = Scene.v().getSootClass("org.trifort.rootbeer.runtime.Memory");
    bcl.startStaticMethod(method_name, VoidType.v(), mem.getType(), m_gcObjVisitor.top().getType());
   
    Local memory = bcl.refParameter(0);
    Local gc_visit = bcl.refParameter(1);
    m_currMem.push(memory);
    m_gcObjVisitor.push(gc_visit);
   
    doWriter(soot_class, children);
   
    bcl.returnVoid();
    bcl.endMethod();
   
    m_gcObjVisitor.pop();
    m_currMem.pop();
    m_bcl.pop();
  }
 
  private void doWriter(SootClass soot_class, List<SootClass> children){ 
    BytecodeLanguage bcl = m_bcl.top();
    Local memory = m_currMem.top();
    Local gc_visit = m_gcObjVisitor.top();
   
    writeType(soot_class.getType());
   
    List<OpenCLField> static_fields = m_StaticOffsets.getStaticFields(soot_class);
   
    BclMemory bcl_mem = new BclMemory(bcl, memory);
    SootClass obj = Scene.v().getSootClass("java.lang.Object");
    for(OpenCLField field : static_fields){
      Local field_value;
      if(soot_class.isApplicationClass()){
        field_value = bcl.refStaticField(soot_class.getType(), field.getName());
      } else {
        SootClass string = Scene.v().getSootClass("java.lang.String");
        SootClass cls = Scene.v().getSootClass("java.lang.Class");
        bcl.pushMethod(gc_visit, "readStaticField", obj.getType(), cls.getType(), string.getType());
        Local obj_field_value = bcl.invokeMethodRet(gc_visit, ClassConstant.v(toConstant(soot_class.getName())), StringConstant.v(field.getName()));
        if(field.getType().isRefType()){
          field_value = obj_field_value;
        } else {
          Local capital_value = bcl.cast(field.getType().getCapitalType(), obj_field_value);
          bcl.pushMethod(capital_value, field.getType().getName()+"Value", field.getType().getSootType());
          field_value = bcl.invokeMethodRet(capital_value);
        }
      }
      if(field.getType().isRefType()){
        bcl.pushMethod(gc_visit, "writeToHeap", LongType.v(), obj.getType(), BooleanType.v());
        Local ref = bcl.invokeMethodRet(gc_visit, field_value, IntConstant.v(1));
        bcl_mem.useStaticPointer();
        bcl_mem.setAddress(LongConstant.v(m_StaticOffsets.getIndex(field)));
        bcl_mem.writeRef(ref);
        bcl_mem.useInstancePointer();
      } else {
        bcl_mem.useStaticPointer();
        bcl_mem.setAddress(LongConstant.v(m_StaticOffsets.getIndex(field)));
        bcl_mem.writeVar(field_value);
        bcl_mem.useInstancePointer();
      }
    }
   
    for(SootClass child : children){
      if(soot_class.isApplicationClass()){
        attachAndCallWriter(child, new ArrayList<SootClass>());
      } else {
        doWriter(child, new ArrayList<SootClass>());
      }
    }
  }

  private boolean reachesJavaLangClass(){
    List<RefType> ref_types = RootbeerClassLoader.v().getDfsInfo().getOrderedRefTypes()
    RefType java_lang_class = RefType.v("java.lang.Class");
    return ref_types.contains(java_lang_class);
  }
 
  private void writeType(Type type) {
    if(reachesJavaLangClass() == false){
      return;
    }
    int number = OpenCLScene.v().getClassConstantNumbers().get(type);
    Local gc_visit = m_gcObjVisitor.top();
    Local class_obj = null;
   
    if(type instanceof ArrayType){
      ArrayType array_type = (ArrayType) type;
      class_obj = m_bcl.top().classConstant(type);  
    } else {
      RefType ref_type = (RefType) type;
      class_obj = m_bcl.top().classConstant(type);  
    }
   
    //getName has to be called to load the name variable
    SootClass str_cls = Scene.v().getSootClass("java.lang.String");
    m_bcl.top().pushMethod(class_obj, "getName", str_cls.getType());
    m_bcl.top().invokeMethodRet(class_obj);
   
    SootClass obj_cls = Scene.v().getSootClass("java.lang.Object");
    m_bcl.top().pushMethod(gc_visit, "writeToHeap", LongType.v(), obj_cls.getType(), BooleanType.v());
    Local ref = m_bcl.top().invokeMethodRet(gc_visit, class_obj, IntConstant.v(1));
   
    m_bcl.top().pushMethod(gc_visit, "addClassRef", VoidType.v(), LongType.v(), IntType.v());
    m_bcl.top().invokeMethodNoRet(gc_visit, ref, IntConstant.v(number));
  }
}
TOP

Related Classes of org.trifort.rootbeer.generate.bytecode.VisitorWriteGenStatic

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.