//===--------- JnjvmModule.cpp - Definition of a Jnjvm module -------------===//
//
//                              JnJVM
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/CallingConv.h"
#include "llvm/Instructions.h"
#include "llvm/Support/MutexGuard.h"


#include "mvm/JIT.h"

#include "JavaThread.h"
#include "JavaTypes.h"
#include "Jnjvm.h"
#include "JnjvmModule.h"
#include "JnjvmModuleProvider.h"


using namespace jnjvm;
using namespace llvm;


#ifdef WITH_TRACER
const llvm::FunctionType* JnjvmModule::MarkAndTraceType = 0;
#endif

const llvm::Type* JnjvmModule::JavaObjectType = 0;
const llvm::Type* JnjvmModule::JavaArrayType = 0;
const llvm::Type* JnjvmModule::JavaArrayUInt8Type = 0;
const llvm::Type* JnjvmModule::JavaArraySInt8Type = 0;
const llvm::Type* JnjvmModule::JavaArrayUInt16Type = 0;
const llvm::Type* JnjvmModule::JavaArraySInt16Type = 0;
const llvm::Type* JnjvmModule::JavaArrayUInt32Type = 0;
const llvm::Type* JnjvmModule::JavaArraySInt32Type = 0;
const llvm::Type* JnjvmModule::JavaArrayFloatType = 0;
const llvm::Type* JnjvmModule::JavaArrayDoubleType = 0;
const llvm::Type* JnjvmModule::JavaArrayLongType = 0;
const llvm::Type* JnjvmModule::JavaArrayObjectType = 0;
const llvm::Type* JnjvmModule::CacheNodeType = 0;
const llvm::Type* JnjvmModule::EnveloppeType = 0;
const llvm::Type* JnjvmModule::JnjvmType = 0;
const llvm::Type* JnjvmModule::ConstantPoolType = 0;

llvm::Constant*     JnjvmModule::JavaObjectNullConstant;
llvm::Constant*     JnjvmModule::UTF8NullConstant;
llvm::Constant*     JnjvmModule::JavaClassNullConstant;
llvm::Constant*     JnjvmModule::MaxArraySizeConstant;
llvm::Constant*     JnjvmModule::JavaObjectSizeConstant;
llvm::Constant*     JnjvmModule::JavaArraySizeConstant;
llvm::ConstantInt*  JnjvmModule::OffsetObjectSizeInClassConstant;
llvm::ConstantInt*  JnjvmModule::OffsetVTInClassConstant;
llvm::ConstantInt*  JnjvmModule::OffsetDepthInClassConstant;
llvm::ConstantInt*  JnjvmModule::OffsetDisplayInClassConstant;
llvm::ConstantInt*  JnjvmModule::OffsetStatusInClassConstant;
llvm::ConstantInt*  JnjvmModule::OffsetTaskClassMirrorInClassConstant;
llvm::ConstantInt*  JnjvmModule::OffsetStaticInstanceInTaskClassMirrorConstant;
llvm::ConstantInt*  JnjvmModule::OffsetStatusInTaskClassMirrorConstant;
llvm::ConstantInt*  JnjvmModule::ClassReadyConstant;
const llvm::Type*   JnjvmModule::JavaClassType;
const llvm::Type*   JnjvmModule::VTType;
llvm::ConstantInt*  JnjvmModule::JavaArrayElementsOffsetConstant;
llvm::ConstantInt*  JnjvmModule::JavaArraySizeOffsetConstant;
llvm::ConstantInt*  JnjvmModule::JavaObjectLockOffsetConstant;
llvm::ConstantInt*  JnjvmModule::JavaObjectClassOffsetConstant;

Value* JnjvmModule::getNativeClass(CommonClass* classDef) {
  llvm::GlobalVariable* varGV = 0;
  native_class_iterator End = nativeClasses.end();
  native_class_iterator I = nativeClasses.find(classDef);
  if (I == End) {
    Constant* cons = 
      ConstantExpr::getIntToPtr(ConstantInt::get(Type::Int64Ty,
                                                 uint64_t (classDef)),
                                JnjvmModule::JavaClassType);
      
    varGV = new GlobalVariable(JnjvmModule::JavaClassType, !staticCompilation,
                               GlobalValue::ExternalLinkage,
                               cons, "", this);

    nativeClasses.insert(std::make_pair(classDef, varGV));
  } else {
    varGV = I->second;
  }   
  return varGV;
}

Value* JnjvmModule::getConstantPool(JavaConstantPool* ctp) {
  llvm::GlobalVariable* varGV = 0;
  constant_pool_iterator End = constantPools.end();
  constant_pool_iterator I = constantPools.find(ctp);
  if (I == End) {
    void* ptr = ctp->ctpRes;
    assert(ptr && "No constant pool found");
    Constant* cons = 
      ConstantExpr::getIntToPtr(ConstantInt::get(Type::Int64Ty, uint64(ptr)),
                                mvm::MvmModule::ptrPtrType);
    varGV = new GlobalVariable(mvm::MvmModule::ptrPtrType, !staticCompilation,
                               GlobalValue::ExternalLinkage,
                               cons, "", this);
    constantPools.insert(std::make_pair(ctp, varGV));
  } else {
    varGV = I->second;
  }
  return varGV;
}

Value* JnjvmModule::getString(JavaString* str) {
  llvm::GlobalVariable* varGV;
  string_iterator SI = strings.find(str);
  if (SI != strings.end()) {
    varGV = SI->second;
  } else {
    void* ptr = str;
    assert(ptr && "No string given");
    Constant* cons = 
      ConstantExpr::getIntToPtr(ConstantInt::get(Type::Int64Ty, uint64(ptr)),
                                JnjvmModule::JavaObjectType);
    varGV = new GlobalVariable(JnjvmModule::JavaObjectType, !staticCompilation,
                               GlobalValue::ExternalLinkage,
                               cons, "", this);
    strings.insert(std::make_pair(str, varGV));
  }
  return varGV;
}

Value* JnjvmModule::getEnveloppe(Enveloppe* enveloppe) {
  llvm::GlobalVariable* varGV;
  enveloppe_iterator SI = enveloppes.find(enveloppe);
  if (SI != enveloppes.end()) {
    varGV = SI->second;
  } else {
    void* ptr = enveloppe;
    assert(ptr && "No enveloppe given");
    Constant* cons = 
      ConstantExpr::getIntToPtr(ConstantInt::get(Type::Int64Ty, uint64(ptr)),
                                JnjvmModule::EnveloppeType);
    varGV = new GlobalVariable(JnjvmModule::EnveloppeType, !staticCompilation,
                               GlobalValue::ExternalLinkage,
                               cons, "", this);
    enveloppes.insert(std::make_pair(enveloppe, varGV));
  }
  return varGV;
}

Value* JnjvmModule::getJavaClass(CommonClass* cl) {
  llvm::GlobalVariable* varGV = 0;
  java_class_iterator End = javaClasses.end();
  java_class_iterator I = javaClasses.find(cl);
  if (I == End) {
    
    JavaObject* obj = isStaticCompiling() ? 0 : 
      cl->getClassDelegatee(JavaThread::get()->getJVM());
    assert((obj || isStaticCompiling()) && "Delegatee not created");
    Constant* cons = 
      ConstantExpr::getIntToPtr(ConstantInt::get(Type::Int64Ty, uint64(obj)),
                                JnjvmModule::JavaObjectType);
    varGV = new GlobalVariable(JnjvmModule::JavaObjectType, !staticCompilation,
                               GlobalValue::ExternalLinkage,
                               cons, "", this);

    javaClasses.insert(std::make_pair(cl, varGV));
  } else {
    varGV = I->second;
  }
  return varGV;
}

Value* JnjvmModule::getStaticInstance(Class* classDef) {
  llvm::GlobalVariable* varGV = 0;
  static_instance_iterator End = staticInstances.end();
  static_instance_iterator I = staticInstances.find(classDef);
  if (I == End) {
    LLVMClassInfo* LCI = getClassInfo(classDef);
    LCI->getStaticType();
    JavaObject* obj = ((Class*)classDef)->getStaticInstance();
#ifndef ISOLATE
    if (!obj && !isStaticCompiling()) {
      Class* cl = (Class*)classDef;
      classDef->acquire();
      obj = cl->getStaticInstance();
      if (!obj) {
        // Allocate now so that compiled code can reference it.
        obj = cl->allocateStaticInstance(JavaThread::get()->getJVM());
      }
      classDef->release();
    }
#endif
    Constant* cons = 
      ConstantExpr::getIntToPtr(ConstantInt::get(Type::Int64Ty,
                                uint64_t (obj)), JnjvmModule::JavaObjectType);
      
    varGV = new GlobalVariable(JnjvmModule::JavaObjectType, !staticCompilation,
                               GlobalValue::ExternalLinkage,
                               cons, "", this);

    staticInstances.insert(std::make_pair(classDef, varGV));
  } else {
    varGV = I->second;
  }

  return varGV;
}

Value* JnjvmModule::getVirtualTable(CommonClass* classDef) {
  llvm::GlobalVariable* varGV = 0;
  virtual_table_iterator End = virtualTables.end();
  virtual_table_iterator I = virtualTables.find(classDef);
  if (I == End) {
    if (!classDef->isArray() && !classDef->isPrimitive()) {
      LLVMClassInfo* LCI = getClassInfo((Class*)classDef);
      LCI->getVirtualType();
    }
    assert((classDef->virtualVT || isStaticCompiling()) && 
           "Virtual VT not created");
    Constant* cons = 
      ConstantExpr::getIntToPtr(ConstantInt::get(Type::Int64Ty,
                                                 uint64_t(classDef->virtualVT)),
                                JnjvmModule::VTType);
    varGV = new GlobalVariable(JnjvmModule::VTType, !staticCompilation,
                               GlobalValue::ExternalLinkage,
                               cons, "", this);
    
    virtualTables.insert(std::make_pair(classDef, varGV));
  } else {
    varGV = I->second;
  }
  return varGV;
}

Value* JnjvmModule::getNativeFunction(JavaMethod* meth, void* ptr) {
  llvm::GlobalVariable* varGV = 0;
  native_function_iterator End = nativeFunctions.end();
  native_function_iterator I = nativeFunctions.find(meth);
  if (I == End) {
    
      
    LLVMSignatureInfo* LSI = getSignatureInfo(meth->getSignature());
    const llvm::Type* valPtrType = LSI->getNativePtrType();
    
    assert((ptr || isStaticCompiling()) && "No native function given");

    Constant* cons = 
      ConstantExpr::getIntToPtr(ConstantInt::get(Type::Int64Ty, uint64_t(ptr)),
                                valPtrType);

    varGV = new GlobalVariable(valPtrType, !staticCompilation,
                               GlobalValue::ExternalLinkage,
                               cons, "", this);
    
    nativeFunctions.insert(std::make_pair(meth, varGV));
  } else {
    varGV = I->second;
  }
  return varGV;
}

#ifndef WITHOUT_VTABLE
VirtualTable* JnjvmModule::allocateVT(Class* cl) {
  for (uint32 i = 0; i < cl->nbVirtualMethods; ++i) {
    JavaMethod& meth = cl->virtualMethods[i];
    if (meth.name->equals(cl->classLoader->bootstrapLoader->finalize)) {
      meth.offset = 0;
    } else {
      JavaMethod* parent = cl->super? 
        cl->super->lookupMethodDontThrow(meth.name, meth.type, false, true,
                                         0) :
        0;

      uint64_t offset = 0;
      if (!parent) {
        offset = cl->virtualTableSize++;
        meth.offset = offset;
      } else {
        offset = parent->offset;
        meth.offset = parent->offset;
      }
    }
  }

  uint64 size = cl->virtualTableSize;
  mvm::BumpPtrAllocator& allocator = cl->classLoader->allocator;
  VirtualTable* VT = (VirtualTable*)allocator.Allocate(size * sizeof(void*));
  if (cl->super) {
    Class* super = (Class*)cl->super;
    assert(cl->virtualTableSize >= cl->super->virtualTableSize &&
      "Super VT bigger than own VT");
    assert(super->virtualVT && "Super does not have a VT!");
    memcpy(VT, super->virtualVT, cl->super->virtualTableSize * sizeof(void*));
  } else {
    memcpy(VT, JavaObject::VT, VT_SIZE);
  }
  return VT;
}
#endif


llvm::Function* JnjvmModule::makeTracer(Class* cl, bool stat) {
  
  LLVMClassInfo* LCI = (LLVMClassInfo*)getClassInfo(cl);
  const Type* type = stat ? LCI->getStaticType() : LCI->getVirtualType();
  JavaField* fields = 0;
  uint32 nbFields = 0;
  if (stat) {
    fields = cl->getStaticFields();
    nbFields = cl->nbStaticFields;
  } else {
    fields = cl->getVirtualFields();
    nbFields = cl->nbVirtualFields;
  }
  
  Function* func = Function::Create(JnjvmModule::MarkAndTraceType,
                                    GlobalValue::ExternalLinkage,
                                    "markAndTraceObject",
                                    this);

  Constant* zero = mvm::MvmModule::constantZero;
  Argument* arg = func->arg_begin();
  BasicBlock* block = BasicBlock::Create("", func);
  llvm::Value* realArg = new BitCastInst(arg, type, "", block);

  std::vector<Value*> Args;
  Args.push_back(arg);
#ifdef MULTIPLE_GC
  Value* GC = ++func->arg_begin();
  Args.push_back(GC);
#endif
  if (stat || cl->super == 0) {
    CallInst::Create(JavaObjectTracerFunction, Args.begin(), Args.end(),
                     "", block);
  } else {
    LLVMClassInfo* LCP = (LLVMClassInfo*)getClassInfo((Class*)(cl->super));
    CallInst::Create(LCP->getVirtualTracer(), Args.begin(),
                     Args.end(), "", block);
  }
  
  for (uint32 i = 0; i < nbFields; ++i) {
    JavaField& cur = fields[i];
    if (cur.getSignature()->trace()) {
      LLVMFieldInfo* LFI = getFieldInfo(&cur);
      std::vector<Value*> args; //size = 2
      args.push_back(zero);
      args.push_back(LFI->getOffset());
      Value* ptr = GetElementPtrInst::Create(realArg, args.begin(), args.end(), 
                                             "",block);
      Value* val = new LoadInst(ptr, "", block);
      Value* valCast = new BitCastInst(val, JnjvmModule::JavaObjectType, "",
                                       block);
      std::vector<Value*> Args;
      Args.push_back(valCast);
#ifdef MULTIPLE_GC
      Args.push_back(GC);
#endif
      CallInst::Create(JnjvmModule::MarkAndTraceFunction, Args.begin(),
                       Args.end(), "", block);
    }
  }

  ReturnInst::Create(block);
  
  if (!stat) {
    LCI->virtualTracerFunction = func;
  } else {
    LCI->staticTracerFunction = func;
  }

  return func;
}

VirtualTable* JnjvmModule::makeVT(Class* cl, bool stat) {
  
  VirtualTable* VT = 0;
#ifndef WITHOUT_VTABLE
  if (stat) {
#endif
    mvm::BumpPtrAllocator& allocator = cl->classLoader->allocator;
    VT = (VirtualTable*)allocator.Allocate(VT_SIZE);
    memcpy(VT, JavaObject::VT, VT_SIZE);
#ifndef WITHOUT_VTABLE
  } else {
    if (cl->super) {
      cl->virtualTableSize = cl->super->virtualTableSize;
    } else {
      cl->virtualTableSize = VT_NB_FUNCS;
    }

    // Allocate the virtual table.
    VT = allocateVT(cl);

    // Fill the virtual table with function pointers.
    ExecutionEngine* EE = mvm::MvmModule::executionEngine;
    for (uint32 i = 0; i < cl->nbVirtualMethods; ++i) {
      JavaMethod& meth = cl->virtualMethods[i];
      LLVMMethodInfo* LMI = getMethodInfo(&meth);
      Function* func = LMI->getMethod();

      // Special handling for finalize method. Don't put a finalizer
      // if there is none, or if it is empty.
      if (meth.offset == 0) {
#ifdef ISOLATE_SHARING
        ((void**)VT)[0] = 0;
#else
        JnjvmClassLoader* loader = cl->classLoader;
        Function* func = loader->getModuleProvider()->parseFunction(&meth);
        if (!cl->super) meth.canBeInlined = true;
        Function::iterator BB = func->begin();
        BasicBlock::iterator I = BB->begin();
        if (isa<ReturnInst>(I)) {
          ((void**)VT)[0] = 0;
        } else {
          // LLVM does not allow recursive compilation. Create the code now.
          ((void**)VT)[0] = EE->getPointerToFunction(func);
        }
      }
#endif

      if (staticCompilation) {
        ((void**)VT)[meth.offset] = func;
      } else {
        ((void**)VT)[meth.offset] = EE->getPointerToFunctionOrStub(func);
      }
    }
 
    // If there is no super, then it's the first VT that we allocate. Assign
    // this VT to native types.
    if (!(cl->super)) {
      uint32 size =  (cl->virtualTableSize - VT_NB_FUNCS) * sizeof(void*);
#define COPY(CLASS) \
    memcpy((void*)((uintptr_t)CLASS::VT + VT_SIZE), \
           (void*)((uintptr_t)VT + VT_SIZE), size);

      COPY(JavaArray)
      COPY(JavaObject)
      COPY(ArrayObject)

#undef COPY
    }
  }
#endif
  
#ifdef WITH_TRACER
  llvm::Function* func = makeTracer(cl, stat);
  
  if (staticCompilation) {
    ((void**)VT)[VT_TRACER_OFFSET] = func;
  } else {
    void* codePtr = mvm::MvmModule::executionEngine->getPointerToFunction(func);
    ((void**)VT)[VT_TRACER_OFFSET] = codePtr;
    func->deleteBody();
  }
  

#endif
  return VT;
}


const Type* LLVMClassInfo::getVirtualType() {
  if (!virtualType) {
    std::vector<const llvm::Type*> fields;
    
    if (classDef->super) {
      LLVMClassInfo* CLI = 
        JnjvmModule::getClassInfo((Class*)classDef->super);
      fields.push_back(CLI->getVirtualType()->getContainedType(0));
    } else {
      fields.push_back(JnjvmModule::JavaObjectType->getContainedType(0));
    }
    
    for (uint32 i = 0; i < classDef->nbVirtualFields; ++i) {
      JavaField& field = classDef->virtualFields[i];
      field.num = i;
      Typedef* type = field.getSignature();
      LLVMAssessorInfo& LAI = JnjvmModule::getTypedefInfo(type);
      fields.push_back(LAI.llvmType);
    }
    
    
    StructType* structType = StructType::get(fields, false);
    virtualType = PointerType::getUnqual(structType);
    ExecutionEngine* engine = mvm::MvmModule::executionEngine;
    const TargetData* targetData = engine->getTargetData();
    const StructLayout* sl = targetData->getStructLayout(structType);
    
    for (uint32 i = 0; i < classDef->nbVirtualFields; ++i) {
      JavaField& field = classDef->virtualFields[i];
      field.ptrOffset = sl->getElementOffset(i + 1);
    }
    
    uint64 size = mvm::MvmModule::getTypeSize(structType);
    classDef->virtualSize = (uint32)size;
    virtualSizeConstant = ConstantInt::get(Type::Int32Ty, size);
    
    JnjvmModule* Mod = classDef->classLoader->getModule();
    if (!Mod->isStaticCompiling()) {
      classDef->virtualVT = Mod->makeVT((Class*)classDef, false);
    }
  

  }

  return virtualType;
}

const Type* LLVMClassInfo::getStaticType() {
  
  if (!staticType) {
    Class* cl = (Class*)classDef;
    std::vector<const llvm::Type*> fields;
    fields.push_back(JnjvmModule::JavaObjectType->getContainedType(0));

    for (uint32 i = 0; i < classDef->nbStaticFields; ++i) {
      JavaField& field = classDef->staticFields[i];
      field.num = i;
      Typedef* type = field.getSignature();
      LLVMAssessorInfo& LAI = JnjvmModule::getTypedefInfo(type);
      fields.push_back(LAI.llvmType);
    }
  
    StructType* structType = StructType::get(fields, false);
    staticType = PointerType::getUnqual(structType);
    ExecutionEngine* engine = mvm::MvmModule::executionEngine;
    const TargetData* targetData = engine->getTargetData();
    const StructLayout* sl = targetData->getStructLayout(structType);
    
    for (uint32 i = 0; i < classDef->nbStaticFields; ++i) {
      JavaField& field = classDef->staticFields[i];
      field.ptrOffset = sl->getElementOffset(i + 1);
    }
    
    uint64 size = mvm::MvmModule::getTypeSize(structType);
    cl->staticSize = size;
    
    JnjvmModule* Mod = cl->classLoader->getModule();
    if (!Mod->isStaticCompiling()) {
      cl->staticVT = Mod->makeVT((Class*)classDef, true);
    }
  }
  return staticType;
}


Value* LLVMClassInfo::getVirtualSize() {
  if (!virtualSizeConstant) {
    getVirtualType();
    virtualSizeConstant = 
      ConstantInt::get(Type::Int32Ty, classDef->virtualSize);
  }
  return virtualSizeConstant;
}

Function* LLVMClassInfo::getStaticTracer() {
  if (!staticTracerFunction) {
    getStaticType();
  }
  return staticTracerFunction;
}

Function* LLVMClassInfo::getVirtualTracer() {
  if (!virtualTracerFunction) {
    getVirtualType();
  }
  return virtualTracerFunction;
}

Function* LLVMMethodInfo::getMethod() {
  if (!methodFunction) {
    JnjvmClassLoader* JCL = methodDef->classDef->classLoader;
    JnjvmModule* Mod = JCL->getModule();
    if (Mod->isStaticCompiling()) {
      const UTF8* jniConsClName = methodDef->classDef->name;
      const UTF8* jniConsName = methodDef->name;
      const UTF8* jniConsType = methodDef->type;
      sint32 clen = jniConsClName->size;
      sint32 mnlen = jniConsName->size;
      sint32 mtlen = jniConsType->size;

      char* buf = 
        (char*)alloca(3 + JNI_NAME_PRE_LEN + mnlen + clen + (mtlen << 1));
      methodDef->jniConsFromMeth3(buf);
      methodFunction = Function::Create(getFunctionType(), 
                                        GlobalValue::GhostLinkage, buf, Mod);

    } else {

      methodFunction = Function::Create(getFunctionType(), 
                                        GlobalValue::GhostLinkage,
                                        "", Mod);

    }
    methodFunction->addAnnotation(this);
  }
  return methodFunction;
}

const FunctionType* LLVMMethodInfo::getFunctionType() {
  if (!functionType) {
    Signdef* sign = methodDef->getSignature();
    LLVMSignatureInfo* LSI = JnjvmModule::getSignatureInfo(sign);
    assert(LSI);
    if (isStatic(methodDef->access)) {
      functionType = LSI->getStaticType();
    } else {
      functionType = LSI->getVirtualType();
    }
  }
  return functionType;
}

ConstantInt* LLVMMethodInfo::getOffset() {
  if (!offsetConstant) {
    JnjvmModule::resolveVirtualClass(methodDef->classDef);
    offsetConstant = ConstantInt::get(Type::Int32Ty, methodDef->offset);
  }
  return offsetConstant;
}

ConstantInt* LLVMFieldInfo::getOffset() {
  if (!offsetConstant) {
    if (isStatic(fieldDef->access)) {
      JnjvmModule::resolveStaticClass(fieldDef->classDef); 
    } else {
      JnjvmModule::resolveVirtualClass(fieldDef->classDef); 
    }
    // Increment by one because zero is JavaObject
    offsetConstant = ConstantInt::get(Type::Int32Ty, fieldDef->num + 1);
  }
  return offsetConstant;
}

const llvm::FunctionType* LLVMSignatureInfo::getVirtualType() {
 if (!virtualType) {
    // Lock here because we are called by arbitrary code
    llvm::MutexGuard locked(mvm::MvmModule::executionEngine->lock);
    std::vector<const llvm::Type*> llvmArgs;
    unsigned int size = signature->args.size();

    llvmArgs.push_back(JnjvmModule::JavaObjectType);

    for (uint32 i = 0; i < size; ++i) {
      Typedef* type = signature->args.at(i);
      LLVMAssessorInfo& LAI = JnjvmModule::getTypedefInfo(type);
      llvmArgs.push_back(LAI.llvmType);
    }

#if defined(ISOLATE_SHARING)
    llvmArgs.push_back(JnjvmModule::ConstantPoolType); // cached constant pool
#endif

    LLVMAssessorInfo& LAI = JnjvmModule::getTypedefInfo(signature->ret);
    virtualType = FunctionType::get(LAI.llvmType, llvmArgs, false);
  }
  return virtualType;
}

const llvm::FunctionType* LLVMSignatureInfo::getStaticType() {
 if (!staticType) {
    // Lock here because we are called by arbitrary code
    llvm::MutexGuard locked(mvm::MvmModule::executionEngine->lock);
    std::vector<const llvm::Type*> llvmArgs;
    unsigned int size = signature->args.size();

    for (uint32 i = 0; i < size; ++i) {
      Typedef* type = signature->args.at(i);
      LLVMAssessorInfo& LAI = JnjvmModule::getTypedefInfo(type);
      llvmArgs.push_back(LAI.llvmType);
    }

#if defined(ISOLATE_SHARING)
    llvmArgs.push_back(JnjvmModule::ConstantPoolType); // cached constant pool
#endif

    LLVMAssessorInfo& LAI = JnjvmModule::getTypedefInfo(signature->ret);
    staticType = FunctionType::get(LAI.llvmType, llvmArgs, false);
  }
  return staticType;
}

const llvm::FunctionType* LLVMSignatureInfo::getNativeType() {
  if (!nativeType) {
    // Lock here because we are called by arbitrary code
    llvm::MutexGuard locked(mvm::MvmModule::executionEngine->lock);
    std::vector<const llvm::Type*> llvmArgs;
    unsigned int size = signature->args.size();
    
    llvmArgs.push_back(mvm::MvmModule::ptrType); // JNIEnv
    llvmArgs.push_back(JnjvmModule::JavaObjectType); // Class

    for (uint32 i = 0; i < size; ++i) {
      Typedef* type = signature->args.at(i);
      LLVMAssessorInfo& LAI = JnjvmModule::getTypedefInfo(type);
      llvmArgs.push_back(LAI.llvmType);
    }

#if defined(ISOLATE_SHARING)
    llvmArgs.push_back(JnjvmModule::ConstantPoolType); // cached constant pool
#endif

    LLVMAssessorInfo& LAI = JnjvmModule::getTypedefInfo(signature->ret);
    nativeType = FunctionType::get(LAI.llvmType, llvmArgs, false);
  }
  return nativeType;
}


Function* LLVMSignatureInfo::createFunctionCallBuf(bool virt) {
  
  std::vector<Value*> Args;

  Function* res = Function::Create(virt ? getVirtualBufType() : 
                                          getStaticBufType(),
                                   GlobalValue::ExternalLinkage,
                                   signature->printString(),
                                   signature->initialLoader->TheModule);
  
  BasicBlock* currentBlock = BasicBlock::Create("enter", res);
  Function::arg_iterator i = res->arg_begin();
  Value *obj, *ptr, *func;
#if defined(ISOLATE_SHARING)
  Value* ctp = i;
#endif
  ++i;
  func = i;
  ++i;
  if (virt) {
    obj = i;
    ++i;
    Args.push_back(obj);
  }
  ptr = i;

  for (std::vector<Typedef*>::iterator i = signature->args.begin(), 
            e = signature->args.end(); i!= e; ++i) {
  
    LLVMAssessorInfo& LAI = JnjvmModule::getTypedefInfo(*i);
    Value* val = new BitCastInst(ptr, LAI.llvmTypePtr, "", currentBlock);
    Value* arg = new LoadInst(val, "", currentBlock);
    Args.push_back(arg);
    ptr = GetElementPtrInst::Create(ptr, JnjvmModule::constantEight, "",
                                    currentBlock);
  }

#if defined(ISOLATE_SHARING)
  Args.push_back(ctp);
#endif

  Value* val = CallInst::Create(func, Args.begin(), Args.end(), "",
                                currentBlock);
  if (res->getFunctionType()->getReturnType() != Type::VoidTy)
    ReturnInst::Create(val, currentBlock);
  else
    ReturnInst::Create(currentBlock);
  
  return res;
}

Function* LLVMSignatureInfo::createFunctionCallAP(bool virt) {
  
  std::vector<Value*> Args;

  Function* res = Function::Create(virt ? getVirtualBufType() :
                                          getStaticBufType(),
                                   GlobalValue::ExternalLinkage,
                                   signature->printString(),
                                   signature->initialLoader->TheModule);
  
  BasicBlock* currentBlock = BasicBlock::Create("enter", res);
  Function::arg_iterator i = res->arg_begin();
  Value *obj, *ap, *func;
#if defined(ISOLATE_SHARING)
  Value* ctp = i;
#endif
  ++i;
  func = i;
  ++i;
  if (virt) {
    obj = i;
    Args.push_back(obj);
    ++i;
  }
  ap = i;

  for (std::vector<Typedef*>::iterator i = signature->args.begin(),
       e = signature->args.end(); i!= e; i++) {
    LLVMAssessorInfo& LAI = JnjvmModule::getTypedefInfo(*i);
    Args.push_back(new VAArgInst(ap, LAI.llvmType, "", currentBlock));
  }

#if defined(ISOLATE_SHARING)
  Args.push_back(ctp);
#endif

  Value* val = CallInst::Create(func, Args.begin(), Args.end(), "",
                                currentBlock);
  if (res->getFunctionType()->getReturnType() != Type::VoidTy)
    ReturnInst::Create(val, currentBlock);
  else
    ReturnInst::Create(currentBlock);
  
  return res;
}

const PointerType* LLVMSignatureInfo::getStaticPtrType() {
  if (!staticPtrType) {
    staticPtrType = PointerType::getUnqual(getStaticType());
  }
  return staticPtrType;
}

const PointerType* LLVMSignatureInfo::getVirtualPtrType() {
  if (!virtualPtrType) {
    virtualPtrType = PointerType::getUnqual(getVirtualType());
  }
  return virtualPtrType;
}

const PointerType* LLVMSignatureInfo::getNativePtrType() {
  if (!nativePtrType) {
    nativePtrType = PointerType::getUnqual(getNativeType());
  }
  return nativePtrType;
}


const FunctionType* LLVMSignatureInfo::getVirtualBufType() {
  if (!virtualBufType) {
    // Lock here because we are called by arbitrary code
    llvm::MutexGuard locked(mvm::MvmModule::executionEngine->lock);
    std::vector<const llvm::Type*> Args2;
    Args2.push_back(JnjvmModule::ConstantPoolType); // ctp
    Args2.push_back(getVirtualPtrType());
    Args2.push_back(JnjvmModule::JavaObjectType);
    Args2.push_back(JnjvmModule::ptrType);
    LLVMAssessorInfo& LAI = JnjvmModule::getTypedefInfo(signature->ret);
    virtualBufType = FunctionType::get(LAI.llvmType, Args2, false);
  }
  return virtualBufType;
}

const FunctionType* LLVMSignatureInfo::getStaticBufType() {
  if (!staticBufType) {
    // Lock here because we are called by arbitrary code
    llvm::MutexGuard locked(mvm::MvmModule::executionEngine->lock);
    std::vector<const llvm::Type*> Args;
    Args.push_back(JnjvmModule::ConstantPoolType); // ctp
    Args.push_back(getStaticPtrType());
    Args.push_back(JnjvmModule::ptrType);
    LLVMAssessorInfo& LAI = JnjvmModule::getTypedefInfo(signature->ret);
    staticBufType = FunctionType::get(LAI.llvmType, Args, false);
  }
  return staticBufType;
}

Function* LLVMSignatureInfo::getVirtualBuf() {
  if (!virtualBufFunction) {
    // Lock here because we are called by arbitrary code
    llvm::MutexGuard locked(mvm::MvmModule::executionEngine->lock);
    virtualBufFunction = createFunctionCallBuf(true);
    signature->setVirtualCallBuf((intptr_t)
      mvm::MvmModule::executionEngine->getPointerToGlobal(virtualBufFunction));
    virtualBufFunction->deleteBody();
  }
  return virtualBufFunction;
}

Function* LLVMSignatureInfo::getVirtualAP() {
  if (!virtualAPFunction) {
    // Lock here because we are called by arbitrary code
    llvm::MutexGuard locked(mvm::MvmModule::executionEngine->lock);
    virtualAPFunction = createFunctionCallAP(true);
    signature->setVirtualCallAP((intptr_t)
      mvm::MvmModule::executionEngine->getPointerToGlobal(virtualAPFunction));
    virtualAPFunction->deleteBody();
  }
  return virtualAPFunction;
}

Function* LLVMSignatureInfo::getStaticBuf() {
  if (!staticBufFunction) {
    // Lock here because we are called by arbitrary code
    llvm::MutexGuard locked(mvm::MvmModule::executionEngine->lock);
    staticBufFunction = createFunctionCallBuf(false);
    signature->setStaticCallBuf((intptr_t)
      mvm::MvmModule::executionEngine->getPointerToGlobal(staticBufFunction));
    staticBufFunction->deleteBody();
  }
  return staticBufFunction;
}

Function* LLVMSignatureInfo::getStaticAP() {
  if (!staticAPFunction) {
    // Lock here because we are called by arbitrary code
    llvm::MutexGuard locked(mvm::MvmModule::executionEngine->lock);
    staticAPFunction = createFunctionCallAP(false);
    signature->setStaticCallAP((intptr_t)
      mvm::MvmModule::executionEngine->getPointerToGlobal(staticAPFunction));
    staticAPFunction->deleteBody();
  }
  return staticAPFunction;
}

void JnjvmModule::resolveVirtualClass(Class* cl) {
  // Lock here because we may be called by a class resolver
  llvm::MutexGuard locked(mvm::MvmModule::executionEngine->lock);
  LLVMClassInfo* LCI = (LLVMClassInfo*)getClassInfo(cl);
  LCI->getVirtualType();
}

void JnjvmModule::resolveStaticClass(Class* cl) {
  // Lock here because we may be called by a class initializer
  llvm::MutexGuard locked(mvm::MvmModule::executionEngine->lock);
  LLVMClassInfo* LCI = (LLVMClassInfo*)getClassInfo(cl);
  LCI->getStaticType();
}


namespace jnjvm { 
  namespace llvm_runtime { 
    #include "LLVMRuntime.inc"
  }
}

Module* JnjvmModule::initialModule;

void JnjvmModule::initialise() {
  jnjvm::llvm_runtime::makeLLVMModuleContents(this);
  Module* module = this;
  initialModule = this;

  VTType = module->getTypeByName("VT");

  JnjvmType = 
    PointerType::getUnqual(module->getTypeByName("Jnjvm"));
  ConstantPoolType = 
    PointerType::getUnqual(module->getTypeByName("ConstantPool"));
  
  JavaObjectType = 
    PointerType::getUnqual(module->getTypeByName("JavaObject"));

  JavaArrayType =
    PointerType::getUnqual(module->getTypeByName("JavaArray"));
  
  JavaClassType =
    PointerType::getUnqual(module->getTypeByName("JavaClass"));
  
  JavaArrayUInt8Type =
    PointerType::getUnqual(module->getTypeByName("ArrayUInt8"));
  JavaArraySInt8Type =
    PointerType::getUnqual(module->getTypeByName("ArraySInt8"));
  JavaArrayUInt16Type =
    PointerType::getUnqual(module->getTypeByName("ArrayUInt16"));
  JavaArraySInt16Type =
    PointerType::getUnqual(module->getTypeByName("ArraySInt16"));
  JavaArrayUInt32Type =
    PointerType::getUnqual(module->getTypeByName("ArrayUInt32"));
  JavaArraySInt32Type =
    PointerType::getUnqual(module->getTypeByName("ArraySInt32"));
  JavaArrayLongType =
    PointerType::getUnqual(module->getTypeByName("ArrayLong"));
  JavaArrayFloatType =
    PointerType::getUnqual(module->getTypeByName("ArrayFloat"));
  JavaArrayDoubleType =
    PointerType::getUnqual(module->getTypeByName("ArrayDouble"));
  JavaArrayObjectType =
    PointerType::getUnqual(module->getTypeByName("ArrayObject"));

  CacheNodeType =
    PointerType::getUnqual(module->getTypeByName("CacheNode"));
  
  EnveloppeType =
    PointerType::getUnqual(module->getTypeByName("Enveloppe"));

#ifdef WITH_TRACER
  MarkAndTraceType = module->getFunction("MarkAndTrace")->getFunctionType();
#endif
 
  UTF8NullConstant = Constant::getNullValue(JavaArrayUInt16Type); 
  JavaClassNullConstant = Constant::getNullValue(JavaClassType); 
  JavaObjectNullConstant = Constant::getNullValue(JnjvmModule::JavaObjectType);
  MaxArraySizeConstant = ConstantInt::get(Type::Int32Ty,
                                          JavaArray::MaxArraySize);
  JavaObjectSizeConstant = ConstantInt::get(Type::Int32Ty, sizeof(JavaObject));
  JavaArraySizeConstant = 
    ConstantInt::get(Type::Int32Ty, sizeof(JavaObject) + sizeof(ssize_t));
  
  
  JavaArrayElementsOffsetConstant = mvm::MvmModule::constantTwo;
  JavaArraySizeOffsetConstant = mvm::MvmModule::constantOne;
  JavaObjectLockOffsetConstant = mvm::MvmModule::constantTwo;
  JavaObjectClassOffsetConstant = mvm::MvmModule::constantOne; 
  
  OffsetObjectSizeInClassConstant = mvm::MvmModule::constantOne;
  OffsetVTInClassConstant = mvm::MvmModule::constantTwo;
  OffsetDisplayInClassConstant = mvm::MvmModule::constantThree;
  OffsetDepthInClassConstant = mvm::MvmModule::constantFour;
  OffsetStatusInClassConstant = mvm::MvmModule::constantFive;
  OffsetTaskClassMirrorInClassConstant = mvm::MvmModule::constantSix;
  OffsetStaticInstanceInTaskClassMirrorConstant = mvm::MvmModule::constantTwo;
  OffsetStatusInTaskClassMirrorConstant = mvm::MvmModule::constantZero;
  
  ClassReadyConstant = ConstantInt::get(Type::Int32Ty, ready);

  LLVMAssessorInfo::initialise();
}

void JnjvmModule::setMethod(JavaMethod* meth, const char* name) {
  llvm::Function* func = getMethodInfo(meth)->getMethod();
  func->setName(name);
  func->setLinkage(llvm::GlobalValue::ExternalLinkage);
}

void* JnjvmModule::getMethod(JavaMethod* meth) {
  return getMethodInfo(meth)->getMethod();
}

JnjvmModule::JnjvmModule(const std::string &ModuleID, bool sc) : 
  MvmModule(ModuleID) {
  
  std::string str = 
    mvm::MvmModule::executionEngine->getTargetData()->getStringRepresentation();
  setDataLayout(str);
  staticCompilation = sc;
  if (!VTType) initialise();

  Module* module = initialModule;
   
  InterfaceLookupFunction = module->getFunction("jnjvmVirtualLookup");
  MultiCallNewFunction = module->getFunction("multiCallNew");
  InitialisationCheckFunction = module->getFunction("initialisationCheck");
  ForceInitialisationCheckFunction = 
    module->getFunction("forceInitialisationCheck");
  InitialiseClassFunction = module->getFunction("jnjvmRuntimeInitialiseClass");
  
  GetConstantPoolAtFunction = module->getFunction("getConstantPoolAt");
  ArrayLengthFunction = module->getFunction("arrayLength");
  GetVTFunction = module->getFunction("getVT");
  GetClassFunction = module->getFunction("getClass");
  ClassLookupFunction = module->getFunction("classLookup");
  GetVTFromClassFunction = module->getFunction("getVTFromClass");
  GetObjectSizeFromClassFunction = 
    module->getFunction("getObjectSizeFromClass");
 
  GetClassDelegateeFunction = module->getFunction("getClassDelegatee");
  InstanceOfFunction = module->getFunction("instanceOf");
  IsAssignableFromFunction = module->getFunction("isAssignableFrom");
  ImplementsFunction = module->getFunction("implements");
  InstantiationOfArrayFunction = module->getFunction("instantiationOfArray");
  GetDepthFunction = module->getFunction("getDepth");
  GetStaticInstanceFunction = module->getFunction("getStaticInstance");
  GetDisplayFunction = module->getFunction("getDisplay");
  GetClassInDisplayFunction = module->getFunction("getClassInDisplay");
  AquireObjectFunction = module->getFunction("JavaObjectAquire");
  ReleaseObjectFunction = module->getFunction("JavaObjectRelease");
  OverflowThinLockFunction = module->getFunction("overflowThinLock");

  VirtualFieldLookupFunction = module->getFunction("virtualFieldLookup");
  StaticFieldLookupFunction = module->getFunction("staticFieldLookup");
  
  GetExceptionFunction = module->getFunction("JavaThreadGetException");
  GetJavaExceptionFunction = module->getFunction("JavaThreadGetJavaException");
  CompareExceptionFunction = module->getFunction("JavaThreadCompareException");
  JniProceedPendingExceptionFunction = 
    module->getFunction("jniProceedPendingException");
  GetSJLJBufferFunction = module->getFunction("getSJLJBuffer");
  
  NullPointerExceptionFunction =
    module->getFunction("jnjvmNullPointerException");
  ClassCastExceptionFunction = module->getFunction("jnjvmClassCastException");
  IndexOutOfBoundsExceptionFunction = 
    module->getFunction("indexOutOfBoundsException");
  NegativeArraySizeExceptionFunction = 
    module->getFunction("negativeArraySizeException");
  OutOfMemoryErrorFunction = module->getFunction("outOfMemoryError");

  JavaObjectAllocateFunction = module->getFunction("gcmalloc");

  PrintExecutionFunction = module->getFunction("printExecution");
  PrintMethodStartFunction = module->getFunction("printMethodStart");
  PrintMethodEndFunction = module->getFunction("printMethodEnd");

  ThrowExceptionFunction = module->getFunction("JavaThreadThrowException");

  ClearExceptionFunction = module->getFunction("JavaThreadClearException");
  

#ifdef ISOLATE
  StringLookupFunction = module->getFunction("stringLookup");
#ifdef ISOLATE_SHARING
  EnveloppeLookupFunction = module->getFunction("enveloppeLookup");
  GetCtpCacheNodeFunction = module->getFunction("getCtpCacheNode");
  GetCtpClassFunction = module->getFunction("getCtpClass");
  GetJnjvmExceptionClassFunction = 
    module->getFunction("getJnjvmExceptionClass");
  GetJnjvmArrayClassFunction = module->getFunction("getJnjvmArrayClass");
  StaticCtpLookupFunction = module->getFunction("staticCtpLookup");
  SpecialCtpLookupFunction = module->getFunction("specialCtpLookup");
  GetArrayClassFunction = module->getFunction("getArrayClass");
#endif
#endif
 
#ifdef SERVICE
  ServiceCallStartFunction = module->getFunction("serviceCallStart");
  ServiceCallStopFunction = module->getFunction("serviceCallStop");
#endif

#ifdef WITH_TRACER
  MarkAndTraceFunction = module->getFunction("MarkAndTrace");
  JavaObjectTracerFunction = module->getFunction("JavaObjectTracer");
#endif

#ifndef WITHOUT_VTABLE
  VirtualLookupFunction = module->getFunction("vtableLookup");
#endif

  GetLockFunction = module->getFunction("getLock");
}

void LLVMAssessorInfo::initialise() {
  AssessorInfo[I_VOID].llvmType = Type::VoidTy;
  AssessorInfo[I_VOID].llvmTypePtr = 0;
  AssessorInfo[I_VOID].llvmNullConstant = 0;
  AssessorInfo[I_VOID].sizeInBytesConstant = 0;
  
  AssessorInfo[I_BOOL].llvmType = Type::Int8Ty;
  AssessorInfo[I_BOOL].llvmTypePtr = PointerType::getUnqual(Type::Int8Ty);
  AssessorInfo[I_BOOL].llvmNullConstant = 
    Constant::getNullValue(Type::Int8Ty);
  AssessorInfo[I_BOOL].sizeInBytesConstant = mvm::MvmModule::constantOne;
  
  AssessorInfo[I_BYTE].llvmType = Type::Int8Ty;
  AssessorInfo[I_BYTE].llvmTypePtr = PointerType::getUnqual(Type::Int8Ty);
  AssessorInfo[I_BYTE].llvmNullConstant = 
    Constant::getNullValue(Type::Int8Ty);
  AssessorInfo[I_BYTE].sizeInBytesConstant = mvm::MvmModule::constantOne;
  
  AssessorInfo[I_SHORT].llvmType = Type::Int16Ty;
  AssessorInfo[I_SHORT].llvmTypePtr = PointerType::getUnqual(Type::Int16Ty);
  AssessorInfo[I_SHORT].llvmNullConstant = 
    Constant::getNullValue(Type::Int16Ty);
  AssessorInfo[I_SHORT].sizeInBytesConstant = mvm::MvmModule::constantTwo;
  
  AssessorInfo[I_CHAR].llvmType = Type::Int16Ty;
  AssessorInfo[I_CHAR].llvmTypePtr = PointerType::getUnqual(Type::Int16Ty);
  AssessorInfo[I_CHAR].llvmNullConstant = 
    Constant::getNullValue(Type::Int16Ty);
  AssessorInfo[I_CHAR].sizeInBytesConstant = mvm::MvmModule::constantTwo;
  
  AssessorInfo[I_INT].llvmType = Type::Int32Ty;
  AssessorInfo[I_INT].llvmTypePtr = PointerType::getUnqual(Type::Int32Ty);
  AssessorInfo[I_INT].llvmNullConstant = 
    Constant::getNullValue(Type::Int32Ty);
  AssessorInfo[I_INT].sizeInBytesConstant = mvm::MvmModule::constantFour;
  
  AssessorInfo[I_FLOAT].llvmType = Type::FloatTy;
  AssessorInfo[I_FLOAT].llvmTypePtr = PointerType::getUnqual(Type::FloatTy);
  AssessorInfo[I_FLOAT].llvmNullConstant = 
    Constant::getNullValue(Type::FloatTy);
  AssessorInfo[I_FLOAT].sizeInBytesConstant = mvm::MvmModule::constantFour;
  
  AssessorInfo[I_LONG].llvmType = Type::Int64Ty;
  AssessorInfo[I_LONG].llvmTypePtr = PointerType::getUnqual(Type::Int64Ty);
  AssessorInfo[I_LONG].llvmNullConstant = 
    Constant::getNullValue(Type::Int64Ty);
  AssessorInfo[I_LONG].sizeInBytesConstant = mvm::MvmModule::constantEight;
  
  AssessorInfo[I_DOUBLE].llvmType = Type::DoubleTy;
  AssessorInfo[I_DOUBLE].llvmTypePtr = PointerType::getUnqual(Type::DoubleTy);
  AssessorInfo[I_DOUBLE].llvmNullConstant = 
    Constant::getNullValue(Type::DoubleTy);
  AssessorInfo[I_DOUBLE].sizeInBytesConstant = mvm::MvmModule::constantEight;
  
  AssessorInfo[I_TAB].llvmType = JnjvmModule::JavaObjectType;
  AssessorInfo[I_TAB].llvmTypePtr =
    PointerType::getUnqual(JnjvmModule::JavaObjectType);
  AssessorInfo[I_TAB].llvmNullConstant =
    JnjvmModule::JavaObjectNullConstant;
  AssessorInfo[I_TAB].sizeInBytesConstant = mvm::MvmModule::constantPtrSize;
  
  AssessorInfo[I_REF].llvmType = JnjvmModule::JavaObjectType;
  AssessorInfo[I_REF].llvmTypePtr =
    PointerType::getUnqual(JnjvmModule::JavaObjectType);
  AssessorInfo[I_REF].llvmNullConstant =
    JnjvmModule::JavaObjectNullConstant;
  AssessorInfo[I_REF].sizeInBytesConstant = mvm::MvmModule::constantPtrSize;
}

std::map<const char, LLVMAssessorInfo> LLVMAssessorInfo::AssessorInfo;

LLVMAssessorInfo& JnjvmModule::getTypedefInfo(Typedef* type) {
  return LLVMAssessorInfo::AssessorInfo[type->getKey()->elements[0]];
}

static AnnotationID JavaMethod_ID(
  AnnotationManager::getID("Java::JavaMethod"));


LLVMMethodInfo::LLVMMethodInfo(JavaMethod* M) : 
  llvm::Annotation(JavaMethod_ID), methodDef(M), methodFunction(0),
  offsetConstant(0), functionType(0) {}

JavaMethod* LLVMMethodInfo::get(const llvm::Function* F) {
  LLVMMethodInfo *MI = (LLVMMethodInfo*)F->getAnnotation(JavaMethod_ID);
  if (MI) return MI->methodDef;
  return 0;
}

#ifdef SERVICE
Value* JnjvmModule::getIsolate(Jnjvm* isolate) {
  llvm::GlobalVariable* varGV = 0;
  isolate_iterator End = isolates.end();
  isolate_iterator I = isolates.find(isolate);
  if (I == End) {
    
      
    Constant* cons = 
      ConstantExpr::getIntToPtr(ConstantInt::get(Type::Int64Ty,
                                                 uint64_t(isolate)),
                                ptrType);

    varGV = new GlobalVariable(ptrType, !staticCompilation,
                               GlobalValue::ExternalLinkage,
                               cons, "", this);
    
    isolates.insert(std::make_pair(isolate, varGV));
  } else {
    varGV = I->second;
  }
  return varGV;
}
#endif
