//===----- JavaAOTCompiler.cpp - Support for Ahead of Time Compiler --------===//
//
//                            The VMKit project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/IR/DataLayout.h"

#include "vmkit/UTF8.h"
#include "vmkit/Thread.h"

#include "j3/J3Intrinsics.h"
#include "j3/JavaAOTCompiler.h"
#include "j3/JavaJITCompiler.h"

#include "JavaArray.h"
#include "JavaConstantPool.h"
#include "JavaString.h"
#include "JavaThread.h"
#include "JavaTypes.h"
#include "JavaUpcalls.h"
#include "Jnjvm.h"
#include "Reader.h"
#include "VMStaticInstance.h"
#include "Zip.h"

#include <cstdio>

using namespace j3;
using namespace llvm;

bool JavaAOTCompiler::isCompiling(const CommonClass* cl) const {
  if (cl->isClass()) {
    // A class is being static compiled if owner class is not null.
    return precompile || (cl->asClass()->getOwnerClass() != 0);
  } else if (cl->isArray()) {
    // Only compile an aray if we are compiling rt.jar.
    return compileRT;
  } else if (cl->isPrimitive() && compileRT) {
    return true;
  } else {
    return false;
  }
}

void JavaAOTCompiler::AddInitializerToClass(GlobalVariable* varGV, CommonClass* classDef) {
  if (classDef->isClass() && isCompiling(classDef)) {
    Constant* C = CreateConstantFromClass(classDef->asClass());
    varGV->setInitializer(C);
  } else if (classDef->isArray()) {
    Constant* C = CreateConstantFromClassArray(classDef->asArrayClass());
    varGV->setInitializer(C);
  } else if (classDef->isPrimitive() && compileRT) {
    Constant* C = 
      CreateConstantFromClassPrimitive(classDef->asPrimitiveClass());
    varGV->setInitializer(C);
  }
}

GlobalVariable* JavaAOTCompiler::getNativeClass(CommonClass* classDef) {

  if (classDef->isClass() || isCompiling(classDef) || assumeCompiled) {

    native_class_iterator End = nativeClasses.end();
    native_class_iterator I = nativeClasses.find(classDef);
    if (I == End) {
      llvm::Type* Ty = NULL;
      
      if (classDef->isArray()) {
        Ty = JavaIntrinsics.JavaClassArrayType->getContainedType(0); 
      } else if (classDef->isPrimitive()) {
        Ty = JavaIntrinsics.JavaClassPrimitiveType->getContainedType(0); 
      } else {
        Ty = JavaIntrinsics.JavaClassType->getContainedType(0); 
      }
    
      GlobalVariable* varGV =
        new GlobalVariable(*getLLVMModule(), Ty, false,
                        GlobalValue::ExternalLinkage, 0,
                        UTF8Buffer(classDef->name).toCompileName()->cString());
    
      nativeClasses.insert(std::make_pair(classDef, varGV));

      if (!precompile || classDef->isPrimitive()) {
        AddInitializerToClass(varGV, classDef);
      }

      return varGV;
    } else {
      return I->second;
    }
  } else if (classDef->isArray()) {
    array_class_iterator End = arrayClasses.end();
    array_class_iterator I = arrayClasses.find(classDef->asArrayClass());
    if (I == End) {
      llvm::Type* Ty = JavaIntrinsics.JavaClassArrayType;
      Module& Mod = *getLLVMModule();
    
      GlobalVariable* varGV = 
        new GlobalVariable(Mod, Ty, false, GlobalValue::InternalLinkage,
                           Constant::getNullValue(Ty),
                        UTF8Buffer(classDef->name).toCompileName()->cString());
    
      arrayClasses.insert(std::make_pair(classDef->asArrayClass(), varGV));
      return varGV;
    } else {
      return I->second;
    }
  } else {
    assert(0 && "Implement me");
  }
  return 0;
}

Constant* JavaAOTCompiler::CreateConstantFromJavaConstantPool(JavaConstantPool* ctp) {
  StructType* STy = 
    dyn_cast<StructType>(JavaIntrinsics.JavaConstantPoolType->getContainedType(0));
  Module& Mod = *getLLVMModule();
  
  std::vector<Constant*> Elemts;

  // Class
  Elemts.push_back(getNativeClass(ctp->classDef));

  // ctpSize
  Elemts.push_back(ConstantInt::get(Type::getInt32Ty(getLLVMContext()), ctp->ctpSize));

  // ctpType
  ArrayType* ATy = ArrayType::get(Type::getInt8Ty(getLLVMContext()), ctp->ctpSize);
  std::vector<Constant*> Vals;
  for (uint32 i = 0; i < ctp->ctpSize; ++i) {
    Vals.push_back(ConstantInt::get(Type::getInt8Ty(getLLVMContext()), ctp->ctpType[i]));
  }

  Constant* Array = ConstantArray::get(ATy, Vals);
  GlobalVariable* varGV = new GlobalVariable(Mod, Array->getType(), false,
                                             GlobalValue::InternalLinkage,
                                             Array, "");
 
  Array = ConstantExpr::getBitCast(
      varGV, PointerType::getUnqual(Type::getInt8Ty(getLLVMContext())));
  Elemts.push_back(Array);

  // ctpDef
  ATy = ArrayType::get(Type::getInt32Ty(getLLVMContext()), ctp->ctpSize);
  Vals.clear();
  for (uint32 i = 0; i < ctp->ctpSize; ++i) {
    Vals.push_back(ConstantInt::get(Type::getInt32Ty(getLLVMContext()), ctp->ctpDef[i]));
  }

  Array = ConstantArray::get(ATy, Vals);
  varGV = new GlobalVariable(Mod, Array->getType(), false,
                             GlobalValue::InternalLinkage,
                             Array, "");
 
  Array = ConstantExpr::getBitCast(
      varGV, PointerType::getUnqual(Type::getInt32Ty(getLLVMContext())));

  Elemts.push_back(Array);

  // ctpRes
  Elemts.push_back(getResolvedConstantPool(ctp));

  return ConstantStruct::get(STy, Elemts);
}

Constant* JavaAOTCompiler::getResolvedConstantPool(JavaConstantPool* ctp) {
  resolved_constant_pool_iterator End = resolvedConstantPools.end();
  resolved_constant_pool_iterator I = resolvedConstantPools.find(ctp);
  if (I == End) {
    Module& Mod = *getLLVMModule();

    ArrayType* ATy = ArrayType::get(JavaIntrinsics.ptrType, ctp->ctpSize);
    std::vector<Constant*> Vals;
    for (uint32 i = 0; i < ctp->ctpSize; ++i) {
      if (ctp->typeAt(i) == JavaConstantPool::ConstantUTF8) {
        Vals.push_back(ConstantExpr::getBitCast(getUTF8(ctp->UTF8At(i)), JavaIntrinsics.ptrType));
      } else if (ctp->typeAt(i) == JavaConstantPool::ConstantClass
                  && (ctp->isClassLoaded(i) != NULL)) {
        Vals.push_back(ConstantExpr::getBitCast(
            getNativeClass(ctp->isClassLoaded(i)), JavaIntrinsics.ptrType));
      } else {
        Vals.push_back(Constant::getNullValue(JavaIntrinsics.ptrType));
      }
    }

    Constant* Array = ConstantArray::get(ATy, Vals);
    GlobalVariable* varGV = new GlobalVariable(Mod, Array->getType(), false,
                                               GlobalValue::InternalLinkage,
                                               Array, "");
 
    Array = ConstantExpr::getBitCast(varGV, JavaIntrinsics.ResolvedConstantPoolType);
    
    resolvedConstantPools.insert(std::make_pair(ctp, Array));
    return Array;
  } else {
    return I->second;
  }
}

Constant* JavaAOTCompiler::getMethodInClass(JavaMethod* meth) {
  Class* cl = meth->classDef;
  Constant* MOffset = 0;
  Constant* Array = 0;

  for (uint32 i = 0; i < cl->nbVirtualMethods + cl->nbStaticMethods; ++i) {
    if (&cl->virtualMethods[i] == meth) {
      MOffset = ConstantInt::get(Type::getInt32Ty(getLLVMContext()), i);
      break;
    }
  }
  assert(MOffset && "No offset for method");

  method_iterator SI = virtualMethods.find(cl);
  if (SI != virtualMethods.end()) {
    Array = SI->second; 
    assert(Array && "No array in class");
  } else {
    std::string name(UTF8Buffer(cl->name).toCompileName()->cString());
    name += "_VirtualMethods";
    Module& Mod = *getLLVMModule();
    Type* ATy =
      ArrayType::get(JavaIntrinsics.JavaMethodType->getContainedType(0),
                     cl->nbVirtualMethods + cl->nbStaticMethods);

    Array = new GlobalVariable(Mod, ATy, false, GlobalValue::ExternalLinkage,
                               0, name);
    virtualMethods.insert(std::make_pair(cl, Array));
  }
    
  Constant* GEPs[2] = { getIntrinsics()->constantZero, MOffset };
  return ConstantExpr::getGetElementPtr(Array, GEPs, 2);
}

Constant* JavaAOTCompiler::getString(JavaString* str) {
  llvm_gcroot(str, 0);

  assert(!useCooperativeGC());
  string_iterator SI = strings.find(str);
  if (SI != strings.end()) {
    return SI->second;
  } else {
    assert(str && "No string given");
    LLVMClassInfo* LCI = getClassInfo(JavaObject::getClass(str)->asClass());
    llvm::Type* Ty = LCI->getVirtualType();
    Module& Mod = *getLLVMModule();
    
    const char* name = JavaString::strToAsciiz(str);
    GlobalVariable* varGV = 
      new GlobalVariable(Mod, Ty->getContainedType(0), false,
                         GlobalValue::ExternalLinkage, 0, "str");
    delete[] name;
    Constant* res = ConstantExpr::getCast(Instruction::BitCast, varGV,
                                          JavaIntrinsics.JavaObjectType);
    strings.insert(std::make_pair(str, res));
    Constant* C = CreateConstantFromJavaString(str);
    varGV->setInitializer(C);
    return res;
  }
}

Constant* JavaAOTCompiler::getClassBytes(const UTF8* className, ClassBytes* bytes) {
  class_bytes_iterator CI = classBytes.find(bytes);
  if (CI != classBytes.end()) {
    return CI->second;
  }

  std::vector<Type*> Elemts;
  ArrayType* ATy = ArrayType::get(Type::getInt8Ty(getLLVMContext()), bytes->size);
  Elemts.push_back(Type::getInt32Ty(getLLVMContext()));
  Elemts.push_back(ATy);
  StructType* STy = StructType::get(getLLVMContext(), Elemts);

  std::string name(UTF8Buffer(className).toCompileName("_bytes")->cString());
  Constant* C = emitClassBytes ? CreateConstantFromClassBytes(bytes) : NULL;
  GlobalVariable* varGV = new GlobalVariable(*getLLVMModule(), STy, false,
                                             GlobalValue::ExternalLinkage,
                                             C, name);
  classBytes[bytes] = varGV;
  return varGV;
}

Constant* JavaAOTCompiler::getStringPtr(JavaString** str) {
  fprintf(stderr, "Implement me");
  abort();
}

Constant* JavaAOTCompiler::getJavaClass(CommonClass* cl) {
  return Constant::getNullValue(JavaIntrinsics.JavaObjectType);
}

Constant* JavaAOTCompiler::getJavaClassPtr(CommonClass* cl) {
  // Make sure it's emitted.
  getJavaClass(cl);

  Constant* Cl = getNativeClass(cl);
  Cl = ConstantExpr::getBitCast(Cl, JavaIntrinsics.JavaCommonClassType);

  Constant* GEP[2] = { getIntrinsics()->constantZero,
                       getIntrinsics()->constantZero };
  
  Constant* TCMArray = ConstantExpr::getGetElementPtr(Cl, GEP, 2);
    
  Constant* GEP2[2] = { getIntrinsics()->constantZero,
                        getIntrinsics()->constantZero };

  Constant* Ptr = ConstantExpr::getGetElementPtr(TCMArray, GEP2, 2);
  return Ptr;
}

JavaObject* JavaAOTCompiler::getFinalObject(llvm::Value* obj) {
  if (Constant* CI = dyn_cast<Constant>(obj)) {
    reverse_final_object_iterator End = reverseFinalObjects.end();
    reverse_final_object_iterator I = reverseFinalObjects.find(CI);
    if (I != End) return I->second;
  }
  
  return 0;
}

Constant* JavaAOTCompiler::HandleMagic(JavaObject* obj, CommonClass* objCl) {
  word_t* realObj = 0;
  llvm_gcroot(obj, 0);
  llvm_gcroot(realObj, 0);

  static const UTF8* AddressArray = objCl->classLoader->asciizConstructUTF8("org/vmmagic/unboxed/AddressArray");
  static const UTF8* WordArray = objCl->classLoader->asciizConstructUTF8("org/vmmagic/unboxed/WordArray");
  static const UTF8* ExtentArray = objCl->classLoader->asciizConstructUTF8("org/vmmagic/unboxed/ExtentArray");
  static const UTF8* ObjectReferenceArray = objCl->classLoader->asciizConstructUTF8("org/vmmagic/unboxed/ObjectReferenceArray");
  static const UTF8* OffsetArray = objCl->classLoader->asciizConstructUTF8("org/vmmagic/unboxed/OffsetArray");
  const UTF8* name = objCl->name;

  if (name->equals(AddressArray) || name->equals(WordArray) ||
      name->equals(ExtentArray) || name->equals(ObjectReferenceArray) || 
      name->equals(OffsetArray)) {
    
    realObj = (word_t*)obj;
    word_t size = realObj[0];

    ArrayType* ATy = ArrayType::get(JavaIntrinsics.JavaObjectType,
                                    size + 1);
  
    std::vector<Constant*> Vals;
    for (uint32 i = 0; i < size + 1; ++i) {
      Constant* CI = ConstantInt::get(Type::getInt64Ty(getLLVMContext()),
                                      uint64_t(realObj[i]));
      CI = ConstantExpr::getIntToPtr(CI, JavaIntrinsics.JavaObjectType);
      Vals.push_back(CI);
    }

    Constant* CA = ConstantArray::get(ATy, Vals);
  
    GlobalVariable* varGV = new GlobalVariable(*getLLVMModule(), CA->getType(),
                                               false,
                                               GlobalValue::InternalLinkage,
                                               CA, "");
 
    return ConstantExpr::getBitCast(varGV, JavaIntrinsics.JavaObjectType);

  } else {
    Constant* CI = ConstantInt::get(Type::getInt64Ty(getLLVMContext()),
                                    uint64_t(obj));
    CI = ConstantExpr::getIntToPtr(CI, JavaIntrinsics.JavaObjectType);
    return CI;
  }
}


Constant* JavaAOTCompiler::getFinalObject(JavaObject* obj, CommonClass* objCl) {
  llvm_gcroot(obj, 0);

  assert(!useCooperativeGC());
  llvm::GlobalVariable* varGV = 0;
  final_object_iterator End = finalObjects.end();
  final_object_iterator I = finalObjects.find(obj);
  if (I == End) {
  
    if (vmkit::Collector::begOf(obj)) {
      Type* Ty = 0;
      CommonClass* cl = JavaObject::getClass(obj);
      
      if (cl->isArray()) {
        Classpath* upcalls = cl->classLoader->bootstrapLoader->upcalls;
        CommonClass* subClass = cl->asArrayClass()->baseClass();
        if (subClass->isPrimitive()) {
          if (subClass == upcalls->OfBool) {
            Ty = Type::getInt8Ty(getLLVMContext());
          } else if (subClass == upcalls->OfByte) {
            Ty = Type::getInt8Ty(getLLVMContext());
          } else if (subClass == upcalls->OfShort) {
            Ty = Type::getInt16Ty(getLLVMContext());
          } else if (subClass == upcalls->OfChar) {
            Ty = Type::getInt16Ty(getLLVMContext());
          } else if (subClass == upcalls->OfInt) {
            Ty = Type::getInt32Ty(getLLVMContext());
          } else if (subClass == upcalls->OfFloat) {
            Ty = Type::getFloatTy(getLLVMContext());
          } else if (subClass == upcalls->OfLong) {
            Ty = Type::getInt64Ty(getLLVMContext());
          } else if (subClass == upcalls->OfDouble) {
            Ty = Type::getDoubleTy(getLLVMContext());
          } else {
            abort();
          }
        } else {
          Ty = JavaIntrinsics.JavaObjectType;
        }
        
        std::vector<Type*> Elemts;
        ArrayType* ATy = ArrayType::get(Ty, JavaArray::getSize(obj));
        Elemts.push_back(JavaIntrinsics.JavaObjectType->getContainedType(0));
        Elemts.push_back(JavaIntrinsics.pointerSizeType);
        Elemts.push_back(ATy);
        Ty = StructType::get(getLLVMModule()->getContext(), Elemts);

      } else {
        LLVMClassInfo* LCI = getClassInfo(cl->asClass());
        Ty = LCI->getVirtualType()->getContainedType(0);
      }

      Module& Mod = *getLLVMModule();
      // Set as External, so that inlining MMTk code works.
      varGV = new GlobalVariable(Mod, Ty, false, GlobalValue::ExternalLinkage,
                                 0, "finalObject");

      Constant* C = ConstantExpr::getBitCast(varGV,
                                             JavaIntrinsics.JavaObjectType);
  
      finalObjects.insert(std::make_pair(obj, C));
      reverseFinalObjects.insert(std::make_pair(C, obj));
    
      varGV->setInitializer(CreateConstantFromJavaObject(obj));
      return C;
    } else {
      Constant* CI = HandleMagic(obj, objCl);
      finalObjects.insert(std::make_pair(obj, CI));
      return CI;
    }
  } else {
    return I->second;
  }
}

Constant* JavaAOTCompiler::CreateConstantFromStaticInstance(Class* cl) {
  JavaObject* val = 0;
  JavaString* obj = 0;
  llvm_gcroot(val, 0);
  llvm_gcroot(obj, 0);

  LLVMClassInfo* LCI = getClassInfo(cl);
  Type* Ty = LCI->getStaticType();
  StructType* STy = dyn_cast<StructType>(Ty->getContainedType(0));
  
  std::vector<Constant*> Elts;
  
  for (uint32 i = 0; i < cl->nbStaticFields; ++i) {
    JavaField& field = cl->staticFields[i];
    const Typedef* type = field.getSignature();
    LLVMAssessorInfo& LAI = getTypedefInfo(type);
    Type* Ty = LAI.llvmType;

    JavaAttribute* attribute = field.lookupAttribute(JavaAttribute::constantAttribute);

    if (attribute == NULL) {
      if ((cl->getStaticInstance() != NULL) && !useCooperativeGC()) {
        if (type->isPrimitive()) {
          const PrimitiveTypedef* prim = (const PrimitiveTypedef*)type;
          if (prim->isBool() || prim->isByte()) {
            ConstantInt* CI = ConstantInt::get(
                Type::getInt8Ty(getLLVMContext()),
                field.getStaticInt8Field());
            Elts.push_back(CI);
          } else if (prim->isShort() || prim->isChar()) {
            ConstantInt* CI = ConstantInt::get(
                Type::getInt16Ty(getLLVMContext()),
                field.getStaticInt16Field());
            Elts.push_back(CI);
          } else if (prim->isInt()) {
            ConstantInt* CI = ConstantInt::get(
                Type::getInt32Ty(getLLVMContext()),
                field.getStaticInt32Field());
            Elts.push_back(CI);
          } else if (prim->isLong()) {
            ConstantInt* CI = ConstantInt::get(
                Type::getInt64Ty(getLLVMContext()),
                field.getStaticLongField());
            Elts.push_back(CI);
          } else if (prim->isFloat()) {
            Constant* CF = ConstantFP::get(
                Type::getFloatTy(getLLVMContext()),
                field.getStaticFloatField());
            Elts.push_back(CF);
          } else if (prim->isDouble()) {
            Constant* CF = ConstantFP::get(
                Type::getDoubleTy(getLLVMContext()),
                field.getStaticDoubleField());
            Elts.push_back(CF);
          } else {
            abort();
          }
        } else {
          val = field.getStaticObjectField();
          if (val) {
            JnjvmClassLoader* JCL = cl->classLoader;
            CommonClass* FieldCl = field.getSignature()->assocClass(JCL);
            Constant* CO = getFinalObject(val, FieldCl);
            Elts.push_back(CO);
          } else {
            Elts.push_back(Constant::getNullValue(Ty));
          }
        }
      } else {
        Elts.push_back(Constant::getNullValue(Ty));
      }
    } else {
      Reader reader(attribute, cl->bytes);
      JavaConstantPool * ctpInfo = cl->ctpInfo;
      uint16 idx = reader.readU2();
      if (type->isPrimitive()) {
        if (Ty == Type::getInt64Ty(getLLVMContext())) {
          Elts.push_back(ConstantInt::get(Ty, (uint64)ctpInfo->LongAt(idx)));
        } else if (Ty == Type::getDoubleTy(getLLVMContext())) {
          Elts.push_back(ConstantFP::get(Ty, ctpInfo->DoubleAt(idx)));
        } else if (Ty == Type::getFloatTy(getLLVMContext())) {
          Elts.push_back(ConstantFP::get(Ty, ctpInfo->FloatAt(idx)));
        } else {
          Elts.push_back(ConstantInt::get(Ty, (uint64)ctpInfo->IntegerAt(idx)));
        }
      } else if (type->isReference()) {
        if (useCooperativeGC()) {
          Elts.push_back(JavaIntrinsics.JavaObjectNullConstant);
        } else {
          const UTF8* utf8 = ctpInfo->UTF8At(ctpInfo->ctpDef[idx]);
          obj = ctpInfo->resolveString(utf8, idx);
          Constant* C = getString(obj);
          C = ConstantExpr::getBitCast(C, JavaIntrinsics.JavaObjectType);
          Elts.push_back(C);
        }
      } else {
        fprintf(stderr, "Implement me");
        abort();
      }
    }
  }
   
  return ConstantStruct::get(STy, Elts);
}

Constant* JavaAOTCompiler::getStaticInstance(Class* classDef) {
  static_instance_iterator End = staticInstances.end();
  static_instance_iterator I = staticInstances.find(classDef);
  if (I == End) {
    
    LLVMClassInfo* LCI = getClassInfo(classDef);
    Type* Ty = LCI->getStaticType();
    Ty = Ty->getContainedType(0);
    std::string name(UTF8Buffer(classDef->name).toCompileName()->cString());
    name += "_static";
    Module& Mod = *getLLVMModule();
    GlobalVariable* varGV = 
      new GlobalVariable(Mod, Ty, false, GlobalValue::ExternalLinkage,
                         0, name);

    Constant* res = ConstantExpr::getCast(Instruction::BitCast, varGV,
                                          JavaIntrinsics.ptrType);
    staticInstances.insert(std::make_pair(classDef, res));
    
    if (isCompiling(classDef)) { 
      Constant* C = CreateConstantFromStaticInstance(classDef);
      varGV->setInitializer(C);
    }

    return res;
  } else {
    return I->second;
  }
}

Constant* JavaAOTCompiler::getVirtualTable(JavaVirtualTable* VT) {
  CommonClass* classDef = VT->cl;
  uint32 size = 0;
  if (classDef->isClass()) {
    LLVMClassInfo* LCI = getClassInfo(classDef->asClass());
    LCI->getVirtualType();
    size = classDef->asClass()->virtualTableSize;
  } else {
    size = JavaVirtualTable::getBaseSize();
  }
  llvm::Constant* res = 0;
  virtual_table_iterator End = virtualTables.end();
  virtual_table_iterator I = virtualTables.find(VT);
  if (I == End) {
    
    ArrayType* ATy = 
      dyn_cast<ArrayType>(JavaIntrinsics.VTType->getContainedType(0));
    PointerType* PTy = dyn_cast<PointerType>(ATy->getContainedType(0));
    ATy = ArrayType::get(PTy, size);
    std::string name(UTF8Buffer(classDef->name).toCompileName()->cString());
    name += "_VT";
    // Do not set a virtual table as a constant, because the runtime may
    // modify it.
    Module& Mod = *getLLVMModule();
    GlobalVariable* varGV = new GlobalVariable(Mod, ATy, false,
                                               GlobalValue::ExternalLinkage,
                                               0, name);
  
    res = ConstantExpr::getCast(Instruction::BitCast, varGV,
                                JavaIntrinsics.VTType);
    virtualTables.insert(std::make_pair(VT, res));
  
    if ((precompile && classDef->isPrimitive())
        || (!precompile && (isCompiling(classDef) || assumeCompiled))) {
      varGV->setInitializer(CreateConstantFromVT(VT));
    }
    
    return res;
  } else {
    return I->second;
  } 
}

Constant* JavaAOTCompiler::getNativeFunction(JavaMethod* meth, void* ptr) {
  llvm::Constant* varGV = 0;
  native_function_iterator End = nativeFunctions.end();
  native_function_iterator I = nativeFunctions.find(meth);
  if (I == End) {
    
    LLVMSignatureInfo* LSI = getSignatureInfo(meth->getSignature());
    llvm::Type* valPtrType = LSI->getNativePtrType();
    
    Module& Mod = *getLLVMModule();
    varGV = new GlobalVariable(Mod, valPtrType, false,
                               GlobalValue::InternalLinkage,
                               Constant::getNullValue(valPtrType), "");
  
    nativeFunctions.insert(std::make_pair(meth, varGV));
    return varGV;
  } else {
    return I->second;
  }
}

Constant* JavaAOTCompiler::CreateConstantForBaseObject(CommonClass* cl) {
  assert(!useCooperativeGC());
  StructType* STy = 
    dyn_cast<StructType>(JavaIntrinsics.JavaObjectType->getContainedType(0));
  
  std::vector<Constant*> Elmts;

  // VT
  Elmts.push_back(getVirtualTable(cl->virtualVT));
  
  // lock
//  Constant* L = ConstantInt::get(Type::getInt64Ty(getLLVMContext()), 0);
//  Elmts.push_back(ConstantExpr::getIntToPtr(L, JavaIntrinsics.ptrType));

  return ConstantStruct::get(STy, Elmts);
}

Constant* JavaAOTCompiler::CreateConstantFromJavaObject(JavaObject* obj) {
  JavaObject* val = 0;
  ArrayObject* array = 0;
  llvm_gcroot(obj, 0);
  llvm_gcroot(val, 0);
  llvm_gcroot(array, 0);

  assert(!useCooperativeGC());
  CommonClass* cl = JavaObject::getClass(obj);

  if (cl->isArray()) {
    Classpath* upcalls = cl->classLoader->bootstrapLoader->upcalls;
    CommonClass* subClass = cl->asArrayClass()->baseClass();
    if (subClass->isPrimitive()) {
      if (subClass == upcalls->OfBool) {
        return CreateConstantFromIntArray<ArrayUInt8>((ArrayUInt8*)obj,
                                        Type::getInt8Ty(getLLVMContext()));
      } else if (subClass == upcalls->OfByte) {
        return CreateConstantFromIntArray<ArraySInt8>((ArraySInt8*)obj,
                                        Type::getInt8Ty(getLLVMContext()));
      } else if (subClass == upcalls->OfShort) {
        return CreateConstantFromIntArray<ArraySInt16>((ArraySInt16*)obj,
                                        Type::getInt16Ty(getLLVMContext()));
      } else if (subClass == upcalls->OfChar) {
        return CreateConstantFromIntArray<ArrayUInt16>((ArrayUInt16*)obj,
                                        Type::getInt16Ty(getLLVMContext()));
      } else if (subClass == upcalls->OfInt) {
        return CreateConstantFromIntArray<ArraySInt32>((ArraySInt32*)obj,
                                        Type::getInt32Ty(getLLVMContext()));
      } else if (subClass == upcalls->OfFloat) {
        return CreateConstantFromFPArray<ArrayFloat>((ArrayFloat*)obj,
                                        Type::getFloatTy(getLLVMContext()));
      } else if (subClass == upcalls->OfLong) {
        return CreateConstantFromIntArray<ArrayLong>((ArrayLong*)obj,
                                        Type::getInt64Ty(getLLVMContext()));
      } else if (subClass == upcalls->OfDouble) {
        return CreateConstantFromFPArray<ArrayDouble>((ArrayDouble*)obj,
                                        Type::getDoubleTy(getLLVMContext()));
      } else {
        abort();
      }
    } else {
      array = (ArrayObject*)obj;
      return CreateConstantFromObjectArray(array);
    }
  } else {
    
    std::vector<Constant*> Elmts;
    
    // JavaObject
    Constant* CurConstant =
        CreateConstantForBaseObject(JavaObject::getClass(obj));

    for (uint32 j = 1; j <= cl->virtualVT->depth; ++j) {
      std::vector<Constant*> TempElts;
      Elmts.push_back(CurConstant);
      TempElts.push_back(CurConstant);
      Class* curCl = cl->virtualVT->display[j]->cl->asClass();
      LLVMClassInfo* LCI = getClassInfo(curCl);
      StructType* STy = 
        dyn_cast<StructType>(LCI->getVirtualType()->getContainedType(0));

      for (uint32 i = 0; i < curCl->nbVirtualFields; ++i) {
        JavaField& field = curCl->virtualFields[i];
        const Typedef* type = field.getSignature();
        if (type->isPrimitive()) {
          const PrimitiveTypedef* prim = (const PrimitiveTypedef*)type;
          if (prim->isBool() || prim->isByte()) {
            ConstantInt* CI = ConstantInt::get(Type::getInt8Ty(getLLVMContext()),
                                               field.getInstanceInt8Field(obj));
            TempElts.push_back(CI);
          } else if (prim->isShort() || prim->isChar()) {
            ConstantInt* CI = ConstantInt::get(Type::getInt16Ty(getLLVMContext()),
                                               field.getInstanceInt16Field(obj));
            TempElts.push_back(CI);
          } else if (prim->isInt()) {
            ConstantInt* CI = ConstantInt::get(Type::getInt32Ty(getLLVMContext()),
                                               field.getInstanceInt32Field(obj));
            TempElts.push_back(CI);
          } else if (prim->isLong()) {
            ConstantInt* CI = ConstantInt::get(Type::getInt64Ty(getLLVMContext()),
                                               field.getInstanceLongField(obj));
            TempElts.push_back(CI);
          } else if (prim->isFloat()) {
            Constant* CF = ConstantFP::get(Type::getFloatTy(getLLVMContext()),
                                           field.getInstanceFloatField(obj));
            TempElts.push_back(CF);
          } else if (prim->isDouble()) {
            Constant* CF = ConstantFP::get(Type::getDoubleTy(getLLVMContext()),
                                           field.getInstanceDoubleField(obj));
            TempElts.push_back(CF);
          } else {
            abort();
          }
        } else {
          val = field.getInstanceObjectField(obj);
          if (val) {
            JnjvmClassLoader* JCL = cl->classLoader;
            CommonClass* FieldCl = field.getSignature()->assocClass(JCL);
            Constant* C = getFinalObject(val, FieldCl);
            TempElts.push_back(C);
          } else {
            llvm::Type* Ty = JavaIntrinsics.JavaObjectType;
            TempElts.push_back(Constant::getNullValue(Ty));
          }
        }
      }
      CurConstant = ConstantStruct::get(STy, TempElts);
    }

    return CurConstant;
  }
}

Constant* JavaAOTCompiler::CreateConstantFromJavaString(JavaString* str) {
  llvm_gcroot(str, 0);

  assert(!useCooperativeGC());
  Class* cl = JavaObject::getClass(str)->asClass();
  LLVMClassInfo* LCI = getClassInfo(cl);
  StructType* STy = 
    dyn_cast<StructType>(LCI->getVirtualType()->getContainedType(0));

  std::vector<Constant*> Elmts;

  Elmts.push_back(CreateConstantForBaseObject(cl));

  Constant* Array =
    CreateConstantFromIntArray<ArrayUInt16>(JavaString::getValue(str),
                                            Type::getInt16Ty(getLLVMContext()));
  

  Module& Mod = *getLLVMModule();
  GlobalVariable* varGV = new GlobalVariable(Mod, Array->getType(), false,
                                             GlobalValue::InternalLinkage,
                                             Array, "");
 
	Array = ConstantExpr::getBitCast(varGV, JavaIntrinsics.JavaObjectType);

  Elmts.push_back(Array);
#ifndef USE_OPENJDK
  // Classpath fields
  Elmts.push_back(ConstantInt::get(Type::getInt32Ty(getLLVMContext()),
                                   str->count));
  Elmts.push_back(ConstantInt::get(Type::getInt32Ty(getLLVMContext()),
                                   str->cachedHashCode));
  Elmts.push_back(ConstantInt::get(Type::getInt32Ty(getLLVMContext()),
                                   str->offset));
#else
  // OpenJDK fields
  Elmts.push_back(ConstantInt::get(Type::getInt32Ty(getLLVMContext()),
                                   str->offset));
  Elmts.push_back(ConstantInt::get(Type::getInt32Ty(getLLVMContext()),
                                   str->count));
  Elmts.push_back(ConstantInt::get(Type::getInt32Ty(getLLVMContext()),
                                   str->cachedHashCode));
#endif
 
  return ConstantStruct::get(STy, Elmts);
}


Constant* JavaAOTCompiler::CreateConstantFromAttribute(JavaAttribute& attribute) {
  StructType* STy = 
    dyn_cast<StructType>(JavaIntrinsics.AttributeType->getContainedType(0));


  std::vector<Constant*> Elmts;

  // name
  Elmts.push_back(getUTF8(attribute.name));

  // start
  Elmts.push_back(ConstantInt::get(Type::getInt32Ty(getLLVMContext()), attribute.start));

  // nbb
  Elmts.push_back(ConstantInt::get(Type::getInt32Ty(getLLVMContext()), attribute.nbb));
  
  return ConstantStruct::get(STy, Elmts);
}

Constant* JavaAOTCompiler::CreateConstantFromCommonClass(CommonClass* cl) {
  StructType* STy = 
    dyn_cast<StructType>(JavaIntrinsics.JavaCommonClassType->getContainedType(0));
  Module& Mod = *getLLVMModule();
  
  llvm::Type* TempTy = NULL;

  std::vector<Constant*> CommonClassElts;
  std::vector<Constant*> TempElmts;

  // delegatee
  ArrayType* ATy = dyn_cast<ArrayType>(STy->getContainedType(0));
  assert(ATy && "Malformed type");

  Constant* TCM[1] = { getJavaClass(cl) };
  CommonClassElts.push_back(ConstantArray::get(ATy, TCM));
  
  // access
  CommonClassElts.push_back(ConstantInt::get(Type::getInt32Ty(getLLVMContext()), cl->access));
 
  // interfaces
  if (cl->nbInterfaces) {
    for (uint32 i = 0; i < cl->nbInterfaces; ++i) {
      TempElmts.push_back(getNativeClass(cl->interfaces[i]));
    }

    ATy = ArrayType::get(JavaIntrinsics.JavaClassType, cl->nbInterfaces);
    Constant* interfaces = ConstantArray::get(ATy, TempElmts);
    interfaces = new GlobalVariable(Mod, ATy, true,
                                    GlobalValue::InternalLinkage,
                                    interfaces, "");
    interfaces = ConstantExpr::getCast(Instruction::BitCast, interfaces,
                            PointerType::getUnqual(JavaIntrinsics.JavaClassType));

    CommonClassElts.push_back(interfaces);
  } else {
    Type* Ty = PointerType::getUnqual(JavaIntrinsics.JavaClassType);
    CommonClassElts.push_back(Constant::getNullValue(Ty));
  }

  // nbInterfaces
  CommonClassElts.push_back(ConstantInt::get(Type::getInt16Ty(getLLVMContext()), cl->nbInterfaces));

  // name
  CommonClassElts.push_back(getUTF8(cl->name));

  // super
  if (cl->super) {
    CommonClassElts.push_back(getNativeClass(cl->super));
  } else {
    TempTy = JavaIntrinsics.JavaClassType;
    CommonClassElts.push_back(Constant::getNullValue(TempTy));
  }

  CommonClassElts.push_back(Constant::getNullValue(JavaIntrinsics.ptrType));
  
  // virtualTable
  if (cl->virtualVT) {
    CommonClassElts.push_back(getVirtualTable(cl->virtualVT));
  } else {
    TempTy = JavaIntrinsics.VTType;
    CommonClassElts.push_back(Constant::getNullValue(TempTy));
  }
  return ConstantStruct::get(STy, CommonClassElts);
}

Constant* JavaAOTCompiler::CreateConstantFromJavaField(JavaField& field) {
  StructType* STy = 
    dyn_cast<StructType>(JavaIntrinsics.JavaFieldType->getContainedType(0));
  
  std::vector<Constant*> FieldElts;
  std::vector<Constant*> TempElts;
  
  // signature
  FieldElts.push_back(Constant::getNullValue(JavaIntrinsics.ptrType));
  
  // access
  FieldElts.push_back(ConstantInt::get(Type::getInt16Ty(getLLVMContext()), field.access));

  // name
  FieldElts.push_back(getUTF8(field.name));

  // type
  FieldElts.push_back(getUTF8(field.type));
  
  // attributes
  if (field.nbAttributes) {
    llvm::Type* AttrTy = JavaIntrinsics.AttributeType->getContainedType(0);
    ArrayType* ATy = ArrayType::get(AttrTy, field.nbAttributes);
    for (uint32 i = 0; i < field.nbAttributes; ++i) {
      TempElts.push_back(CreateConstantFromAttribute(field.attributes[i]));
    }

    Constant* attributes = ConstantArray::get(ATy, TempElts);
    TempElts.clear();
    attributes = new GlobalVariable(*getLLVMModule(), ATy, true,
                                   GlobalValue::InternalLinkage,
                                   attributes, "");
    attributes = ConstantExpr::getCast(Instruction::BitCast, attributes,
                                      JavaIntrinsics.AttributeType);
  
    FieldElts.push_back(attributes);
  } else {
    FieldElts.push_back(Constant::getNullValue(JavaIntrinsics.AttributeType));
  }
  
  // nbAttributes
  FieldElts.push_back(ConstantInt::get(Type::getInt16Ty(getLLVMContext()), field.nbAttributes));

  // classDef
  FieldElts.push_back(getNativeClass(field.classDef));

  // ptrOffset
  FieldElts.push_back(ConstantInt::get(Type::getInt32Ty(getLLVMContext()), field.ptrOffset));

  // num
  FieldElts.push_back(ConstantInt::get(Type::getInt16Ty(getLLVMContext()), field.num));

  return ConstantStruct::get(STy, FieldElts); 
}

Constant* JavaAOTCompiler::CreateConstantFromJavaMethod(JavaMethod& method) {
  StructType* STy = 
    dyn_cast<StructType>(JavaIntrinsics.JavaMethodType->getContainedType(0));
  Module& Mod = *getLLVMModule();
  
  std::vector<Constant*> MethodElts;
  std::vector<Constant*> TempElts;
  
  // signature
  MethodElts.push_back(Constant::getNullValue(JavaIntrinsics.ptrType));
  
  // access
  MethodElts.push_back(ConstantInt::get(Type::getInt16Ty(getLLVMContext()), method.access));
 
  // attributes
  if (method.nbAttributes) {
    llvm::Type* AttrTy = JavaIntrinsics.AttributeType->getContainedType(0);
    ArrayType* ATy = ArrayType::get(AttrTy, method.nbAttributes);
    for (uint32 i = 0; i < method.nbAttributes; ++i) {
      TempElts.push_back(CreateConstantFromAttribute(method.attributes[i]));
    }

    Constant* attributes = ConstantArray::get(ATy, TempElts);
    TempElts.clear();
    attributes = new GlobalVariable(Mod, ATy, true,
                                   GlobalValue::InternalLinkage,
                                   attributes, "");
    attributes = ConstantExpr::getCast(Instruction::BitCast, attributes,
                                      JavaIntrinsics.AttributeType);

    MethodElts.push_back(attributes);
  } else {
    MethodElts.push_back(Constant::getNullValue(JavaIntrinsics.AttributeType));
  }
  
  // nbAttributes
  MethodElts.push_back(ConstantInt::get(Type::getInt16Ty(getLLVMContext()), method.nbAttributes));
  
  // classDef
  MethodElts.push_back(getNativeClass(method.classDef));
  
  // name
  MethodElts.push_back(getUTF8(method.name));

  // type
  MethodElts.push_back(getUTF8(method.type));
  
  // canBeInlined
  MethodElts.push_back(ConstantInt::get(Type::getInt8Ty(getLLVMContext()), method.isCustomizable));

  // code
  if (getMethodInfo(&method)->methodFunction == NULL) {
    MethodElts.push_back(Constant::getNullValue(JavaIntrinsics.ptrType));
  } else {
    assert(!isAbstract(method.access));
    Function* func = getMethod(&method, NULL);
    MethodElts.push_back(ConstantExpr::getCast(Instruction::BitCast, func,
                                               JavaIntrinsics.ptrType));
  }
  
  // offset
  MethodElts.push_back(ConstantInt::get(Type::getInt32Ty(getLLVMContext()), method.offset));

  return ConstantStruct::get(STy, MethodElts); 
}

Constant* JavaAOTCompiler::CreateConstantFromClassPrimitive(ClassPrimitive* cl) {
  llvm::Type* JCPTy = 
    JavaIntrinsics.JavaClassPrimitiveType->getContainedType(0);
  StructType* STy = dyn_cast<StructType>(JCPTy);
  
  std::vector<Constant*> ClassElts;
  
  // common class
  ClassElts.push_back(CreateConstantFromCommonClass(cl));

  // primSize
  ClassElts.push_back(ConstantInt::get(Type::getInt32Ty(getLLVMContext()), cl->logSize));

  return ConstantStruct::get(STy, ClassElts);
}

Constant* JavaAOTCompiler::CreateConstantFromClassArray(ClassArray* cl) {
  StructType* STy = 
    dyn_cast<StructType>(JavaIntrinsics.JavaClassArrayType->getContainedType(0));
  
  std::vector<Constant*> ClassElts;
  Constant* ClGEPs[2] = { getIntrinsics()->constantZero,
                          getIntrinsics()->constantZero };
  
  // common class
  ClassElts.push_back(CreateConstantFromCommonClass(cl));

  // baseClass
  Constant* Cl = getNativeClass(cl->baseClass());
  if (Cl->getType() != JavaIntrinsics.JavaCommonClassType)
    Cl = ConstantExpr::getGetElementPtr(Cl, ClGEPs, 2);
    
  ClassElts.push_back(Cl);
  
  return ConstantStruct::get(STy, ClassElts);
}

Constant* JavaAOTCompiler::CreateConstantFromClassMap(const vmkit::VmkitDenseMap<const UTF8*, CommonClass*>& map) {
  StructType* STy = 
    dyn_cast<StructType>(JavaIntrinsics.J3DenseMapType->getContainedType(0));
  Module& Mod = *getLLVMModule();

  std::vector<Constant*> elements;
  elements.push_back(ConstantInt::get(Type::getInt32Ty(getLLVMContext()), map.NumBuckets));

  Constant* buckets;
  if (map.NumBuckets > 0) {
    std::vector<Constant*> TempElts;
    ArrayType* ATy = ArrayType::get(JavaIntrinsics.ptrType, map.NumBuckets * 2);

    for (uint32 i = 0; i < map.NumBuckets; ++i) {
      vmkit::VmkitPair<const UTF8*, CommonClass*> pair = map.Buckets[i];
      if (pair.first == &vmkit::TombstoneKey) {
        TempElts.push_back(ConstantExpr::getCast(Instruction::BitCast, UTF8TombstoneGV, JavaIntrinsics.ptrType));
        TempElts.push_back(Constant::getNullValue(JavaIntrinsics.ptrType));
      } else if (pair.first == &vmkit::EmptyKey) {
        TempElts.push_back(ConstantExpr::getCast(Instruction::BitCast, UTF8EmptyGV, JavaIntrinsics.ptrType));
        TempElts.push_back(Constant::getNullValue(JavaIntrinsics.ptrType));
      } else {
        TempElts.push_back(ConstantExpr::getCast(Instruction::BitCast, getUTF8(pair.first), JavaIntrinsics.ptrType));
        TempElts.push_back(ConstantExpr::getCast(Instruction::BitCast, getNativeClass(pair.second), JavaIntrinsics.ptrType));
      }
    }

    buckets = ConstantArray::get(ATy, TempElts);

    GlobalVariable* gv = new GlobalVariable(Mod, ATy, false, GlobalValue::InternalLinkage, buckets, "");
    buckets = ConstantExpr::getCast(Instruction::BitCast, gv, JavaIntrinsics.ptrType);
  } else {
    buckets = Constant::getNullValue(JavaIntrinsics.ptrType);
  }

  elements.push_back(buckets);
  elements.push_back(ConstantInt::get(Type::getInt32Ty(getLLVMContext()), map.NumEntries));
  elements.push_back(ConstantInt::get(Type::getInt32Ty(getLLVMContext()), map.NumTombstones));
  elements.push_back(ConstantInt::get(Type::getInt1Ty(getLLVMContext()), 1));

  return new GlobalVariable(Mod, STy, false,
                            GlobalValue::ExternalLinkage,
                            ConstantStruct::get(STy, elements), "ClassMap");
}

Constant* JavaAOTCompiler::CreateConstantFromUTF8Map(const vmkit::VmkitDenseSet<vmkit::UTF8MapKey, const UTF8*>& set) {
  StructType* STy = 
    dyn_cast<StructType>(JavaIntrinsics.J3DenseMapType->getContainedType(0));
  Module& Mod = *getLLVMModule();

  std::vector<Constant*> elements;
  elements.push_back(ConstantInt::get(Type::getInt32Ty(getLLVMContext()), set.NumBuckets));

  Constant* buckets;
  if (set.NumBuckets > 0) {
    std::vector<Constant*> TempElts;
    ArrayType* ATy = ArrayType::get(JavaIntrinsics.ptrType, set.NumBuckets);

    for (uint32 i = 0; i < set.NumBuckets; ++i) {
      const UTF8* utf8 = set.Buckets[i];
      if (utf8 == &vmkit::EmptyKey) {
        TempElts.push_back(ConstantExpr::getCast(Instruction::BitCast, UTF8EmptyGV, JavaIntrinsics.ptrType));
      } else if (utf8 == &vmkit::TombstoneKey) {
        TempElts.push_back(ConstantExpr::getCast(Instruction::BitCast, UTF8TombstoneGV, JavaIntrinsics.ptrType));
      } else {
        TempElts.push_back(ConstantExpr::getCast(Instruction::BitCast, getUTF8(utf8), JavaIntrinsics.ptrType));
      }
    }

    buckets = ConstantArray::get(ATy, TempElts);

    GlobalVariable* gv = new GlobalVariable(Mod, ATy, false, GlobalValue::InternalLinkage, buckets, "");
    buckets = ConstantExpr::getCast(Instruction::BitCast, gv, JavaIntrinsics.ptrType);
  } else {
    buckets = Constant::getNullValue(JavaIntrinsics.ptrType);
  }

  elements.push_back(buckets);
  elements.push_back(ConstantInt::get(Type::getInt32Ty(getLLVMContext()), set.NumEntries));
  elements.push_back(ConstantInt::get(Type::getInt32Ty(getLLVMContext()), set.NumTombstones));
  elements.push_back(ConstantInt::get(Type::getInt1Ty(getLLVMContext()), 1));

  return new GlobalVariable(Mod, STy, false,
                            GlobalValue::ExternalLinkage,
                            ConstantStruct::get(STy, elements), "UTF8Map");
}

Constant* JavaAOTCompiler::CreateConstantFromClass(Class* cl) {
  StructType* STy = 
    dyn_cast<StructType>(JavaIntrinsics.JavaClassType->getContainedType(0));
  Module& Mod = *getLLVMModule();
  
  std::vector<Constant*> ClassElts;
  std::vector<Constant*> TempElts;

  // common class
  ClassElts.push_back(CreateConstantFromCommonClass(cl));

  // virtualSize
  ClassElts.push_back(ConstantInt::get(Type::getInt32Ty(getLLVMContext()),
                                       cl->virtualSize));
  
  // alginment
  ClassElts.push_back(ConstantInt::get(Type::getInt32Ty(getLLVMContext()),
                                       cl->alignment));

  // IsolateInfo
  ArrayType* ATy = dyn_cast<ArrayType>(STy->getContainedType(3));
  assert(ATy && "Malformed type");
  
  StructType* TCMTy = dyn_cast<StructType>(ATy->getContainedType(0));
  assert(TCMTy && "Malformed type");

  TempElts.push_back(ConstantInt::get(Type::getInt8Ty(getLLVMContext()),
                                      cl->getInitializationState()));
  TempElts.push_back(ConstantInt::get(Type::getInt1Ty(getLLVMContext()),
                                      cl->isReady() ? 1 : 0));
  TempElts.push_back(getStaticInstance(cl));
  Constant* CStr[1] = { ConstantStruct::get(TCMTy, TempElts) };
  TempElts.clear();
  ClassElts.push_back(ConstantArray::get(ATy, CStr));

  if (cl->nbVirtualFields + cl->nbStaticFields) {
    ATy = ArrayType::get(JavaIntrinsics.JavaFieldType->getContainedType(0),
                         cl->nbVirtualFields + cl->nbStaticFields);
  }

  // virtualFields
  if (cl->nbVirtualFields) {
    for (uint32 i = 0; i < cl->nbVirtualFields; ++i) {
      TempElts.push_back(CreateConstantFromJavaField(cl->virtualFields[i]));
    }
  } 
  
  // staticFields
  if (cl->nbStaticFields) {
    for (uint32 i = 0; i < cl->nbStaticFields; ++i) {
      TempElts.push_back(CreateConstantFromJavaField(cl->staticFields[i]));
    }
  }

  Constant* fields = 0;
  if (cl->nbStaticFields + cl->nbVirtualFields) {
    fields = ConstantArray::get(ATy, TempElts);
    TempElts.clear();
    fields = new GlobalVariable(Mod, ATy, false,
                                GlobalValue::InternalLinkage,
                                fields, "");
    fields = ConstantExpr::getCast(Instruction::BitCast, fields,
                                   JavaIntrinsics.JavaFieldType);
  } else {
    fields = Constant::getNullValue(JavaIntrinsics.JavaFieldType);
  }

  // virtualFields
  ClassElts.push_back(fields);

  ConstantInt* nbVirtualFields = 
    ConstantInt::get(Type::getInt16Ty(getLLVMContext()), cl->nbVirtualFields);
  // nbVirtualFields
  ClassElts.push_back(nbVirtualFields);
  
  // staticFields
  ClassElts.push_back(ConstantExpr::getGetElementPtr(fields, nbVirtualFields));

  // nbStaticFields
  ClassElts.push_back(ConstantInt::get(Type::getInt16Ty(getLLVMContext()), cl->nbStaticFields));
  
  // virtualMethods
  if (cl->nbVirtualMethods + cl->nbStaticMethods) {
    ATy = ArrayType::get(JavaIntrinsics.JavaMethodType->getContainedType(0),
                         cl->nbVirtualMethods + cl->nbStaticMethods);
  }

  if (cl->nbVirtualMethods) {
    for (uint32 i = 0; i < cl->nbVirtualMethods; ++i) {
      TempElts.push_back(CreateConstantFromJavaMethod(cl->virtualMethods[i]));
    }
  }
    
  if (cl->nbStaticMethods) {
    for (uint32 i = 0; i < cl->nbStaticMethods; ++i) {
      TempElts.push_back(CreateConstantFromJavaMethod(cl->staticMethods[i]));
    }
  }

  Constant* methods = 0;
  if (cl->nbVirtualMethods + cl->nbStaticMethods) {
    methods = ConstantArray::get(ATy, TempElts);
    TempElts.clear();

    GlobalVariable* GV = NULL;
    method_iterator SI = virtualMethods.find(cl);
    if (SI != virtualMethods.end()) {
      GV = dyn_cast<GlobalVariable>(SI->second);
      GV->setInitializer(methods);
    } else {
      std::string name(UTF8Buffer(cl->name).toCompileName()->cString());
      name += "_VirtualMethods";
      GV = new GlobalVariable(Mod, ATy, false, GlobalValue::ExternalLinkage,
                              methods, name);
      virtualMethods.insert(std::make_pair(cl, GV));
    }
    methods = ConstantExpr::getCast(Instruction::BitCast, GV,
                                    JavaIntrinsics.JavaMethodType);
  } else {
    methods = Constant::getNullValue(JavaIntrinsics.JavaMethodType);
  }

  // virtualMethods
  ClassElts.push_back(methods);

  ConstantInt* nbVirtualMethods = 
    ConstantInt::get(Type::getInt16Ty(getLLVMContext()), cl->nbVirtualMethods);
  // nbVirtualMethods
  ClassElts.push_back(nbVirtualMethods);
  
  // staticMethods
  ClassElts.push_back(ConstantExpr::getGetElementPtr(methods, nbVirtualMethods));

  // nbStaticMethods
  ClassElts.push_back(ConstantInt::get(Type::getInt16Ty(getLLVMContext()), cl->nbStaticMethods));

  // ownerClass
  ClassElts.push_back(Constant::getNullValue(JavaIntrinsics.ptrType));
  
  // bytes 
  if (precompile) {
    ClassElts.push_back(ConstantExpr::getBitCast(getClassBytes(cl->name, cl->bytes),
                                                 JavaIntrinsics.ClassBytesType));
  } else {
    ClassElts.push_back(Constant::getNullValue(JavaIntrinsics.ClassBytesType));
  }

  // ctpInfo
  Constant* ctpInfo = CreateConstantFromJavaConstantPool(cl->ctpInfo);
  Constant* varGV = new GlobalVariable(*getLLVMModule(), ctpInfo->getType(), false,
                                       GlobalValue::InternalLinkage,
                                       ctpInfo, "");
  ClassElts.push_back(varGV);

  // attributes
  if (cl->nbAttributes) {
    ATy = ArrayType::get(JavaIntrinsics.AttributeType->getContainedType(0),
                         cl->nbAttributes);

    for (uint32 i = 0; i < cl->nbAttributes; ++i) {
      TempElts.push_back(CreateConstantFromAttribute(cl->attributes[i]));
    }

    Constant* attributes = ConstantArray::get(ATy, TempElts);
    TempElts.clear();
    attributes = new GlobalVariable(*getLLVMModule(), ATy, true,
                                   GlobalValue::InternalLinkage,
                                   attributes, "");
    attributes = ConstantExpr::getCast(Instruction::BitCast, attributes,
                                      JavaIntrinsics.AttributeType);
    ClassElts.push_back(attributes);
  } else {
    ClassElts.push_back(Constant::getNullValue(JavaIntrinsics.AttributeType));
  }
  
  // nbAttributes
  ClassElts.push_back(ConstantInt::get(Type::getInt16Ty(getLLVMContext()), cl->nbAttributes));
  
  // innerClasses
  if (cl->nbInnerClasses) {
    for (uint32 i = 0; i < cl->nbInnerClasses; ++i) {
      TempElts.push_back(getNativeClass(cl->innerClasses[i]));
    }

    llvm::Type* TempTy = JavaIntrinsics.JavaClassType;
    ATy = ArrayType::get(TempTy, cl->nbInnerClasses);
    Constant* innerClasses = ConstantArray::get(ATy, TempElts);
    innerClasses = new GlobalVariable(*getLLVMModule(), ATy, true,
                                      GlobalValue::InternalLinkage,
                                      innerClasses, "");
    innerClasses = ConstantExpr::getCast(Instruction::BitCast, innerClasses,
                                         PointerType::getUnqual(TempTy));

    ClassElts.push_back(innerClasses);
  } else {
    Type* Ty = PointerType::getUnqual(JavaIntrinsics.JavaClassType);
    ClassElts.push_back(Constant::getNullValue(Ty));
  }

  // nbInnerClasses
  ClassElts.push_back(ConstantInt::get(Type::getInt16Ty(getLLVMContext()), cl->nbInnerClasses));

  // outerClass
  if (cl->outerClass) {
    ClassElts.push_back(getNativeClass(cl->outerClass));
  } else {
    ClassElts.push_back(Constant::getNullValue(JavaIntrinsics.JavaClassType));
  }

  // innerAccess
  ClassElts.push_back(ConstantInt::get(Type::getInt16Ty(getLLVMContext()), cl->innerAccess));
  
  // innerOuterResolved
  ClassElts.push_back(ConstantInt::get(Type::getInt8Ty(getLLVMContext()), cl->innerOuterResolved));
  
  // isAnonymous
  ClassElts.push_back(ConstantInt::get(Type::getInt8Ty(getLLVMContext()), cl->isAnonymous));
  
  // virtualTableSize
  ClassElts.push_back(ConstantInt::get(Type::getInt32Ty(getLLVMContext()), cl->virtualTableSize));
  
  // staticSize
  ClassElts.push_back(ConstantInt::get(Type::getInt32Ty(getLLVMContext()), cl->staticSize));

  // minJDKVersionMajor
  ClassElts.push_back(ConstantInt::get(Type::getInt16Ty(getLLVMContext()), cl->minJDKVersionMajor));

  // minJDKVersionMinor
  ClassElts.push_back(ConstantInt::get(Type::getInt16Ty(getLLVMContext()), cl->minJDKVersionMinor));

  // minJDKVersionBuild
  ClassElts.push_back(ConstantInt::get(Type::getInt16Ty(getLLVMContext()), cl->minJDKVersionBuild));

  return ConstantStruct::get(STy, ClassElts);
}

Constant* JavaAOTCompiler::CreateConstantFromClassBytes(ClassBytes* bytes) {
  std::vector<Type*> Elemts;
  ArrayType* ATy = ArrayType::get(Type::getInt8Ty(getLLVMContext()), bytes->size);
  Elemts.push_back(Type::getInt32Ty(getLLVMContext()));
  Elemts.push_back(ATy);

  StructType* STy = StructType::get(getLLVMContext(), Elemts);
  
  std::vector<Constant*> Cts;
  Cts.push_back(ConstantInt::get(Type::getInt32Ty(getLLVMContext()), bytes->size));
  
  std::vector<Constant*> Vals;
  for (uint32 i = 0; i < bytes->size; ++i) {
    Vals.push_back(ConstantInt::get(Type::getInt8Ty(getLLVMContext()), bytes->elements[i]));
  }

  Cts.push_back(ConstantArray::get(ATy, Vals));
  
  return ConstantStruct::get(STy, Cts);
}

template<typename T>
Constant* JavaAOTCompiler::CreateConstantFromIntArray(const T* val, Type* Ty) {
  assert(!useCooperativeGC());
  std::vector<Type*> Elemts;
  ArrayType* ATy = ArrayType::get(Ty, T::getSize(val));
  Elemts.push_back(JavaIntrinsics.JavaObjectType->getContainedType(0));
  Elemts.push_back(JavaIntrinsics.pointerSizeType);
  

  Elemts.push_back(ATy);

  StructType* STy = StructType::get(getLLVMModule()->getContext(), Elemts);
  
  std::vector<Constant*> Cts;
  Cts.push_back(CreateConstantForBaseObject(JavaObject::getClass(val)));
  Cts.push_back(ConstantInt::get(JavaIntrinsics.pointerSizeType, T::getSize(val)));
  
  std::vector<Constant*> Vals;
  for (sint32 i = 0; i < T::getSize(val); ++i) {
    Vals.push_back(ConstantInt::get(Ty, (uint64)T::getElement(val, i)));
  }

  Cts.push_back(ConstantArray::get(ATy, Vals));
  
  return ConstantStruct::get(STy, Cts);
}

template<typename T>
Constant* JavaAOTCompiler::CreateConstantFromFPArray(const T* val, Type* Ty) {
  assert(!useCooperativeGC());
  std::vector<Type*> Elemts;
  ArrayType* ATy = ArrayType::get(Ty, T::getSize(val));
  Elemts.push_back(JavaIntrinsics.JavaObjectType->getContainedType(0));
  Elemts.push_back(JavaIntrinsics.pointerSizeType);
  

  Elemts.push_back(ATy);

  StructType* STy = StructType::get(getLLVMModule()->getContext(), Elemts);
  
  std::vector<Constant*> Cts;
  Cts.push_back(CreateConstantForBaseObject(JavaObject::getClass(val)));
  Cts.push_back(ConstantInt::get(JavaIntrinsics.pointerSizeType, T::getSize(val)));
  
  std::vector<Constant*> Vals;
  for (sint32 i = 0; i < T::getSize(val); ++i) {
    Vals.push_back(ConstantFP::get(Ty, (double)T::getElement(val, i)));
  }

  Cts.push_back(ConstantArray::get(ATy, Vals));
  
  return ConstantStruct::get(STy, Cts);
}

Constant* JavaAOTCompiler::CreateConstantFromObjectArray(const ArrayObject* val) {
  JavaObject* obj = 0;
  llvm_gcroot(obj, 0);
  llvm_gcroot(val, 0);
  assert(!useCooperativeGC());
  std::vector<Type*> Elemts;
  llvm::Type* Ty = JavaIntrinsics.JavaObjectType;
  ArrayType* ATy = ArrayType::get(Ty, ArrayObject::getSize(val));
  Elemts.push_back(JavaIntrinsics.JavaObjectType->getContainedType(0));
  Elemts.push_back(JavaIntrinsics.pointerSizeType);
  

  Elemts.push_back(ATy);

  StructType* STy = StructType::get(getLLVMModule()->getContext(), Elemts);
  
  std::vector<Constant*> Cts;
  Cts.push_back(CreateConstantForBaseObject(JavaObject::getClass(val)));
  Cts.push_back(ConstantInt::get(JavaIntrinsics.pointerSizeType,
        ArrayObject::getSize(val)));
  
  std::vector<Constant*> Vals;
  for (sint32 i = 0; i < ArrayObject::getSize(val); ++i) {
    obj = ArrayObject::getElement(val, i);
    if (obj) {
      Vals.push_back(getFinalObject(obj,
          JavaObject::getClass(val)->asArrayClass()->baseClass()));
    } else {
      Vals.push_back(Constant::getNullValue(JavaIntrinsics.JavaObjectType));
    }
  }

  Cts.push_back(ConstantArray::get(ATy, Vals));
  
  return ConstantStruct::get(STy, Cts);
}

Constant* JavaAOTCompiler::CreateConstantFromUTF8(const UTF8* val) {
  std::vector<Type*> Elemts;
  ArrayType* ATy = ArrayType::get(Type::getInt16Ty(getLLVMContext()), val->size);
  Elemts.push_back(JavaIntrinsics.UTF8SizeType);

  Elemts.push_back(ATy);

  StructType* STy = StructType::get(getLLVMModule()->getContext(),
                                          Elemts);

  std::vector<Constant*> Cts;
  Cts.push_back(ConstantInt::get(JavaIntrinsics.UTF8SizeType, val->size));

  ArrayRef<uint16_t> Vals(val->elements, val->size);
  Cts.push_back(ConstantDataArray::get(getLLVMContext(), Vals));

  return ConstantStruct::get(STy, Cts);

}

Constant* JavaAOTCompiler::getUTF8(const UTF8* val) {
  utf8_iterator End = utf8s.end();
  utf8_iterator I = utf8s.find(val);
  if (I == End) {
    Constant* C = CreateConstantFromUTF8(val);
    Module& Mod = *getLLVMModule();
    GlobalVariable* varGV = new GlobalVariable(Mod, C->getType(), true,
                                               GlobalValue::InternalLinkage,
                                               C, "");
    
    Constant* res = ConstantExpr::getCast(Instruction::BitCast, varGV,
                                          JavaIntrinsics.UTF8Type);
    utf8s.insert(std::make_pair(val, res));

    return res;
  } else {
    return I->second;
  }
}

Function* JavaAOTCompiler::getMethodOrStub(JavaMethod* meth, Class* customizeFor) {
  assert(!isStatic(meth->access));
  LLVMMethodInfo* LMI = getMethodInfo(meth);
  LLVMSignatureInfo* LSI = getSignatureInfo(meth->getSignature());
  if (precompile) {
    if (customizeFor != NULL) {
      if (LMI->isCustomizable) {
        if (LMI->customizedVersions[customizeFor] != NULL) {
          // We have a customized version, get it.
          return getMethod(meth, customizeFor);
        } else {
          // No customized version, even if there is an uncustomized version,
          // we return the stub, so that we get a customized version at
          // runtime.
          return LSI->getVirtualStub();
        }
      } else {
        // If we have created a method for it, we know the method is not customizable,
        // and we can use the 'general' method.
        if (LMI->methodFunction) {
          return getMethod(meth, NULL);
        } else {
          // Otherwise, no method has been created for it.
          return LSI->getVirtualStub();
        }
      }
    } else {
      // If we have created a method for it, take it.
      if (LMI->methodFunction) {
        return getMethod(meth, NULL);
      } else {
        // Otherwise, no method has been created for it.
        return LSI->getVirtualStub();
      }
    }
  } else {
    // We're not precompiling, get the method.
    return getMethod(meth, NULL);
  }
}

Function* JavaAOTCompiler::getMethod(JavaMethod* meth, Class* customizeFor) {
  Function* func = getMethodInfo(meth)->getMethod(customizeFor);
  if (func->hasExternalWeakLinkage()) {
    toCompile.push_back(std::make_pair(meth, customizeFor));
  }
  return func;
}

Constant* JavaAOTCompiler::CreateConstantFromVT(JavaVirtualTable* VT) {
  CommonClass* classDef = VT->cl;
  uint32 size = classDef->isClass() ? classDef->asClass()->virtualTableSize :
                                      JavaVirtualTable::getBaseSize();
  JavaVirtualTable* RealVT = classDef->isClass() ? 
    VT : ClassArray::SuperArray->virtualVT;

  Class* maybeCustomize = classDef->isClass() ? classDef->asClass() : NULL;

  ArrayType* ATy = 
    dyn_cast<ArrayType>(JavaIntrinsics.VTType->getContainedType(0));
  PointerType* PTy = dyn_cast<PointerType>(ATy->getContainedType(0));
  ATy = ArrayType::get(PTy, size);

  ConstantPointerNull* N = ConstantPointerNull::get(PTy);
  std::vector<Constant*> Elemts;
   
  // Destructor
  Function* Finalizer = NULL;
  if (VT->hasDestructor()) {
    JavaMethod* meth = (JavaMethod*)(RealVT->destructor);
    Finalizer = getMethodOrStub(meth, maybeCustomize);
  } else {
    Finalizer = EmptyDestructorFunction;
  }
  
  Elemts.push_back(ConstantExpr::getCast(Instruction::BitCast, Finalizer, PTy));
  
  // Delete
  Elemts.push_back(N);
  
  // Tracer
  Function* Tracer = 0;
  if (classDef->isArray()) {
    if (classDef->asArrayClass()->baseClass()->isPrimitive()) {
      Tracer = JavaObjectTracer;
    } else {
      Tracer = ArrayObjectTracer;
    }
  } else if (classDef->isClass()) {
    if (classDef->isSubclassOf(
          classDef->classLoader->bootstrapLoader->upcalls->newReference)) {
      Tracer = ReferenceObjectTracer;
    } else {
      Tracer = RegularObjectTracer;
    }
  }

  Elemts.push_back(Tracer ? 
      ConstantExpr::getCast(Instruction::BitCast, Tracer, PTy) : N);
  
  for (uint32_t i = 0; i < VirtualTable::numberOfSpecializedTracers(); i++) {
    // Push null for now.
    Elemts.push_back(N);
  }

  // Class
  Elemts.push_back(ConstantExpr::getCast(Instruction::BitCast,
                                         getNativeClass(classDef), PTy));

  // depth
  Elemts.push_back(ConstantExpr::getIntToPtr(
        ConstantInt::get(Type::getInt64Ty(getLLVMContext()), VT->depth), PTy));
  
  // offset
  Elemts.push_back(ConstantExpr::getIntToPtr(
        ConstantInt::get(Type::getInt64Ty(getLLVMContext()), VT->offset), PTy));
  
  // cache
  Elemts.push_back(N);
  
  // display
  for (uint32 i = 0; i < JavaVirtualTable::getDisplayLength(); ++i) {
    if (VT->display[i]) {
      Constant* Temp = getVirtualTable(VT->display[i]);
      Temp = ConstantExpr::getBitCast(Temp, PTy);
      Elemts.push_back(Temp);
    } else {
      Elemts.push_back(Constant::getNullValue(PTy));
    }
  }
  
  // nbSecondaryTypes
  Elemts.push_back(ConstantExpr::getIntToPtr(
        ConstantInt::get(Type::getInt64Ty(getLLVMContext()), VT->nbSecondaryTypes), PTy));
  
  // secondaryTypes
  ArrayType* DTy = ArrayType::get(JavaIntrinsics.VTType,
                                  VT->nbSecondaryTypes);
  
  std::vector<Constant*> TempElmts;
  for (uint32 i = 0; i < VT->nbSecondaryTypes; ++i) {
    assert(VT->secondaryTypes[i] && "No secondary type");
    Constant* Cl = getVirtualTable(VT->secondaryTypes[i]);
    TempElmts.push_back(Cl);
  }
  Constant* display = ConstantArray::get(DTy, TempElmts);
  TempElmts.clear();
  
  display = new GlobalVariable(*getLLVMModule(), DTy, true,
                               GlobalValue::InternalLinkage,
                               display, "");

  display = ConstantExpr::getCast(Instruction::BitCast, display, PTy);
  
  Elemts.push_back(display);
    
  // baseClassVT
  if (VT->baseClassVT) {
    Constant* Temp = getVirtualTable(VT->baseClassVT);
    Temp = ConstantExpr::getBitCast(Temp, PTy);
    Elemts.push_back(Temp);
  } else {
    Elemts.push_back(Constant::getNullValue(PTy));
  }
   
  // IMT
  if (!VT->IMT) {
    Elemts.push_back(Constant::getNullValue(PTy));
  } else {
    // TODO: add a null element at the end to diagnose errors.
    Class* cl = classDef->asClass();
    assert(cl && "Not a class");
    std::set<JavaMethod*> contents[InterfaceMethodTable::NumIndexes];
    classDef->asClass()->fillIMT(contents);
  

    ArrayType* ATy = 
      dyn_cast<ArrayType>(JavaIntrinsics.VTType->getContainedType(0));
    PointerType* PTy = dyn_cast<PointerType>(ATy->getContainedType(0));
    ATy = ArrayType::get(PTy, InterfaceMethodTable::NumIndexes);
  
    ConstantPointerNull* N = ConstantPointerNull::get(PTy);
    std::vector<Constant*> IElemts;

    for (uint32_t i = 0; i < InterfaceMethodTable::NumIndexes; ++i) {
      std::set<JavaMethod*>& atIndex = contents[i];
      uint32_t size = atIndex.size();
      if (size == 1) {
        JavaMethod* Imeth = *(atIndex.begin());
        JavaMethod* meth = cl->lookupMethodDontThrow(Imeth->name,
                                                     Imeth->type,
                                                     false, true, 0);
        assert(meth && "No method found");
        Function* func = getMethodOrStub(meth, maybeCustomize);
        IElemts.push_back(ConstantExpr::getBitCast(func, PTy));
      } else if (size > 1) {
        std::vector<JavaMethod*> methods;
        bool SameMethod = true;
        JavaMethod* OldMethod = 0;
      
        for (std::set<JavaMethod*>::iterator it = atIndex.begin(),
             et = atIndex.end(); it != et; ++it) {
          JavaMethod* Imeth = *it;
          JavaMethod* Cmeth = cl->lookupMethodDontThrow(Imeth->name, Imeth->type,
                                                      false, true, 0);
       
          if (OldMethod && OldMethod != Cmeth) SameMethod = false;
          else OldMethod = Cmeth;
        
          methods.push_back(Cmeth);
        }

        if (SameMethod) {
          assert(methods[0] && "No method found");
          Function* func = getMethodOrStub(methods[0], maybeCustomize);
          IElemts.push_back(ConstantExpr::getBitCast(func, PTy));
        } else {

          uint32_t length = 2 * size;
        
          ArrayType* ATy = 
            dyn_cast<ArrayType>(JavaIntrinsics.VTType->getContainedType(0));
          ATy = ArrayType::get(PTy, length);
          std::vector<Constant*> InternalElemts;
     

          std::set<JavaMethod*>::iterator Interf = atIndex.begin();
          for (std::vector<JavaMethod*>::iterator it = methods.begin(),
               et = methods.end(); it != et; ++it, ++Interf) {
            JavaMethod* Imeth = *Interf;
            JavaMethod* Cmeth = *it;
            assert(Cmeth && "No method found");

            Function* func = getMethodOrStub(Cmeth, maybeCustomize);
            InternalElemts.push_back(
              ConstantExpr::getBitCast(getMethodInClass(Imeth), PTy));
            InternalElemts.push_back(ConstantExpr::getBitCast(func, PTy));
          }
          Constant* Array = ConstantArray::get(ATy, InternalElemts);
    
          GlobalVariable* GV = new GlobalVariable(*getLLVMModule(), ATy, false,
                                                  GlobalValue::InternalLinkage,
                                                  Array, "");
     
          Constant* CI =
            ConstantExpr::getPtrToInt(GV, JavaIntrinsics.pointerSizeType);
          CI = ConstantExpr::getAdd(CI,
            ConstantExpr::getIntegerCast(JavaIntrinsics.constantOne,
                                         JavaIntrinsics.pointerSizeType,
                                         false));
          CI = ConstantExpr::getIntToPtr(CI, PTy);
          IElemts.push_back(CI);
        }
      } else {
        IElemts.push_back(N);
      }
    }
 
    Constant* Array = ConstantArray::get(ATy, IElemts);
    GlobalVariable* GV = new GlobalVariable(*getLLVMModule(), ATy, false,
                                            GlobalValue::InternalLinkage,
                                            Array, "");
    Elemts.push_back(ConstantExpr::getBitCast(GV, PTy));
  }
 
  // methods
  for (uint32 i = JavaVirtualTable::getFirstJavaMethodIndex(); i < size; ++i) {
    JavaMethod* meth = ((JavaMethod**)RealVT)[i];
    // Primitive classes don't have methods--abstract or otherwise.
    // (But we do have placeholders for j.l.Object methods in their VTs,
    // so just emit NULL's here)
    if (classDef->isPrimitive() || isAbstract(meth->access)) {
      Elemts.push_back(Constant::getNullValue(PTy));
    } else {
      Function* F = getMethodOrStub(meth, maybeCustomize);
      Elemts.push_back(ConstantExpr::getCast(Instruction::BitCast, F, PTy));
    }
  }

  Constant* Array = ConstantArray::get(ATy, Elemts);
  
  return Array;
}

JavaAOTCompiler::JavaAOTCompiler(
  const std::string& ModuleID, bool compiling_garbage_collector) :
  JavaLLVMCompiler(ModuleID, compiling_garbage_collector) {

  std::string Error;
  const Target* TheTarget(TargetRegistry::lookupTarget(
      vmkit::VmkitModule::getHostTriple(), Error));
  TargetOptions options;
  options.NoFramePointerElim = true;
  TargetMachine* TM = TheTarget->createTargetMachine(
      vmkit::VmkitModule::getHostTriple(), "", "", options);
  TheDataLayout = TM->getDataLayout();
  TheModule->setDataLayout(TheDataLayout->getStringRepresentation());
  TheModule->setTargetTriple(TM->getTargetTriple());
  JavaIntrinsics.init(TheModule);
  initialiseAssessorInfo();  


  generateStubs = true;
  assumeCompiled = false;
  compileRT = false;
  precompile = false;
  emitClassBytes = false;

  std::vector<llvm::Type*> llvmArgs;
  FunctionType* FTy = FunctionType::get(
      Type::getVoidTy(getLLVMContext()), llvmArgs, false);
  Callback = Function::Create(FTy, GlobalValue::ExternalLinkage,
                              "staticCallback", getLLVMModule());

  llvmArgs.clear();
  llvmArgs.push_back(JavaIntrinsics.JavaMethodType);
  
  FTy = FunctionType::get(JavaIntrinsics.ptrType, llvmArgs, false);

  NativeLoader = Function::Create(FTy, GlobalValue::ExternalLinkage,
                                  "vmjcNativeLoader", getLLVMModule());
  
  llvmArgs.clear();
  FTy = FunctionType::get(Type::getVoidTy(getLLVMContext()), llvmArgs, false);
  ObjectPrinter = Function::Create(FTy, GlobalValue::ExternalLinkage,
                                   "printJavaObject", getLLVMModule());
  
  ArrayObjectTracer = Function::Create(FTy, GlobalValue::ExternalLinkage,
                                       "ArrayObjectTracer", getLLVMModule());
  
  RegularObjectTracer = Function::Create(FTy,
                                         GlobalValue::ExternalLinkage,
                                         "RegularObjectTracer",
                                         getLLVMModule());
  
  JavaObjectTracer = Function::Create(FTy, GlobalValue::ExternalLinkage,
                                      "JavaObjectTracer", getLLVMModule());
  
  ReferenceObjectTracer = Function::Create(FTy,
                                           GlobalValue::ExternalLinkage,
                                           "ReferenceObjectTracer",
                                           getLLVMModule());
  
  EmptyDestructorFunction = Function::Create(FTy,
                                             GlobalValue::ExternalLinkage,
                                             "EmptyDestructor",
                                             getLLVMModule());


  UTF8EmptyGV = new GlobalVariable(*getLLVMModule(),
                                   JavaIntrinsics.UTF8Type->getContainedType(0),
                                   false, GlobalValue::ExternalLinkage, NULL,
                                   "EmptyKey");

  UTF8TombstoneGV = new GlobalVariable(*getLLVMModule(),
                                       JavaIntrinsics.UTF8Type->getContainedType(0),
                                       false, GlobalValue::ExternalLinkage, NULL,
                                       "TombstoneKey");
}

void JavaAOTCompiler::printStats() {
  fprintf(stdout, "----------------- Info from the module -----------------\n");
  fprintf(stdout, "Number of native classes            : %llu\n", 
          (unsigned long long int) nativeClasses.size());
  fprintf(stdout, "Number of Java classes              : %llu\n",
          (unsigned long long int) javaClasses.size());
  fprintf(stdout, "Number of external array classes    : %llu\n",
          (unsigned long long int) arrayClasses.size());
  fprintf(stdout, "Number of virtual tables            : %llu\n", 
          (unsigned long long int) virtualTables.size());
  fprintf(stdout, "Number of static instances          : %llu\n", 
          (unsigned long long int) staticInstances.size());
  fprintf(stdout, "Number of constant pools            : %llu\n", 
          (unsigned long long int) resolvedConstantPools.size());
  fprintf(stdout, "Number of strings                   : %llu\n", 
          (unsigned long long int) strings.size());
  fprintf(stdout, "Number of native functions          : %llu\n", 
          (unsigned long long int) nativeFunctions.size());
  fprintf(stdout, "----------------- Total size in .data ------------------\n");
  uint64 size = 0;
  Module* Mod = getLLVMModule();
  for (Module::const_global_iterator i = Mod->global_begin(),
       e = Mod->global_end(); i != e; ++i) {
    size += TheDataLayout->getTypeAllocSize(i->getType());
  }
  fprintf(stdout, "%lluB\n", (unsigned long long int)size);
}


void JavaAOTCompiler::CreateStaticInitializer() {

  std::vector<llvm::Type*> llvmArgs;
  llvmArgs.push_back(JavaIntrinsics.ptrType); // class loader
  llvmArgs.push_back(JavaIntrinsics.JavaCommonClassType); // cl
  FunctionType* FTy =
    FunctionType::get(Type::getVoidTy(getLLVMContext()), llvmArgs, false);

  Function* AddClass = Function::Create(FTy, GlobalValue::ExternalLinkage,
                                        "vmjcAddPreCompiledClass",
                                        getLLVMModule());

  llvmArgs.clear();
  llvmArgs.push_back(JavaIntrinsics.ptrType); // class loader.
  FTy = FunctionType::get(Type::getVoidTy(getLLVMContext()), llvmArgs, false);

  StaticInitializer = Function::Create(FTy, GlobalValue::InternalLinkage,
                                       "Init", getLLVMModule());
 
  llvmArgs.clear();
  // class loader
  llvmArgs.push_back(JavaIntrinsics.ptrType);
  // array ptr
  llvmArgs.push_back(PointerType::getUnqual(JavaIntrinsics.JavaClassArrayType));
  // name
  llvmArgs.push_back(JavaIntrinsics.UTF8Type);
  FTy = FunctionType::get(Type::getVoidTy(getLLVMContext()), llvmArgs, false);
  
  Function* GetClassArray = Function::Create(FTy, GlobalValue::ExternalLinkage,
                                             "vmjcGetClassArray", getLLVMModule());
  
  BasicBlock* currentBlock = BasicBlock::Create(getLLVMContext(), "enter",
                                                StaticInitializer);
  Function::arg_iterator loader = StaticInitializer->arg_begin();
  
  Value* Args[3];
  // If we have defined some strings.
  if (strings.begin() != strings.end()) {
    llvmArgs.clear();
    llvmArgs.push_back(JavaIntrinsics.ptrType); // class loader
    llvmArgs.push_back(strings.begin()->second->getType()); // val
    FTy = FunctionType::get(Type::getVoidTy(getLLVMContext()), llvmArgs, false);
  
    Function* AddString = Function::Create(FTy, GlobalValue::ExternalLinkage,
                                           "vmjcAddString", getLLVMModule());
  

  
    for (string_iterator i = strings.begin(), e = strings.end(); i != e; ++i) {
      Args[0] = loader;
      Args[1] = i->second;
      CallInst::Create(AddString, ArrayRef<Value*>(Args, 2), "", currentBlock);
    }
  }
 
  for (native_class_iterator i = nativeClasses.begin(), 
       e = nativeClasses.end(); i != e; ++i) {
    if (isCompiling(i->first)) {
      Args[0] = loader;
      Args[1] = ConstantExpr::getBitCast(i->second,
                                         JavaIntrinsics.JavaCommonClassType);
      CallInst::Create(AddClass, ArrayRef<Value*>(Args, 2), "", currentBlock);
    }
  }
  
  for (array_class_iterator i = arrayClasses.begin(), 
       e = arrayClasses.end(); i != e; ++i) {
    Args[0] = loader;
    Args[1] = i->second;
    Args[2] = getUTF8(i->first->name);
    CallInst::Create(GetClassArray, ArrayRef<Value*>(Args, 3), "", currentBlock);
  }
  

  ReturnInst::Create(getLLVMContext(), currentBlock);
}

void JavaAOTCompiler::makeVT(Class* cl) {
  JavaVirtualTable* VT = cl->virtualVT;
  
  if (cl->super) {
    // Copy the super VT into the current VT.
    uint32 size = cl->super->virtualTableSize - 
        JavaVirtualTable::getFirstJavaMethodIndex();
    memcpy(VT->getFirstJavaMethod(), cl->super->virtualVT->getFirstJavaMethod(),
           size * sizeof(word_t));
    VT->destructor = cl->super->virtualVT->destructor;
  }
  
  for (uint32 i = 0; i < cl->nbVirtualMethods; ++i) {
    JavaMethod& meth = cl->virtualMethods[i];
    ((void**)VT)[meth.offset] = &meth;
  }

  if (!cl->super) VT->destructor = reinterpret_cast<word_t>(EmptyDestructor);
}

void JavaAOTCompiler::makeIMT(Class* cl) {
}

void JavaAOTCompiler::setMethod(Function* func, void* ptr, const char* name) {
  func->setName(name);
  func->setLinkage(GlobalValue::ExternalLinkage);
}

Value* JavaAOTCompiler::addCallback(Class* cl, uint16 index,
                                    Signdef* sign, bool stat,
                                    BasicBlock* insert) {
 
  JavaConstantPool* ctpInfo = cl->ctpInfo;
  Signdef* signature = 0;
  const UTF8* name = 0;
  const UTF8* methCl = 0;
  ctpInfo->nameOfStaticOrSpecialMethod(index, methCl, name, signature);

  fprintf(stderr, "Warning: emitting a callback from %s (%s.%s)\n",
          UTF8Buffer(cl->name).cString(), UTF8Buffer(methCl).cString(),
          UTF8Buffer(name).cString());

  LLVMSignatureInfo* LSI = getSignatureInfo(sign);
  
  FunctionType* type = stat ? LSI->getStaticType() : 
                              LSI->getVirtualType();
  
  Value* func = ConstantExpr::getBitCast(Callback,
                                         PointerType::getUnqual(type));
  
  return func;
}

void JavaAOTCompiler::compileClass(Class* cl) {
  
  // Make sure the class is emitted.
  getNativeClass(cl);

  for (uint32 i = 0; i < cl->nbVirtualMethods; ++i) {
    JavaMethod& meth = cl->virtualMethods[i];
    if (!isAbstract(meth.access)) parseFunction(&meth, NULL);
    if (generateStubs) compileAllStubs(meth.getSignature());
  }
  
  for (uint32 i = 0; i < cl->nbStaticMethods; ++i) {
    JavaMethod& meth = cl->staticMethods[i];
    if (!isAbstract(meth.access)) parseFunction(&meth, NULL);
    if (generateStubs) compileAllStubs(meth.getSignature());
  }
}



void extractFiles(ClassBytes* bytes,
                  JavaAOTCompiler* M,
                  JnjvmBootstrapLoader* bootstrapLoader,
                  std::vector<Class*>& classes) {
  ZipArchive archive(bytes, bootstrapLoader->allocator);
   
  vmkit::BumpPtrAllocator allocator; 
  char* realName = (char*)allocator.Allocate(4096, "temp");
  for (ZipArchive::table_iterator i = archive.filetable.begin(), 
       e = archive.filetable.end(); i != e; ++i) {
    ZipFile* file = i->second;
     
    char* name = file->filename;
    uint32 size = strlen(name);
    if (size > 6 && !strcmp(&(name[size - 6]), ".class")) {
      memcpy(realName, name, size);
      realName[size - 6] = 0;
      const UTF8* utf8 = bootstrapLoader->asciizConstructUTF8(realName);
      Class* cl = bootstrapLoader->loadName(utf8, true, false, NULL);
      assert(cl && "Class not created");
      if (cl == ClassArray::SuperArray) M->compileRT = true;
      classes.push_back(cl);  
    } else if (size > 4 && (!strcmp(&name[size - 4], ".jar") || 
                            !strcmp(&name[size - 4], ".zip"))) {
      ClassBytes* res = new (allocator, file->ucsize) ClassBytes(file->ucsize);
      int ok = archive.readFile(res, file);
      if (!ok) return;
      
      extractFiles(res, M, bootstrapLoader, classes);
    }
  }
}


static const char* name;

extern "C" void UnreachableMagicMMTk() {
  UNREACHABLE();
}

void mainCompilerStart(JavaThread* th) {
  
  Jnjvm* vm = th->getJVM();
  JnjvmBootstrapLoader* bootstrapLoader = vm->bootstrapLoader;
  JavaAOTCompiler* M = (JavaAOTCompiler*)bootstrapLoader->getCompiler();
  M->addJavaPasses();

  bootstrapLoader->analyseClasspathEnv(vm->bootstrapLoader->bootClasspathEnv);
  uint32 size = strlen(name);
  if (size > 4 && 
      (!strcmp(&name[size - 4], ".jar") || !strcmp(&name[size - 4], ".zip"))) {
    bootstrapLoader->analyseClasspathEnv(name);
  }

  JavaJITCompiler* Comp = NULL;
  if (!M->clinits->empty()) {
    Comp = JavaJITCompiler::CreateCompiler("JIT");
    Comp->EmitFunctionName = true;
    if (!M->useCooperativeGC()) {
      Comp->disableCooperativeGC();
    }
    bootstrapLoader->setCompiler(Comp);
    bootstrapLoader->analyseClasspathEnv(vm->classpath);
  } else {
    bootstrapLoader->analyseClasspathEnv(vm->classpath);
    bootstrapLoader->upcalls->initialiseClasspath(bootstrapLoader);
  }
  
    
  if (size > 4 && 
      (!strcmp(&name[size - 4], ".jar") || !strcmp(&name[size - 4], ".zip"))) {
  
    std::vector<Class*> classes;
    ClassBytes* bytes = Reader::openFile(bootstrapLoader, name);
      
    if (!bytes) {
      fprintf(stderr, "Can't find zip file '%s'.\n", name);
      goto end;
    }

    extractFiles(bytes, M, bootstrapLoader, classes);

    // First resolve everyone so that there can not be unknown references in
    // constant pools.
    for (std::vector<Class*>::iterator i = classes.begin(),
         e = classes.end(); i != e; ++i) {
      Class* cl = *i;
      cl->resolveClass();
      cl->setOwnerClass(JavaThread::get());
      
      for (uint32 i = 0; i < cl->nbVirtualMethods; ++i) {
        if (!isAbstract(cl->virtualMethods[i].access)) {
          M->getMethod(&cl->virtualMethods[i], NULL);
        }
      }

      for (uint32 i = 0; i < cl->nbStaticMethods; ++i) {
        M->getMethod(&cl->staticMethods[i], NULL);
      }
    }

    if (!M->clinits->empty()) {
      vm->loadBootstrap();
      
      // First, if we have the magic classes available, make sure we
      // compile them so that we can call them directly and let
      // LowerMagic lower them later on.
      for (std::vector<Class*>::iterator ii = classes.begin(),
           ee = classes.end(); ii != ee; ++ii) {
        Class* cl = *ii;
        static const std::string magic = "org/vmmagic";
        static void* ptr = (void*)(word_t)UnreachableMagicMMTk;
        if (!strncmp(UTF8Buffer(cl->name).cString(),
                     magic.c_str(),
                     magic.length() - 1)) {
          for (uint32 i = 0; i < cl->nbVirtualMethods; ++i) {
            if (!isAbstract(cl->virtualMethods[i].access)) {
              Function* F = M->getMethod(&cl->virtualMethods[i], NULL);
              M->setMethod(F, ptr, F->getName().data());
              cl->virtualMethods[i].compiledPtr();
              // Set native so that we don't try to inline it.
              cl->virtualMethods[i].setNative();
            }
          }

          for (uint32 i = 0; i < cl->nbStaticMethods; ++i) {
            Function* F = M->getMethod(&cl->staticMethods[i], NULL);
            M->setMethod(F, ptr, F->getName().data());
            cl->staticMethods[i].compiledPtr();
            // Set native so that we don't try to inline it.
            cl->staticMethods[i].setNative();
          }
        }
      }

      // Initialize all classes given with with the -with-clinit
      // command line argument.
      for (std::vector<std::string>::iterator i = M->clinits->begin(),
           e = M->clinits->end(); i != e; ++i) {
        Class* cl = NULL;
        TRY {
          if (i->at(i->length() - 1) == '*') {
            for (std::vector<Class*>::iterator ii = classes.begin(),
                 ee = classes.end(); ii != ee; ++ii) {
              cl = *ii;
              if (!strncmp(UTF8Buffer(cl->name).cString(), i->c_str(),
                           i->length() - 1)) {
                cl->initialiseClass(vm);
              }
            }
          } else {
            const UTF8* name = bootstrapLoader->asciizConstructUTF8(i->c_str());
            CommonClass* cls = bootstrapLoader->lookupClass(name);
            if (cls && cls->isClass()) {
              cl = cls->asClass();
              cl->initialiseClass(vm);
            } else {
              fprintf(stderr, "Class %s does not exist or is an array class.\n",
                      i->c_str());
            }
          }
        } CATCH {
          fprintf(stderr, "Error when initializing %s\n",
                  UTF8Buffer(cl->name).cString());
          abort();
        } END_CATCH;
      }
      bootstrapLoader->setCompiler(M);
    }

    // We don't want strings to be interned when AOT'ing, otherwise
    // we would call Java code.
    bootstrapLoader->upcalls->internString = NULL;
   
    // Set the thread as the owner of the classes, so that it knows it
    // has to compile them. 
    for (std::vector<Class*>::iterator i = classes.begin(), e = classes.end();
         i != e; ++i) {
      (*i)->setOwnerClass(JavaThread::get());
    }
    
    // Finally, compile all classes.
    for (std::vector<Class*>::iterator i = classes.begin(), e = classes.end();
         i != e; ++i) {
      M->compileClass(*i);
    }

  } else {
    vmkit::ThreadAllocator allocator;
    char* realName = (char*)allocator.Allocate(size + 1);
    if (size > 6 && !strcmp(&name[size - 6], ".class")) {
      memcpy(realName, name, size - 6);
      realName[size - 6] = 0;
    } else {
      memcpy(realName, name, size + 1);
    }
   
    const UTF8* utf8 = bootstrapLoader->asciizConstructUTF8(realName);
    UserClass* cl = bootstrapLoader->loadName(utf8, true, true, NULL);
    
    if (!M->clinits->empty()) {
      vm->loadBootstrap();
      cl->initialiseClass(vm);
      bootstrapLoader->setCompiler(M);
    }
    
    cl->setOwnerClass(JavaThread::get());
    cl->resolveInnerOuterClasses();
    for (uint32 i = 0; i < cl->nbInnerClasses; ++i) {
      cl->innerClasses[i]->setOwnerClass(JavaThread::get());
      M->compileClass(cl->innerClasses[i]);
    }
    M->compileClass(cl);
  }

  if (M->compileRT) {
    // Make sure that if we compile RT, the native classes are emitted.
    M->getNativeClass(bootstrapLoader->upcalls->OfVoid);
    M->getNativeClass(bootstrapLoader->upcalls->OfBool);
    M->getNativeClass(bootstrapLoader->upcalls->OfByte);
    M->getNativeClass(bootstrapLoader->upcalls->OfChar);
    M->getNativeClass(bootstrapLoader->upcalls->OfShort);
    M->getNativeClass(bootstrapLoader->upcalls->OfInt);
    M->getNativeClass(bootstrapLoader->upcalls->OfFloat);
    M->getNativeClass(bootstrapLoader->upcalls->OfLong);
    M->getNativeClass(bootstrapLoader->upcalls->OfDouble);
  }

  M->CreateStaticInitializer();

end:

  vm->threadSystem.leave(); 
}

void JavaAOTCompiler::compileFile(Jnjvm* vm, const char* n) {
  name = n;
  JavaThread* th = new JavaThread(vm);
  vm->setMainThread(th);
  th->start((void (*)(vmkit::Thread*))mainCompilerStart);
  vm->waitForExit();
}

void JavaAOTCompiler::compileClassLoader(JnjvmBootstrapLoader* loader) {
  JavaJITCompiler* jitCompiler = (JavaJITCompiler*)loader->getCompiler();
  loader->setCompiler(this);
  compileRT = true;
  precompile = true;
  addJavaPasses();

  // Make sure that the native classes are emitted.
  getNativeClass(loader->upcalls->OfVoid);
  getNativeClass(loader->upcalls->OfBool);
  getNativeClass(loader->upcalls->OfByte);
  getNativeClass(loader->upcalls->OfChar);
  getNativeClass(loader->upcalls->OfShort);
  getNativeClass(loader->upcalls->OfInt);
  getNativeClass(loader->upcalls->OfFloat);
  getNativeClass(loader->upcalls->OfLong);
  getNativeClass(loader->upcalls->OfDouble);

  // First set all classes to resolved.
  for (ClassMap::iterator i = loader->getClasses()->map.begin(),
       e = loader->getClasses()->map.end(); i!= e; ++i) {
    if (i->second->isClass()) {
      if (i->second->asClass()->isResolved()) {
        i->second->asClass()->setResolved();
      } else {
        i->second->asClass()->resolveClass();
      }
    }
  }

  for (method_info_iterator I = jitCompiler->method_infos.begin(),
       E = jitCompiler->method_infos.end(); I != E; I++) {
    if (!isAbstract(I->first->access)) {
      LLVMMethodInfo* LMI = I->second;
      if (LMI->methodFunction) {
        parseFunction(I->first, NULL);
      }
      for (std::map<Class*, Function*>::iterator
           CI = LMI->customizedVersions.begin(),
           CE = LMI->customizedVersions.end(); CI != CE; CI++) {
        parseFunction(I->first, CI->first);
      }
    }
  }

  while (!toCompile.empty()) {
    JavaMethod* meth = toCompile.back().first;
    Class* customizeFor = toCompile.back().second;
    // parseFunction may introduce new functions to compile, so
    // pop toCompile before calling parseFunction.
    toCompile.pop_back();
    parseFunction(meth, customizeFor);
  }

  // Make sure classes and arrays already referenced in constant pools
  // are loaded.
  for (ClassMap::iterator i = loader->getClasses()->map.begin(),
       e = loader->getClasses()->map.end(); i!= e; ++i) {
    if (i->second->isClass()) {
      getResolvedConstantPool(i->second->asClass()->ctpInfo);
    }
  }

  // Add all class and VT initializers.
  for (ClassMap::iterator i = loader->getClasses()->map.begin(),
       e = loader->getClasses()->map.end(); i!= e; ++i) {
    AddInitializerToClass(getNativeClass(i->second), i->second);
    JavaVirtualTable* VT = i->second->virtualVT;
    GlobalVariable* gv =
        dyn_cast<GlobalVariable>(getVirtualTable(VT)->getOperand(0));
    gv->setInitializer(CreateConstantFromVT(VT));
  }

  assert(toCompile.size() == 0);

  // Add used stubs to the image.
  for (SignMap::iterator i = loader->javaSignatures->map.begin(),
       e = loader->javaSignatures->map.end(); i != e; i++) {
    Signdef* signature = i->second;
    LLVMSignatureInfo* LSI = getSignatureInfo(signature);
    if (signature->_staticCallBuf != 0) {
      LSI->getStaticBuf();
    }
    if (signature->_virtualCallBuf != 0) {
      LSI->getVirtualBuf();
    }
    if (signature->_staticCallAP != 0) {
      LSI->getStaticAP();
    }
    if (signature->_virtualCallAP != 0) {
      LSI->getVirtualAP();
    }
    if (signature->_virtualCallStub != 0) {
      LSI->getVirtualStub();
    }
    if (signature->_specialCallStub != 0) {
      LSI->getSpecialStub();
    }
    if (signature->_staticCallStub != 0) {
      LSI->getStaticStub();
    }
  }

  // Emit the stub for the main signature.
  Signdef* mainSignature =
    loader->constructSign(loader->asciizConstructUTF8("([Ljava/lang/String;)V"));
  getSignatureInfo(mainSignature)->getStaticBuf();

  // Emit the class map.
  CreateConstantFromClassMap(loader->classes->map);

  // Emit the UTF8 map.
  CreateConstantFromUTF8Map(loader->hashUTF8->map);

  // Check that we have compiled everything.
  for (Module::iterator I = TheModule->begin(), E = TheModule->end();
       I != E;
       I++) {
    assert(!I->hasExternalWeakLinkage());
  }
}

void JavaAOTCompiler::generateClassBytes(JnjvmBootstrapLoader* loader) {
  emitClassBytes = true;
  // Add the bootstrap classes to the image.
  for (std::vector<ZipArchive*>::iterator i = loader->bootArchives.begin(),
       e = loader->bootArchives.end(); i != e; ++i) {
    ZipArchive* archive = *i;
    for (ZipArchive::table_iterator zi = archive->filetable.begin(),
         ze = archive->filetable.end(); zi != ze; zi++) {
      // Remove the '.class'.
      const char* name = zi->first;
      std::string str(name, strlen(name) - strlen(".class"));
      ClassBytes* bytes = Reader::openZip(loader, archive, name);
      getClassBytes(loader->asciizConstructUTF8(str.c_str()), bytes);
    }
  }
}


/// compileAllStubs - Compile all the native -> Java stubs. 
/// TODO: Once LLVM supports va_arg, enable AP.
///
void JavaAOTCompiler::compileAllStubs(Signdef* sign) {
  sign->getStaticCallBuf();
  // getStaticCallAP();
  sign->getVirtualCallBuf();
  // getVirtualCallAP();
}

void JavaAOTCompiler::generateMain(const char* name, bool jit) {

  // Type Definitions
  std::vector<Type*> FuncArgs;
  FuncArgs.push_back(Type::getInt32Ty(getLLVMContext()));
  FuncArgs.push_back(PointerType::getUnqual(JavaIntrinsics.ptrType));
  
  FunctionType* FuncTy = FunctionType::get(Type::getInt32Ty(getLLVMContext()),
                                           FuncArgs, false);

  Function* MainFunc = Function::Create(FuncTy, GlobalValue::ExternalLinkage,
                                        "main", TheModule);
  BasicBlock* currentBlock = BasicBlock::Create(getLLVMContext(), "enter",
                                                MainFunc);
 
  GlobalVariable* GvarArrayStr = new GlobalVariable(
    *TheModule, ArrayType::get(Type::getInt8Ty(getLLVMContext()),
                               strlen(name) + 1),
    true, GlobalValue::InternalLinkage, 0, "mainClass");


  Constant* NameArray = ConstantDataArray::getString(getLLVMContext(), name, true);
  GvarArrayStr->setInitializer(NameArray);
  Value* Indices[2] = { JavaIntrinsics.constantZero,
                        JavaIntrinsics.constantZero };
  Value* ArgName = ConstantExpr::getGetElementPtr(GvarArrayStr, Indices, 2);

  Function::arg_iterator FuncVals = MainFunc->arg_begin();
  Value* Argc = FuncVals++;
  Value* Argv = FuncVals++;
  Value* Args[3] = { Argc, Argv, ArgName };

  FuncArgs.push_back(Args[2]->getType());

  FuncTy = FunctionType::get(Type::getInt32Ty(getLLVMContext()), FuncArgs, false);

  Function* CalledFunc = 
    Function::Create(FuncTy, GlobalValue::ExternalLinkage,
                     jit ? "StartJnjvmWithJIT" : "StartJnjvmWithoutJIT",
                     TheModule);

  Value* res = CallInst::Create(CalledFunc, ArrayRef<Value*>(Args, 3), "", currentBlock);
  ReturnInst::Create(getLLVMContext(), res, currentBlock);

}

// TODO: clean up to have a better interface with the fake GC.
#include <set>
extern std::set<gc*> __InternalSet__;

CommonClass* JavaAOTCompiler::getUniqueBaseClass(CommonClass* cl) {
  JavaObject* obj = NULL;
  llvm_gcroot(obj, 0);
  std::set<gc*>::iterator I = __InternalSet__.begin();
  std::set<gc*>::iterator E = __InternalSet__.end();
  CommonClass* currentClass = 0;

  for (; I != E; ++I) {
    obj = (JavaObject*)(*I);
    if (!VMClassLoader::isVMClassLoader(obj) &&
        !VMStaticInstance::isVMStaticInstance(obj) &&
        JavaObject::instanceOf(obj, cl)) {
      if (currentClass != NULL) {
        if (JavaObject::getClass(obj) != currentClass) {
          return 0;
        }
      } else {
        currentClass = JavaObject::getClass(obj);
      }
    }
  }
  return currentClass;
}
