Package org.trifort.rootbeer.generate.bytecode

Source Code of org.trifort.rootbeer.generate.bytecode.StaticOffsets$SortableField

/*
* 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.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.trifort.rootbeer.generate.opencl.OpenCLClass;
import org.trifort.rootbeer.generate.opencl.OpenCLScene;
import org.trifort.rootbeer.generate.opencl.fields.CompositeField;
import org.trifort.rootbeer.generate.opencl.fields.OpenCLField;

import soot.RefType;
import soot.Scene;
import soot.SootClass;
import soot.Type;
import soot.rbclassload.RootbeerClassLoader;

public class StaticOffsets {
 
  private Map<Integer, SortableField> m_offsetToFieldMap;
  private Map<OpenCLField, Integer> m_fieldToOffsetMap;
  private Map<SootClass, Integer> m_classToOffsetMap;
  private Map<SootClass, List<OpenCLField>> m_staticFields;
  private int m_endIndex;
  private int m_lockStart;
  private int m_zerosSize;
 
  public StaticOffsets(){  
    m_offsetToFieldMap = new HashMap<Integer, SortableField>();
    m_fieldToOffsetMap = new HashMap<OpenCLField, Integer>();
    m_classToOffsetMap = new HashMap<SootClass, Integer>();
    m_staticFields = new HashMap<SootClass, List<OpenCLField>>();
    buildMaps();
  }
 
  public OpenCLField getField(int index){
    return m_offsetToFieldMap.get(index).m_field;
  }
 
  public int getIndex(OpenCLField field){
    return m_fieldToOffsetMap.get(field);
  }
 
  public int getIndex(SootClass soot_class){
    return m_classToOffsetMap.get(soot_class);
  }

  public int getEndIndex(){
    return m_endIndex;
  }
 
  public List<OpenCLField> getStaticFields(SootClass soot_class){
    List<OpenCLField> ret = m_staticFields.get(soot_class);
    if(ret == null){
      ret = new ArrayList<OpenCLField>();
    }
    return ret;
  }
 
  private void buildMaps() {
    List<CompositeField> composites = OpenCLScene.v().getCompositeFields();
    Set<SortableField> sortable_fields = new HashSet<SortableField>();
    for(CompositeField composite : composites){
      List<SootClass> classes = composite.getClasses();
      for(SootClass soot_class : classes){
        sortable_fields.addAll(convert(composite.getRefFieldsByClass(soot_class), soot_class));
        sortable_fields.addAll(convert(composite.getNonRefFieldsByClass(soot_class), soot_class));
       
        List<OpenCLField> static_fields = new ArrayList<OpenCLField>();
        static_fields.addAll(staticFilter(composite.getRefFieldsByClass(soot_class)));
        static_fields.addAll(staticFilter(composite.getNonRefFieldsByClass(soot_class)));
        m_staticFields.put(soot_class, static_fields);
      }
    }
    SortableField[] array = new SortableField[sortable_fields.size()];
    array = sortable_fields.toArray(array);
    Arrays.sort(array);
    int index = 0;
    for(SortableField field : array){
      m_offsetToFieldMap.put(index, field);
      m_fieldToOffsetMap.put(field.m_field, index);
      int size = field.m_field.getSize();
      index += size;
    }
    int leftover = index % 4;
    if(leftover != 0){
      index += leftover;
    }
    m_lockStart = index;
    Set<Type> types = RootbeerClassLoader.v().getDfsInfo().getDfsTypes();
    for(Type type : types){
      if(type instanceof RefType == false){
        continue;
      }
      RefType ref_type = (RefType) type;
      String curr = ref_type.getClassName();
      SootClass soot_class = Scene.v().getSootClass(curr);
      m_classToOffsetMap.put(soot_class, index);
      index += 4;
    }
    m_endIndex = index;
    int mod = m_endIndex % 16;
    m_zerosSize = 0;
    if(mod != 0){
      m_endIndex += (16 - mod);
      m_zerosSize += (16 - mod);
    }
    //give room for junk space. some reason 32 bytes of space are needed for
    //the synchronized tests to pass.
    m_endIndex += 32;
    m_zerosSize += 32;
  }
 
  public int getZerosSize(){
    return m_zerosSize;
  }

  private List<SortableField> convert(List<OpenCLField> fields, SootClass soot_class) {
    fields = staticFilter(fields);
    List<SortableField> ret = new ArrayList<SortableField>();
    for(OpenCLField field : fields){
      ret.add(new SortableField(field, soot_class));
    }
    return ret;
  }
 
  private List<OpenCLField> staticFilter(List<OpenCLField> fields){
    List<OpenCLField> ret = new ArrayList<OpenCLField>();
    for(OpenCLField field : fields){
      if(field.isInstance() == false){
        ret.add(field);
      }
    }
    return ret;
  }

  public int getClassSize() {
    return m_classToOffsetMap.size();
  }

  public int getLockStart() {
    return m_lockStart;
  }
 
  private class SortableField implements Comparable<SortableField> {
    public OpenCLField m_field;
    public SootClass m_sootClass;
   
    public SortableField(OpenCLField field, SootClass soot_class){
      m_field = field;
      m_sootClass = soot_class;
    }

    public int compareTo(SortableField o) {
      int this_size = m_field.getSize();
      int o_size = o.m_field.getSize();
      return Integer.valueOf(o_size).compareTo(Integer.valueOf(this_size));
    }
   
    @Override
    public boolean equals(Object other){
      if(other instanceof SortableField == false){
        return false;
      }
      SortableField rhs = (SortableField) other;
      if(m_field.getName().equals(rhs.m_field.getName()) == false){
        return false;
      }
      if(m_field.getSootField().getDeclaringClass().getName().equals(rhs.m_field.getSootField().getDeclaringClass().getName()) == false){
        return false;
      }
      return true;
    }

    @Override
    public int hashCode() {
      int hash = 3;
      hash = 23 * hash + (this.m_field.toString() != null ? this.m_field.toString().hashCode() : 0);
      return hash;
    }
  }
}
TOP

Related Classes of org.trifort.rootbeer.generate.bytecode.StaticOffsets$SortableField

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.