Package org.trifort.rootbeer.generate.opencl

Source Code of org.trifort.rootbeer.generate.opencl.OpenCLPolymorphicMethod$VirtualMethodComparator

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

package org.trifort.rootbeer.generate.opencl;

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

import org.trifort.rootbeer.generate.opencl.tweaks.Tweaks;

import soot.*;
import soot.rbclassload.ClassHierarchy;
import soot.rbclassload.HierarchyGraph;
import soot.rbclassload.MethodSignatureUtil;
import soot.rbclassload.RootbeerClassLoader;

/**
* Represents an OpenCL function that dispatches to the real OpenCL function
* implementing the behavior of a certain classes version of a virtual method.
* @author pcpratts
*/
public class OpenCLPolymorphicMethod {

  private final SootMethod m_sootMethod;
  private MethodSignatureUtil m_util;
 
  private Set<String> m_extraMethods;

  public OpenCLPolymorphicMethod(SootMethod soot_method){
    m_sootMethod = soot_method;
    m_util = new MethodSignatureUtil();
   
    m_extraMethods = new HashSet<String>();
    m_extraMethods.add("<java.lang.Object: int hashCode()>");
  }

  public String getMethodPrototypes(){
    if(m_sootMethod.getName().equals("<init>"))
      return "";
    List<String> decls = getMethodDecls();
    StringBuilder ret = new StringBuilder();
    for(String decl : decls){
      decl += ";\n";
      ret.append(decl);
    }
    return ret.toString();
  }

  private List<String> getMethodDecls(){
    if(shouldOutput() == false){
      return new ArrayList<String>();
    }
    List<SootMethod> virtual_methods = getVirtualMethods();
   
    List<String> ret = new ArrayList<String>();
    for(SootMethod virtual_method : virtual_methods){
      SootClass soot_class = virtual_method.getDeclaringClass();
      OpenCLMethod ocl_method = new OpenCLMethod(m_sootMethod, soot_class);

      StringBuilder builder = new StringBuilder();
      builder.append(Tweaks.v().getDeviceFunctionQualifier()+" ");
      builder.append(ocl_method.getReturnString());
      builder.append(" invoke_"+ocl_method.getPolymorphicName());
      builder.append(ocl_method.getArgumentListStringPolymorphic());
      ret.add(builder.toString());
    }
    return ret;
  }

  public Set<String> getMethodBodies(){
    if(shouldOutput() == false){
      return new HashSet<String>();
    }
    if(m_sootMethod.getName().equals("<init>"))
      return new HashSet<String>();
    List<String> decls = getMethodDecls();
    Set<String> ret = new HashSet<String>();
    for(String decl : decls){
      String method = getMethodBody(decl);
      ret.add(method);
    }
    return ret;
  }
 
  private List<SootMethod> getVirtualMethods(){
    ClassHierarchy class_hierarchy = RootbeerClassLoader.v().getClassHierarchy();
    List<String> virtual_methods = class_hierarchy.getVirtualMethods(m_sootMethod.getSignature());
    List<SootMethod> ret = new ArrayList<SootMethod>();
    for(String virtual_method : virtual_methods){
      m_util.parse(virtual_method);
      SootMethod soot_method = m_util.getSootMethod();
      if(soot_method.isConcrete()){
        ret.add(soot_method);
      }
    }
    if(ret.contains(m_sootMethod) == false){
      ret.add(m_sootMethod);
    }
    return ret;
  }
 
  public String getMethodBody(String decl){
    StringBuilder ret = new StringBuilder();
    String address_qual = Tweaks.v().getGlobalAddressSpaceQualifier();
    //write function signature
    ret.append(decl);
    ret.append("{\n");
   
    List<SootMethod> virtual_methods = getVirtualMethods();
    if(m_sootMethod.isStatic()){
      if(m_sootMethod.getReturnType() instanceof VoidType == false){
        ret.append("return ");
      }
      Type first_type = m_sootMethod.getDeclaringClass().getType();
      RefType ref_type = (RefType) first_type;
      SootClass first_class = ref_type.getSootClass();
      String invoke_string = getStaticInvokeString(first_class);
      ret.append(invoke_string+"\n");
    } else {
      ret.append(address_qual+" char * thisref_deref;\n");
      ret.append("GC_OBJ_TYPE_TYPE derived_type;\n");
      ret.append("if(thisref == -1){\n");
      ret.append("  *exception = %%java_lang_NullPointerException_TypeNumber%%;\n");
      ret.append("return ");
      if(m_sootMethod.getReturnType() instanceof VoidType == false)
        ret.append("-1");
      ret.append(";\n");
      ret.append("}\n");
      ret.append("thisref_deref = org_trifort_gc_deref(thisref);\n");
      if(virtual_methods.size() == 1){
        SootClass sclass = virtual_methods.get(0).getDeclaringClass();
        String invoke_string = getInvokeString(sclass);
        if(m_sootMethod.getReturnType() instanceof VoidType == false){
          ret.append("return ");
        }
        ret.append(invoke_string+"\n");
      } else {
        ret.append("derived_type = org_trifort_gc_get_type(thisref_deref);\n");
        ret.append("if(0){}\n");
        int count = 0;
        List<SootMethod> used_methods = new ArrayList<SootMethod>();
        for(SootMethod method : virtual_methods){
          SootClass sclass = method.getDeclaringClass();
          if(sclass.isInterface()){
            continue;
          }
          String invoke_string = getInvokeString(sclass);
          if(invoke_string == ""){
            continue;
          }
          used_methods.add(method);
        }
        Collections.sort(used_methods, new VirtualMethodComparator());
        for(SootMethod method : used_methods){
          SootClass sclass = method.getDeclaringClass();
          String invoke_string = getInvokeString(sclass);
       
          ret.append("else if(derived_type == "+RootbeerClassLoader.v().getClassNumber(sclass)+"){\n");
          if(m_sootMethod.getReturnType() instanceof VoidType == false){
            ret.append("return ");
          }
          ret.append(invoke_string+"\n");
          ret.append("}\n");
          count++;
        }
      }
    }
    ret.append("return ");
    if(m_sootMethod.getReturnType() instanceof VoidType == false)
      ret.append("-1");
    ret.append(";\n");
    ret.append("}\n");
    return ret.toString();
  }

  //used to invoke polymorphic method inside this function
  private String getInvokeString(SootClass start_class){
    if(m_sootMethod.getName().equals("<init>"))
      return "";
       
    SootClass soot_class = start_class;
    OpenCLMethod ocl_method = new OpenCLMethod(m_sootMethod, soot_class);
    String ret = ocl_method.getPolymorphicName() + "(";

    //write the thisref
    ret += "thisref, ";
    List args = m_sootMethod.getParameterTypes();
    for(int i = 0; i < args.size(); ++i){
      ret += "parameter" + Integer.toString(i);
      ret += ", ";
    }
    ret += "exception);";
    return ret;
  }

  private String getStaticInvokeString(SootClass soot_class) {
    if(m_sootMethod.getName().equals("<init>"))
      return "";
    OpenCLMethod ocl_method = new OpenCLMethod(m_sootMethod, soot_class);
    String ret = ocl_method.getPolymorphicName() + "(";

    List args = m_sootMethod.getParameterTypes();
    for(int i = 0; i < args.size(); ++i){
      ret += "parameter" + Integer.toString(i);
      ret += ", ";
    }
    ret += "exception);";
    return ret;
  }

  public class VirtualMethodComparator implements
      Comparator<SootMethod> {

    @Override
    public int compare(SootMethod lhs, SootMethod rhs) {
      SootClass lhs_class = lhs.getDeclaringClass();
      SootClass rhs_class = rhs.getDeclaringClass();
     
      Integer lhs_number = RootbeerClassLoader.v().getClassNumber(lhs_class);
      Integer rhs_number = RootbeerClassLoader.v().getClassNumber(rhs_class);
      return lhs_number.compareTo(rhs_number);
    }
  }
 
  private boolean shouldOutput(){
    if(m_extraMethods.contains(m_sootMethod.getSignature())){
      return true;
    }
    return m_sootMethod.isConcrete();
  }
}
TOP

Related Classes of org.trifort.rootbeer.generate.opencl.OpenCLPolymorphicMethod$VirtualMethodComparator

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.