//===----------- JavaJIT.cpp - Java just in time compiler -----------------===//
//
//                            The VMKit project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//


#define DEBUG 0
#define JNJVM_COMPILE 0
#define JNJVM_EXECUTE 0

#include <cstring>

#include <llvm/Constants.h>
#include <llvm/DerivedTypes.h>
#include <llvm/Function.h>
#include <llvm/Instructions.h>
#include <llvm/Module.h>
#include <llvm/Type.h>
#include <llvm/Analysis/DebugInfo.h>
#include <llvm/Support/CFG.h>

#include "mvm/JIT.h"

#include "debug.h"
#include "JavaArray.h"
#include "JavaClass.h"
#include "JavaConstantPool.h"
#include "JavaObject.h"
#include "JavaJIT.h"
#include "JavaString.h"
#include "JavaThread.h"
#include "JavaTypes.h"
#include "JavaUpcalls.h"
#include "Jnjvm.h"
#include "Reader.h"

#include "j3/JavaLLVMCompiler.h"
#include "j3/J3Intrinsics.h"

using namespace j3;
using namespace llvm;

static bool needsInitialisationCheck(Class* cl, Class* compilingClass) {
#ifdef SERVICE
  return true;
#else

  if (cl->isReadyForCompilation() || 
      (!cl->isInterface() && compilingClass->isAssignableFrom(cl))) {
    return false;
  }

  if (!cl->needsInitialisationCheck()) {
    if (!cl->isReady()) {
      cl->setInitializationState(ready);
    }
    return false;
  }

  return true;
#endif
}

bool JavaJIT::canBeInlined(JavaMethod* meth) {
  JnjvmClassLoader* loader = meth->classDef->classLoader;
  return (meth->canBeInlined &&
          meth != compilingMethod && inlineMethods[meth] == 0 &&
          (loader == compilingClass->classLoader ||
           loader == compilingClass->classLoader->bootstrapLoader));
}

void JavaJIT::invokeVirtual(uint16 index) {
  
  JavaConstantPool* ctpInfo = compilingClass->ctpInfo;
  CommonClass* cl = 0;
  JavaMethod* meth = 0;
  ctpInfo->infoOfMethod(index, ACC_VIRTUAL, cl, meth);
  bool canBeDirect = false;
  Value* val = NULL;  // The return from the method.
 
  if ((cl && isFinal(cl->access)) || 
      (meth && (isFinal(meth->access) || isPrivate(meth->access)))) {
    canBeDirect = true;
  }

  if (meth && isInterface(meth->classDef->access)) {
    // This can happen because we compute miranda methods before resolving
    // interfaces.
		return invokeInterface(index);
	}
 
  const UTF8* name = 0;
  Signdef* signature = ctpInfo->infoOfInterfaceOrVirtualMethod(index, name);

  Value* obj = objectStack[stack.size() - signature->nbArguments - 1];
  JavaObject* source = TheCompiler->getFinalObject(obj);
  if (source) {
    canBeDirect = true;
    CommonClass* sourceClass = source->getClass();
    Class* lookup = sourceClass->isArray() ? sourceClass->super :
                                             sourceClass->asClass();
    meth = lookup->lookupMethodDontThrow(name, signature->keyName, false,
                                         true, 0);
  }
  
  if (TheCompiler->isStaticCompiling()) {
    CommonClass* unique = TheCompiler->getUniqueBaseClass(cl);
    if (unique) {
      canBeDirect = true;
      Class* lookup = unique->isArray() ? unique->super : unique->asClass();
      meth = lookup->lookupMethodDontThrow(name, signature->keyName, false,
                                           true, 0);
    }
  }
 
#if !defined(WITHOUT_VTABLE)
  Typedef* retTypedef = signature->getReturnType();
  std::vector<Value*> args; // size = [signature->nbIn + 3];
  LLVMSignatureInfo* LSI = TheCompiler->getSignatureInfo(signature);
  const llvm::FunctionType* virtualType = LSI->getVirtualType();
  FunctionType::param_iterator it  = virtualType->param_end();
  makeArgs(it, index, args, signature->nbArguments + 1);
  const llvm::Type* retType = virtualType->getReturnType();
   
  JITVerifyNull(args[0]);

  bool needsInit = false;
  if (canBeDirect && meth && !TheCompiler->needsCallback(meth, &needsInit)) {
    val = invoke(TheCompiler->getMethod(meth), args, "", currentBlock);
  } else {

    BasicBlock* endBlock = 0;
    PHINode* node = 0;
#if 0
    // TODO: enable this only when inlining?
    if (meth && !isAbstract(meth->access)) {
      Value* cl = CallInst::Create(intrinsics->GetClassFunction, args[0], "",
                                   currentBlock);
      Value* cl2 = intrinsics->getNativeClass(meth->classDef);
      if (cl2->getType() != intrinsics->JavaCommonClassType) {
        cl2 = new BitCastInst(cl2, intrinsics->JavaCommonClassType, "", currentBlock);
      }

      Value* test = new ICmpInst(*currentBlock, ICmpInst::ICMP_EQ, cl, cl2, "");

      BasicBlock* trueBlock = createBasicBlock("true virtual invoke");
      BasicBlock* falseBlock = createBasicBlock("false virtual invoke");
      endBlock = createBasicBlock("end virtual invoke");
      BranchInst::Create(trueBlock, falseBlock, test, currentBlock);
      currentBlock = trueBlock;
      Value* res = 0;
      if (canBeInlined(meth)) {
        res = invokeInline(meth, args);
      } else {
        Function* func = intrinsics->getMethod(meth);
        res = invoke(func, args, "", currentBlock);
      }
      BranchInst::Create(endBlock, currentBlock);
      if (retType != Type::getVoidTy(*llvmContext)) {
        node = PHINode::Create(virtualType->getReturnType(), "", endBlock);
        node->addIncoming(res, currentBlock);
      }
      currentBlock = falseBlock;
    }
#endif

    Value* VT = CallInst::Create(intrinsics->GetVTFunction, args[0], "",
                                 currentBlock);
    Value* indexes2[2];
    indexes2[0] = intrinsics->constantZero;

#ifdef ISOLATE_SHARING
    Value* indexesCtp; //[3];
#endif
    if (meth) {
      LLVMMethodInfo* LMI = TheCompiler->getMethodInfo(meth);
      Constant* Offset = LMI->getOffset();
      indexes2[1] = Offset;
#ifdef ISOLATE_SHARING
      indexesCtp = ConstantInt::get(Type::getInt32Ty(*llvmContext),
                                    Offset->getZExtValue() * -1);
#endif
    } else {
   
      GlobalVariable* GV = new GlobalVariable(*llvmFunction->getParent(),
                                              Type::getInt32Ty(*llvmContext),
                                              false,
                                              GlobalValue::ExternalLinkage,
                                              intrinsics->constantZero, "");
    
      BasicBlock* resolveVirtual = createBasicBlock("resolveVirtual");
      BasicBlock* endResolveVirtual = createBasicBlock("endResolveVirtual");
      PHINode* node = PHINode::Create(Type::getInt32Ty(*llvmContext), "",
                                      endResolveVirtual);

      Value* load = new LoadInst(GV, "", false, currentBlock);
      Value* test = new ICmpInst(*currentBlock, ICmpInst::ICMP_EQ, load,
                                 intrinsics->constantZero, "");
      BranchInst::Create(resolveVirtual, endResolveVirtual, test, currentBlock);
      node->addIncoming(load, currentBlock);
      currentBlock = resolveVirtual;
      std::vector<Value*> Args;
      Args.push_back(TheCompiler->getNativeClass(compilingClass));
      Args.push_back(ConstantInt::get(Type::getInt32Ty(*llvmContext), index));
      Args.push_back(GV);
      Args.push_back(args[0]);
      load = invoke(intrinsics->VirtualLookupFunction, Args, "", currentBlock);
      node->addIncoming(load, currentBlock);
      BranchInst::Create(endResolveVirtual, currentBlock);
      currentBlock = endResolveVirtual;

      indexes2[1] = node;
#ifdef ISOLATE_SHARING
      Value* mul = BinaryOperator::CreateMul(val, intrinsics->constantMinusOne,
                                             "", currentBlock);
      indexesCtp = mul;
#endif
    }
 
    Value* FuncPtr = GetElementPtrInst::Create(VT, indexes2, indexes2 + 2, "",
                                               currentBlock);
    
    Value* Func = new LoadInst(FuncPtr, "", currentBlock);
  
    Func = new BitCastInst(Func, LSI->getVirtualPtrType(), "", currentBlock);
#ifdef ISOLATE_SHARING
    Value* CTP = GetElementPtrInst::Create(VT, indexesCtp, "", currentBlock);
    
    CTP = new LoadInst(CTP, "", currentBlock);
    CTP = new BitCastInst(CTP, intrinsics->ConstantPoolType, "", currentBlock);
    args.push_back(CTP);
#endif
    val = invoke(Func, args, "", currentBlock);
  
    if (endBlock) {
      if (node) {
        node->addIncoming(val, currentBlock);
        val = node;
      }
      BranchInst::Create(endBlock, currentBlock);
      currentBlock = endBlock;
    }
  }

  if (retType != Type::getVoidTy(*llvmContext)) {
    if (retType == intrinsics->JavaObjectType) {
      JnjvmClassLoader* JCL = compilingClass->classLoader;
      push(val, false, signature->getReturnType()->findAssocClass(JCL));
    } else {
      push(val, retTypedef->isUnsigned());
      if (retType == Type::getDoubleTy(*llvmContext) || retType == Type::getInt64Ty(*llvmContext)) {
        push(intrinsics->constantZero, false);
      }
    }
  }
    
#else
  return invokeInterface(index);
#endif
}

llvm::Value* JavaJIT::getCurrentThread(const llvm::Type* Ty) {
  Value* FrameAddr = CallInst::Create(intrinsics->llvm_frameaddress,
                                     	intrinsics->constantZero, "", currentBlock);
  Value* threadId = new PtrToIntInst(FrameAddr, intrinsics->pointerSizeType, "",
                              			 currentBlock);
  threadId = BinaryOperator::CreateAnd(threadId, intrinsics->constantThreadIDMask,
                                       "", currentBlock);
  threadId = new IntToPtrInst(threadId, Ty, "", currentBlock);

  return threadId;
}

extern "C" void j3ThrowExceptionFromJIT();

llvm::Function* JavaJIT::nativeCompile(intptr_t natPtr) {
  
  PRINT_DEBUG(JNJVM_COMPILE, 1, COLOR_NORMAL, "native compile %s.%s\n",
              UTF8Buffer(compilingClass->name).cString(),
              UTF8Buffer(compilingMethod->name).cString());
  
  bool stat = isStatic(compilingMethod->access);

  const FunctionType *funcType = llvmFunction->getFunctionType();
  const llvm::Type* returnType = funcType->getReturnType();
  
  bool j3 = false;
  
  const UTF8* jniConsClName = compilingClass->name;
  const UTF8* jniConsName = compilingMethod->name;
  const UTF8* jniConsType = compilingMethod->type;
  sint32 clen = jniConsClName->size;
  sint32 mnlen = jniConsName->size;
  sint32 mtlen = jniConsType->size;

  char* functionName = (char*)alloca(3 + JNI_NAME_PRE_LEN + 
                            ((mnlen + clen + mtlen) << 3));
  
  if (!natPtr)
    natPtr = compilingClass->classLoader->nativeLookup(compilingMethod, j3,
                                                       functionName);
  
  if (!natPtr && !TheCompiler->isStaticCompiling()) {
    currentBlock = createBasicBlock("start");
    CallInst::Create(intrinsics->ThrowExceptionFromJITFunction, "", currentBlock);
    if (returnType != Type::getVoidTy(*llvmContext))
      ReturnInst::Create(*llvmContext, Constant::getNullValue(returnType), currentBlock);
    else
      ReturnInst::Create(*llvmContext, currentBlock);
  
    PRINT_DEBUG(JNJVM_COMPILE, 1, COLOR_NORMAL, "end native compile %s.%s\n",
                UTF8Buffer(compilingClass->name).cString(),
                UTF8Buffer(compilingMethod->name).cString());
  
    return llvmFunction;
  }
  
  
  Function* func = llvmFunction;
  if (j3) {
    compilingMethod->setCompiledPtr((void*)natPtr, functionName);
    llvmFunction->clearGC();
    return llvmFunction;
  }


  currentExceptionBlock = endExceptionBlock = 0;
  currentBlock = createBasicBlock("start");
  endBlock = createBasicBlock("end block");
  
  if (returnType != Type::getVoidTy(*llvmContext)) {
    endNode = PHINode::Create(returnType, "", endBlock);
  }
  
  // Allocate currentLocalIndexNumber pointer
  Value* temp = new AllocaInst(Type::getInt32Ty(*llvmContext), "",
                               currentBlock);
  new StoreInst(intrinsics->constantZero, temp, false, currentBlock);
  
  // Allocate oldCurrentLocalIndexNumber pointer
  Value* oldCLIN = new AllocaInst(PointerType::getUnqual(Type::getInt32Ty(*llvmContext)), "",
                                  currentBlock);
  
  Constant* sizeF = ConstantInt::get(Type::getInt32Ty(*llvmContext), 2 * sizeof(void*));
  Value* Frame = new AllocaInst(Type::getInt8Ty(*llvmContext), sizeF, "", currentBlock);
  
  // Synchronize before saying we're entering native
  if (isSynchro(compilingMethod->access))
    beginSynchronize();

  uint32 nargs = func->arg_size() + 1 + (stat ? 1 : 0); 
  std::vector<Value*> nativeArgs;
  
  
  Value* threadId = getCurrentThread(intrinsics->JavaThreadType);

  Value* geps[2] = { intrinsics->constantZero,
                     intrinsics->OffsetJNIInThreadConstant };

  Value* jniEnv = GetElementPtrInst::Create(threadId, geps, geps + 2, "",
                                            currentBlock);
 
  jniEnv = new BitCastInst(jniEnv, intrinsics->ptrType, "", currentBlock);

  nativeArgs.push_back(jniEnv);

  uint32 index = 0;
  if (stat) {
#ifdef ISOLATE_SHARING
    Value* val = getClassCtp();
    Value* cl = CallInst::Create(intrinsics->GetClassDelegateePtrFunction,
                                 val, "", currentBlock);
#else
    Value* cl = TheCompiler->getJavaClassPtr(compilingClass);
#endif
    nativeArgs.push_back(cl);
    index = 2;
  } else {
    index = 1;
  }
  for (Function::arg_iterator i = func->arg_begin(); 
       index < nargs; ++i, ++index) {
    
    if (i->getType() == intrinsics->JavaObjectType) {
      BasicBlock* BB = createBasicBlock("");
      BasicBlock* NotZero = createBasicBlock("");
      const Type* Ty = PointerType::getUnqual(intrinsics->JavaObjectType);
      PHINode* node = PHINode::Create(Ty, "", BB);

      Value* test = new ICmpInst(*currentBlock, ICmpInst::ICMP_EQ, i,
                                 intrinsics->JavaObjectNullConstant, "");

      node->addIncoming(Constant::getNullValue(Ty), currentBlock);
      BranchInst::Create(BB, NotZero, test, currentBlock);

      currentBlock = NotZero;

      Instruction* temp = new AllocaInst(intrinsics->JavaObjectType, "",
                                         func->begin()->getTerminator());
      
      if (TheCompiler->useCooperativeGC()) {
        Value* GCArgs[2] = { 
          new BitCastInst(temp, intrinsics->ptrPtrType, "",
                          func->begin()->getTerminator()),
          intrinsics->constantPtrNull
        };
        
        CallInst::Create(intrinsics->llvm_gc_gcroot, GCArgs, GCArgs + 2, "",
                         func->begin()->getTerminator());
      }
      
      new StoreInst(i, temp, false, currentBlock);
      node->addIncoming(temp, currentBlock);
      BranchInst::Create(BB, currentBlock);

      currentBlock = BB;

      nativeArgs.push_back(node);
    } else {
      nativeArgs.push_back(i);
    }
  }
  
  
  Instruction* ResultObject = 0;
  if (returnType == intrinsics->JavaObjectType) {
    ResultObject = new AllocaInst(intrinsics->JavaObjectType, "",
                                  func->begin()->begin());
    
    if (TheCompiler->useCooperativeGC()) {
      
      Value* GCArgs[2] = { 
        new BitCastInst(ResultObject, intrinsics->ptrPtrType, "", currentBlock),
        intrinsics->constantPtrNull
      };
      
      CallInst::Create(intrinsics->llvm_gc_gcroot, GCArgs, GCArgs + 2, "",
                       currentBlock);
    } else {
      new StoreInst(intrinsics->JavaObjectNullConstant, ResultObject, "",
                    currentBlock);
    }
  }
  
  Value* nativeFunc = TheCompiler->getNativeFunction(compilingMethod,
                                                     (void*)natPtr);

  if (TheCompiler->isStaticCompiling()) {
    Value* Arg = TheCompiler->getMethodInClass(compilingMethod); 
    
    // If the global variable is null, then load it.
    BasicBlock* unloadedBlock = createBasicBlock("");
    BasicBlock* endBlock = createBasicBlock("");
    Value* test = new LoadInst(nativeFunc, "", currentBlock);
    const llvm::Type* Ty = test->getType();
    PHINode* node = PHINode::Create(Ty, "", endBlock);
    node->addIncoming(test, currentBlock);
    Value* cmp = new ICmpInst(*currentBlock, ICmpInst::ICMP_EQ, test,
                              Constant::getNullValue(Ty), "");
    BranchInst::Create(unloadedBlock, endBlock, cmp, currentBlock);
    currentBlock = unloadedBlock;

    Value* res = CallInst::Create(TheCompiler->NativeLoader, Arg, "",
                                  currentBlock);

    res = new BitCastInst(res, Ty, "", currentBlock);
    new StoreInst(res, nativeFunc, currentBlock);
    node->addIncoming(res, currentBlock);
    BranchInst::Create(endBlock, currentBlock);
    currentBlock = endBlock;
    nativeFunc = node;
  }
  
  Value* Args4[3] = { temp, oldCLIN, Frame };

  CallInst::Create(intrinsics->StartJNIFunction, Args4, Args4 + 3, "",
                   currentBlock);
  
  Value* result = llvm::CallInst::Create(nativeFunc, nativeArgs.begin(),
                                         nativeArgs.end(), "", currentBlock);

  if (returnType == intrinsics->JavaObjectType) {
    const Type* Ty = PointerType::getUnqual(intrinsics->JavaObjectType);
    Constant* C = Constant::getNullValue(Ty);
    Value* cmp = new ICmpInst(*currentBlock, ICmpInst::ICMP_EQ, result, C, "");
    BasicBlock* loadBlock = createBasicBlock("");

    endNode->addIncoming(intrinsics->JavaObjectNullConstant, currentBlock);
    BranchInst::Create(endBlock, loadBlock, cmp, currentBlock);

    currentBlock = loadBlock;
    result = new LoadInst(result, "", currentBlock);
    new StoreInst(result, ResultObject, "", currentBlock);
    endNode->addIncoming(result, currentBlock);

  } else if (returnType != Type::getVoidTy(*llvmContext)) {
    endNode->addIncoming(result, currentBlock);
  }
  
  BranchInst::Create(endBlock, currentBlock);


  currentBlock = endBlock; 
 
  Value* Args2[1] = { oldCLIN };

  CallInst::Create(intrinsics->EndJNIFunction, Args2, Args2 + 1, "", currentBlock);
  
  // Synchronize after leaving native.
  if (isSynchro(compilingMethod->access))
    endSynchronize();
  
  if (returnType != Type::getVoidTy(*llvmContext))
    ReturnInst::Create(*llvmContext, endNode, currentBlock);
  else
    ReturnInst::Create(*llvmContext, currentBlock);
  
  PRINT_DEBUG(JNJVM_COMPILE, 1, COLOR_NORMAL, "end native compile %s.%s\n",
              UTF8Buffer(compilingClass->name).cString(),
              UTF8Buffer(compilingMethod->name).cString());
  
  if (codeInfo.size()) { 
    compilingMethod->codeInfo = new CodeLineInfo[codeInfo.size()];
    for (uint32 i = 0; i < codeInfo.size(); i++) {
      compilingMethod->codeInfo[i].lineNumber = codeInfo[i].lineNumber;
      compilingMethod->codeInfo[i].ctpIndex = codeInfo[i].ctpIndex;
      compilingMethod->codeInfo[i].bytecodeIndex = codeInfo[i].bytecodeIndex;
      compilingMethod->codeInfo[i].bytecode = codeInfo[i].bytecode;
    }
  }
 
  return llvmFunction;
}

void JavaJIT::monitorEnter(Value* obj) {
  std::vector<Value*> gep;
  gep.push_back(intrinsics->constantZero);
  gep.push_back(intrinsics->JavaObjectLockOffsetConstant);
  Value* lockPtr = GetElementPtrInst::Create(obj, gep.begin(), gep.end(), "",
                                             currentBlock);
  
  Value* lock = new LoadInst(lockPtr, "", currentBlock);
  lock = new PtrToIntInst(lock, intrinsics->pointerSizeType, "", currentBlock);
  Value* GCMask = ConstantInt::get(intrinsics->pointerSizeType,
                                   mvm::GCMask);

  lock = BinaryOperator::CreateAnd(lock, GCMask, "", currentBlock);

  lockPtr = new BitCastInst(lockPtr, 
                            PointerType::getUnqual(intrinsics->pointerSizeType),
                            "", currentBlock);
  Value* threadId = getCurrentThread(intrinsics->MutatorThreadType);
  threadId = new PtrToIntInst(threadId, intrinsics->pointerSizeType, "",
                              currentBlock);
  Value* newValMask = BinaryOperator::CreateOr(threadId, lock, "",
                                               currentBlock);

  std::vector<Value*> atomicArgs;
  atomicArgs.push_back(lockPtr);
  atomicArgs.push_back(lock);
  atomicArgs.push_back(newValMask);

  // Do the atomic compare and swap.
  Value* atomic = CallInst::Create(intrinsics->llvm_atomic_lcs_ptr,
                                   atomicArgs.begin(), atomicArgs.end(), "",
                                   currentBlock);
  
  Value* cmp = new ICmpInst(*currentBlock, ICmpInst::ICMP_EQ, atomic,
                            lock, "");
  
  BasicBlock* OK = createBasicBlock("synchronize passed");
  BasicBlock* NotOK = createBasicBlock("synchronize did not pass");
  BasicBlock* FatLockBB = createBasicBlock("fat lock");
  BasicBlock* ThinLockBB = createBasicBlock("thin lock");

  BranchInst::Create(OK, NotOK, cmp, currentBlock);

  currentBlock = NotOK;
  
  // The compare and swap did not pass, look if it's a thin lock
  Value* isThin = BinaryOperator::CreateAnd(atomic, intrinsics->constantFatMask, "",
                                            currentBlock);
  cmp = new ICmpInst(*currentBlock, ICmpInst::ICMP_EQ, isThin,
                     intrinsics->constantPtrZero, "");
  
  BranchInst::Create(ThinLockBB, FatLockBB, cmp, currentBlock);

  // It's a thin lock. Look if we're the owner of this lock.
  currentBlock = ThinLockBB;
  Value* idMask = ConstantInt::get(intrinsics->pointerSizeType, mvm::Thread::IDMask);
  Value* cptMask = ConstantInt::get(intrinsics->pointerSizeType, mvm::ThinCountMask);
  Value* IdInLock = BinaryOperator::CreateAnd(atomic, idMask, "", currentBlock);
  Value* owner = new ICmpInst(*currentBlock, ICmpInst::ICMP_EQ, threadId,
                              IdInLock, "");

  BasicBlock* OwnerBB = createBasicBlock("owner thread");

  BranchInst::Create(OwnerBB, FatLockBB, owner, currentBlock);
  currentBlock = OwnerBB;

  // OK, we are the owner, now check if the counter will overflow.
  Value* count = BinaryOperator::CreateAnd(atomic, cptMask, "", currentBlock);
  cmp = new ICmpInst(*currentBlock, ICmpInst::ICMP_ULT, count, cptMask, "");

  BasicBlock* IncCounterBB = createBasicBlock("Increment counter");
  BasicBlock* OverflowCounterBB = createBasicBlock("Overflow counter");

  BranchInst::Create(IncCounterBB, OverflowCounterBB, cmp, currentBlock);
  currentBlock = IncCounterBB;
  
  // The counter will not overflow, increment it.
  Value* One = ConstantInt::get(intrinsics->pointerSizeType, mvm::ThinCountAdd);
  Value* Add = BinaryOperator::CreateAdd(One, atomic, "", currentBlock);
  new StoreInst(Add, lockPtr, false, currentBlock);
  BranchInst::Create(OK, currentBlock);

  currentBlock = OverflowCounterBB;

  // The counter will overflow, call this function to create a new lock,
  // lock it 0x101 times, and pass.
  CallInst::Create(intrinsics->OverflowThinLockFunction, obj, "",
                   currentBlock);
  BranchInst::Create(OK, currentBlock);
  
  currentBlock = FatLockBB;
  // Either it's a fat lock or there is contention.
  CallInst::Create(intrinsics->AquireObjectFunction, obj, "", currentBlock);
  BranchInst::Create(OK, currentBlock);
  currentBlock = OK;
}

void JavaJIT::monitorExit(Value* obj) {
  std::vector<Value*> gep;
  gep.push_back(intrinsics->constantZero);
  gep.push_back(intrinsics->JavaObjectLockOffsetConstant);
  Value* lockPtr = GetElementPtrInst::Create(obj, gep.begin(), gep.end(), "",
                                             currentBlock);
  lockPtr = new BitCastInst(lockPtr, 
                            PointerType::getUnqual(intrinsics->pointerSizeType),
                            "", currentBlock);
  Value* lock = new LoadInst(lockPtr, "", currentBlock);
  Value* GCMask = ConstantInt::get(intrinsics->pointerSizeType, ~mvm::GCMask);

  Value* lockedMask = BinaryOperator::CreateAnd(lock, GCMask, "", currentBlock);
  
  Value* threadId = getCurrentThread(intrinsics->MutatorThreadType);
  threadId = new PtrToIntInst(threadId, intrinsics->pointerSizeType, "",
                              currentBlock);
  
  Value* cmp = new ICmpInst(*currentBlock, ICmpInst::ICMP_EQ, lockedMask,
                            threadId, "");
  
  
  BasicBlock* EndUnlock = createBasicBlock("end unlock");
  BasicBlock* LockedOnceBB = createBasicBlock("desynchronize thin lock");
  BasicBlock* NotLockedOnceBB = 
    createBasicBlock("simple desynchronize did not pass");
  BasicBlock* FatLockBB = createBasicBlock("fat lock");
  BasicBlock* ThinLockBB = createBasicBlock("thin lock");
  
  BranchInst::Create(LockedOnceBB, NotLockedOnceBB, cmp, currentBlock);
  
  // Locked once, set zero
  currentBlock = LockedOnceBB;
  GCMask = ConstantInt::get(intrinsics->pointerSizeType, mvm::GCMask);
  lockedMask = BinaryOperator::CreateAnd(lock, GCMask, "", currentBlock);
  new StoreInst(lockedMask, lockPtr, false, currentBlock);
  BranchInst::Create(EndUnlock, currentBlock);

  currentBlock = NotLockedOnceBB;
  // Look if the lock is thin.
  Value* isThin = BinaryOperator::CreateAnd(lock, intrinsics->constantFatMask, "",
                                            currentBlock);
  cmp = new ICmpInst(*currentBlock, ICmpInst::ICMP_EQ, isThin,
                     intrinsics->constantPtrZero, "");
  
  BranchInst::Create(ThinLockBB, FatLockBB, cmp, currentBlock);
  
  currentBlock = ThinLockBB;

  // Decrement the counter.
  Value* One = ConstantInt::get(intrinsics->pointerSizeType, mvm::ThinCountAdd);
  Value* Sub = BinaryOperator::CreateSub(lock, One, "", currentBlock);
  new StoreInst(Sub, lockPtr, false, currentBlock);
  BranchInst::Create(EndUnlock, currentBlock);

  currentBlock = FatLockBB;

  // Either it's a fat lock or there is contention.
  CallInst::Create(intrinsics->ReleaseObjectFunction, obj, "", currentBlock);
  BranchInst::Create(EndUnlock, currentBlock);
  currentBlock = EndUnlock;
}



#ifdef ISOLATE_SHARING
Value* JavaJIT::getStaticInstanceCtp() {
  Value* cl = getClassCtp();
  Value* indexes[2] = { intrinsics->constantZero, module->constantSeven };
  Value* arg1 = GetElementPtrInst::Create(cl, indexes, indexes + 2,
                                          "", currentBlock);
  arg1 = new LoadInst(arg1, "", false, currentBlock);
  return arg1;
  
}

Value* JavaJIT::getClassCtp() {
  Value* indexes = intrinsics->constantOne;
  Value* arg1 = GetElementPtrInst::Create(ctpCache, indexes.begin(),
                                          indexes.end(),  "", currentBlock);
  arg1 = new LoadInst(arg1, "", false, currentBlock);
  arg1 = new BitCastInst(arg1, intrinsics->JavaClassType, "", currentBlock);
  return arg1;
}
#endif

void JavaJIT::beginSynchronize() {
  Value* obj = 0;
  if (isVirtual(compilingMethod->access)) {
    obj = llvmFunction->arg_begin();
  } else {
    obj = TheCompiler->getJavaClass(compilingClass);
  }
  monitorEnter(obj);
}

void JavaJIT::endSynchronize() {
  Value* obj = 0;
  if (isVirtual(compilingMethod->access)) {
    obj = llvmFunction->arg_begin();
  } else {
    obj = TheCompiler->getJavaClass(compilingClass);
  }
  monitorExit(obj);
}


static void removeUnusedLocals(std::vector<AllocaInst*>& locals) {
  for (std::vector<AllocaInst*>::iterator i = locals.begin(),
       e = locals.end(); i != e; ++i) {
    AllocaInst* temp = *i;
    unsigned uses = temp->getNumUses();
    if (!uses) {
      temp->eraseFromParent();
    } else if (uses == 1 && dyn_cast<StoreInst>(temp->use_begin())) {
      dyn_cast<StoreInst>(temp->use_begin())->eraseFromParent();
      temp->eraseFromParent();
    }
  }
}
  
static void removeUnusedObjects(std::vector<AllocaInst*>& objects,
                                J3Intrinsics* intrinsics, bool coop) {
  for (std::vector<AllocaInst*>::iterator i = objects.begin(),
       e = objects.end(); i != e; ++i) {
    AllocaInst* temp = *i;
    unsigned uses = temp->getNumUses();
    if (!uses) {
      temp->eraseFromParent();
    } else if (uses == 1 && dyn_cast<StoreInst>(temp->use_begin())) {
      dyn_cast<StoreInst>(temp->use_begin())->eraseFromParent();
      temp->eraseFromParent();
    } else {
      if (coop) {
        Instruction* I = new BitCastInst(temp, intrinsics->ptrPtrType, "");
        I->insertAfter(temp);
        Value* GCArgs[2] = { I, intrinsics->constantPtrNull };
        Instruction* C = CallInst::Create(intrinsics->llvm_gc_gcroot, GCArgs,
                                          GCArgs + 2, "");
        C->insertAfter(I);
      }
    }
  }
}

Instruction* JavaJIT::inlineCompile(BasicBlock*& curBB,
                                    BasicBlock* endExBlock,
                                    std::vector<Value*>& args) {
  DbgSubprogram = TheCompiler->GetDbgSubprogram(compilingMethod);

  PRINT_DEBUG(JNJVM_COMPILE, 1, COLOR_NORMAL, "inline compile %s.%s\n",
              UTF8Buffer(compilingClass->name).cString(),
              UTF8Buffer(compilingMethod->name).cString());
  
  Attribut* codeAtt = compilingMethod->lookupAttribut(Attribut::codeAttribut);
  
  if (!codeAtt) {
    fprintf(stderr, "I haven't verified your class file and it's malformed:"
                    " no code attribut found for %s.%s!\n",
                    UTF8Buffer(compilingClass->name).cString(),
                    UTF8Buffer(compilingMethod->name).cString());
    abort();
  }

  Reader reader(codeAtt, &(compilingClass->bytes));
  uint16 maxStack = reader.readU2();
  uint16 maxLocals = reader.readU2();
  uint32 codeLen = reader.readU4();
  uint32 start = reader.cursor;
  
  reader.seek(codeLen, Reader::SeekCur);
  
  LLVMMethodInfo* LMI = TheCompiler->getMethodInfo(compilingMethod);
  assert(LMI);
  Function* func = LMI->getMethod();

  const Type* returnType = func->getReturnType();
  endBlock = createBasicBlock("end");

  currentBlock = curBB;
  endExceptionBlock = endExBlock;

  opcodeInfos = new Opinfo[codeLen];
  memset(opcodeInfos, 0, codeLen * sizeof(Opinfo));
  for (uint32 i = 0; i < codeLen; ++i) {
    opcodeInfos[i].exceptionBlock = endExBlock;
  }
  
  BasicBlock* firstBB = llvmFunction->begin();
  
  if (firstBB->begin() != firstBB->end()) {
    Instruction* firstInstruction = firstBB->begin();

    for (int i = 0; i < maxLocals; i++) {
      intLocals.push_back(new AllocaInst(Type::getInt32Ty(*llvmContext), "", firstInstruction));
      new StoreInst(Constant::getNullValue(Type::getInt32Ty(*llvmContext)), intLocals.back(), false, firstInstruction);
      doubleLocals.push_back(new AllocaInst(Type::getDoubleTy(*llvmContext), "",
                                            firstInstruction));
      new StoreInst(Constant::getNullValue(Type::getDoubleTy(*llvmContext)), doubleLocals.back(), false, firstInstruction);
      longLocals.push_back(new AllocaInst(Type::getInt64Ty(*llvmContext), "", firstInstruction));
      new StoreInst(Constant::getNullValue(Type::getInt64Ty(*llvmContext)), longLocals.back(), false, firstInstruction);
      floatLocals.push_back(new AllocaInst(Type::getFloatTy(*llvmContext), "", firstInstruction));
      new StoreInst(Constant::getNullValue(Type::getFloatTy(*llvmContext)), floatLocals.back(), false, firstInstruction);
      objectLocals.push_back(new AllocaInst(intrinsics->JavaObjectType, "",
                                          firstInstruction));
     
      // The GCStrategy will already initialize the value.
      if (!TheCompiler->useCooperativeGC())
        new StoreInst(Constant::getNullValue(intrinsics->JavaObjectType), objectLocals.back(), false, firstInstruction);
    }
    for (int i = 0; i < maxStack; i++) {
      objectStack.push_back(new AllocaInst(intrinsics->JavaObjectType, "",
                                           firstInstruction));
      addHighLevelType(objectStack.back(), upcalls->OfObject);
      intStack.push_back(new AllocaInst(Type::getInt32Ty(*llvmContext), "", firstInstruction));
      doubleStack.push_back(new AllocaInst(Type::getDoubleTy(*llvmContext), "",
                                           firstInstruction));
      longStack.push_back(new AllocaInst(Type::getInt64Ty(*llvmContext), "", firstInstruction));
      floatStack.push_back(new AllocaInst(Type::getFloatTy(*llvmContext), "", firstInstruction));
    }

  } else {
    for (int i = 0; i < maxLocals; i++) {
      intLocals.push_back(new AllocaInst(Type::getInt32Ty(*llvmContext), "", firstBB));
      new StoreInst(Constant::getNullValue(Type::getInt32Ty(*llvmContext)), intLocals.back(), false, firstBB);
      doubleLocals.push_back(new AllocaInst(Type::getDoubleTy(*llvmContext), "", firstBB));
      new StoreInst(Constant::getNullValue(Type::getDoubleTy(*llvmContext)), doubleLocals.back(), false, firstBB);
      longLocals.push_back(new AllocaInst(Type::getInt64Ty(*llvmContext), "", firstBB));
      new StoreInst(Constant::getNullValue(Type::getInt64Ty(*llvmContext)), longLocals.back(), false, firstBB);
      floatLocals.push_back(new AllocaInst(Type::getFloatTy(*llvmContext), "", firstBB));
      new StoreInst(Constant::getNullValue(Type::getFloatTy(*llvmContext)), floatLocals.back(), false, firstBB);
      objectLocals.push_back(new AllocaInst(intrinsics->JavaObjectType, "",
                                            firstBB));
      // The GCStrategy will already initialize the value.
      if (!TheCompiler->useCooperativeGC())
        new StoreInst(Constant::getNullValue(intrinsics->JavaObjectType), objectLocals.back(), false, firstBB);
    }
    
    for (int i = 0; i < maxStack; i++) {
      objectStack.push_back(new AllocaInst(intrinsics->JavaObjectType, "",
                                           firstBB));
      addHighLevelType(objectStack.back(), upcalls->OfObject);
      intStack.push_back(new AllocaInst(Type::getInt32Ty(*llvmContext), "", firstBB));
      doubleStack.push_back(new AllocaInst(Type::getDoubleTy(*llvmContext), "", firstBB));
      longStack.push_back(new AllocaInst(Type::getInt64Ty(*llvmContext), "", firstBB));
      floatStack.push_back(new AllocaInst(Type::getFloatTy(*llvmContext), "", firstBB));
    }
  }
      
  
  uint32 index = 0;
  uint32 count = 0;
#if defined(ISOLATE_SHARING)
  uint32 max = args.size() - 2;
#else
  uint32 max = args.size();
#endif
  Signdef* sign = compilingMethod->getSignature();
  Typedef* const* arguments = sign->getArgumentsType();
  uint32 type = 0;
  std::vector<Value*>::iterator i = args.begin(); 

  if (isVirtual(compilingMethod->access)) {
    Instruction* V = new StoreInst(*i, objectLocals[0], false, currentBlock);
    addHighLevelType(V, compilingClass);
    ++i;
    ++index;
    ++count;
  }

  
  for (;count < max; ++i, ++index, ++count, ++type) {
    
    const Typedef* cur = arguments[type];
    const Type* curType = (*i)->getType();

    if (curType == Type::getInt64Ty(*llvmContext)){
      new StoreInst(*i, longLocals[index], false, currentBlock);
      ++index;
    } else if (cur->isUnsigned()) {
      new StoreInst(new ZExtInst(*i, Type::getInt32Ty(*llvmContext), "", currentBlock),
                    intLocals[index], false, currentBlock);
    } else if (curType == Type::getInt8Ty(*llvmContext) || curType == Type::getInt16Ty(*llvmContext)) {
      new StoreInst(new SExtInst(*i, Type::getInt32Ty(*llvmContext), "", currentBlock),
                    intLocals[index], false, currentBlock);
    } else if (curType == Type::getInt32Ty(*llvmContext)) {
      new StoreInst(*i, intLocals[index], false, currentBlock);
    } else if (curType == Type::getDoubleTy(*llvmContext)) {
      new StoreInst(*i, doubleLocals[index], false, currentBlock);
      ++index;
    } else if (curType == Type::getFloatTy(*llvmContext)) {
      new StoreInst(*i, floatLocals[index], false, currentBlock);
    } else {
      Instruction* V = new StoreInst(*i, objectLocals[index], false, currentBlock);
      addHighLevelType(V, cur->findAssocClass(compilingClass->classLoader));
    }
  }
  
  readExceptionTable(reader, codeLen);
  
  // Lookup line number table attribute.
  uint16 nba = reader.readU2();
  for (uint16 i = 0; i < nba; ++i) {
    const UTF8* attName = compilingClass->ctpInfo->UTF8At(reader.readU2());
    uint32 attLen = reader.readU4();
    if (attName->equals(Attribut::lineNumberTableAttribut)) {
      uint16 lineLength = reader.readU2();
      for (uint16 i = 0; i < lineLength; ++i) {
        uint16 pc = reader.readU2();
        uint16 ln = reader.readU2();
        opcodeInfos[pc].lineNumber = ln;
      }
    } else {
      reader.seek(attLen, Reader::SeekCur);      
    }
  }
   
  exploreOpcodes(&compilingClass->bytes->elements[start], codeLen);

  if (returnType != Type::getVoidTy(*llvmContext)) {
    endNode = PHINode::Create(returnType, "", endBlock);
  }

  compileOpcodes(&compilingClass->bytes->elements[start], codeLen);
  
  PRINT_DEBUG(JNJVM_COMPILE, 1, COLOR_NORMAL,
              "--> end inline compiling %s.%s\n",
              UTF8Buffer(compilingClass->name).cString(),
              UTF8Buffer(compilingMethod->name).cString());

  curBB = endBlock;


  removeUnusedLocals(intLocals);
  removeUnusedLocals(doubleLocals);
  removeUnusedLocals(floatLocals);
  removeUnusedLocals(longLocals);
  removeUnusedLocals(intStack);
  removeUnusedLocals(doubleStack);
  removeUnusedLocals(floatStack);
  removeUnusedLocals(longStack);
  
  removeUnusedObjects(objectLocals, intrinsics, TheCompiler->useCooperativeGC());
  removeUnusedObjects(objectStack, intrinsics, TheCompiler->useCooperativeGC());


  delete[] opcodeInfos;
  return endNode;
    
}

llvm::Function* JavaJIT::javaCompile() {
  PRINT_DEBUG(JNJVM_COMPILE, 1, COLOR_NORMAL, "compiling %s.%s\n",
              UTF8Buffer(compilingClass->name).cString(),
              UTF8Buffer(compilingMethod->name).cString());

  DbgSubprogram = TheCompiler->GetDbgSubprogram(compilingMethod);

  Attribut* codeAtt = compilingMethod->lookupAttribut(Attribut::codeAttribut);
  
  if (!codeAtt) {
    fprintf(stderr, "I haven't verified your class file and it's malformed:"
                    " no code attribute found for %s.%s!\n",
                    UTF8Buffer(compilingClass->name).cString(),
                    UTF8Buffer(compilingMethod->name).cString());
    abort();
  } 

  Reader reader(codeAtt, &(compilingClass->bytes));
  uint16 maxStack = reader.readU2();
  uint16 maxLocals = reader.readU2();
  uint32 codeLen = reader.readU4();
  uint32 start = reader.cursor;
  
  reader.seek(codeLen, Reader::SeekCur);

  const FunctionType *funcType = llvmFunction->getFunctionType();
  const Type* returnType = funcType->getReturnType();
  
  Function* func = llvmFunction;

  currentBlock = createBasicBlock("start");
  endExceptionBlock = createBasicBlock("endExceptionBlock");
  unifiedUnreachable = createBasicBlock("unifiedUnreachable");

  opcodeInfos = new Opinfo[codeLen];
  memset(opcodeInfos, 0, codeLen * sizeof(Opinfo));
  for (uint32 i = 0; i < codeLen; ++i) {
    opcodeInfos[i].exceptionBlock = endExceptionBlock;
  }
  
#if JNJVM_EXECUTE > 0
    {
    Value* arg = TheCompiler->getMethodInClass(compilingMethod);

    llvm::CallInst::Create(intrinsics->PrintMethodStartFunction, arg, "",
                           currentBlock);
    }
#endif

  

  for (int i = 0; i < maxLocals; i++) {
    intLocals.push_back(new AllocaInst(Type::getInt32Ty(*llvmContext), "", currentBlock));
    new StoreInst(Constant::getNullValue(Type::getInt32Ty(*llvmContext)), intLocals.back(), false, currentBlock);
    doubleLocals.push_back(new AllocaInst(Type::getDoubleTy(*llvmContext), "", currentBlock));
    new StoreInst(Constant::getNullValue(Type::getDoubleTy(*llvmContext)), doubleLocals.back(), false, currentBlock);
    longLocals.push_back(new AllocaInst(Type::getInt64Ty(*llvmContext), "", currentBlock));
    new StoreInst(Constant::getNullValue(Type::getInt64Ty(*llvmContext)), longLocals.back(), false, currentBlock);
    floatLocals.push_back(new AllocaInst(Type::getFloatTy(*llvmContext), "", currentBlock));
    new StoreInst(Constant::getNullValue(Type::getFloatTy(*llvmContext)), floatLocals.back(), false, currentBlock);
    objectLocals.push_back(new AllocaInst(intrinsics->JavaObjectType, "",
                                          currentBlock));
    // The GCStrategy will already initialize the value.
    if (!TheCompiler->useCooperativeGC())
      new StoreInst(Constant::getNullValue(intrinsics->JavaObjectType), objectLocals.back(), false, currentBlock);
  }
  
  for (int i = 0; i < maxStack; i++) {
    objectStack.push_back(new AllocaInst(intrinsics->JavaObjectType, "",
                                         currentBlock));
    addHighLevelType(objectStack.back(), upcalls->OfObject);
    intStack.push_back(new AllocaInst(Type::getInt32Ty(*llvmContext), "", currentBlock));
    doubleStack.push_back(new AllocaInst(Type::getDoubleTy(*llvmContext), "", currentBlock));
    longStack.push_back(new AllocaInst(Type::getInt64Ty(*llvmContext), "", currentBlock));
    floatStack.push_back(new AllocaInst(Type::getFloatTy(*llvmContext), "", currentBlock));
  }
  
  uint32 index = 0;
  uint32 count = 0;
#if defined(ISOLATE_SHARING)
  uint32 max = func->arg_size() - 2;
#else
  uint32 max = func->arg_size();
#endif
  Function::arg_iterator i = func->arg_begin(); 
  Signdef* sign = compilingMethod->getSignature();
  Typedef* const* arguments = sign->getArgumentsType();
  uint32 type = 0;

  if (isVirtual(compilingMethod->access)) {
    Instruction* V = new StoreInst(i, objectLocals[0], false, currentBlock);
    addHighLevelType(V, compilingClass);
    ++i;
    ++index;
    ++count;
  }

  for (;count < max; ++i, ++index, ++count, ++type) {
    
    const Typedef* cur = arguments[type];
    const llvm::Type* curType = i->getType();

    if (curType == Type::getInt64Ty(*llvmContext)){
      new StoreInst(i, longLocals[index], false, currentBlock);
      ++index;
    } else if (cur->isUnsigned()) {
      new StoreInst(new ZExtInst(i, Type::getInt32Ty(*llvmContext), "", currentBlock),
                    intLocals[index], false, currentBlock);
    } else if (curType == Type::getInt8Ty(*llvmContext) || curType == Type::getInt16Ty(*llvmContext)) {
      new StoreInst(new SExtInst(i, Type::getInt32Ty(*llvmContext), "", currentBlock),
                    intLocals[index], false, currentBlock);
    } else if (curType == Type::getInt32Ty(*llvmContext)) {
      new StoreInst(i, intLocals[index], false, currentBlock);
    } else if (curType == Type::getDoubleTy(*llvmContext)) {
      new StoreInst(i, doubleLocals[index], false, currentBlock);
      ++index;
    } else if (curType == Type::getFloatTy(*llvmContext)) {
      new StoreInst(i, floatLocals[index], false, currentBlock);
    } else {
      Instruction* V = new StoreInst(i, objectLocals[index], false, currentBlock);
      addHighLevelType(V, cur->findAssocClass(compilingClass->classLoader));
    }
  }

#if defined(ISOLATE_SHARING)
  ctpCache = i;
  Value* addrCtpCache = new AllocaInst(intrinsics->ConstantPoolType, "",
                                       currentBlock);
  /// make it volatile to be sure it's on the stack
  new StoreInst(ctpCache, addrCtpCache, true, currentBlock);
#endif
 

#if defined(SERVICE)
  JnjvmClassLoader* loader = compilingClass->classLoader;
  Value* Cmp = 0;
  Value* threadId = 0;
  Value* OldIsolateID = 0;
  Value* IsolateIDPtr = 0;
  Value* OldIsolate = 0;
  Value* NewIsolate = 0;
  Value* IsolatePtr = 0;
  if (loader != loader->bootstrapLoader && isPublic(compilingMethod->access)) {
    threadId = getCurrentThread(intrinsics->MutatorThreadType);
     
    IsolateIDPtr = GetElementPtrInst::Create(threadId, intrinsics->constantThree,
                                             "", currentBlock);
    const Type* realType = PointerType::getUnqual(intrinsics->pointerSizeType);
    IsolateIDPtr = new BitCastInst(IsolateIDPtr, realType, "",
                                   currentBlock);
    OldIsolateID = new LoadInst(IsolateIDPtr, "", currentBlock);

    Value* MyID = ConstantInt::get(intrinsics->pointerSizeType,
                                   loader->getIsolate()->IsolateID);
    Cmp = new ICmpInst(*currentBlock, ICmpInst::ICMP_EQ, OldIsolateID, MyID,
                       "");

    BasicBlock* EndBB = createBasicBlock("After service check");
    BasicBlock* ServiceBB = createBasicBlock("Begin service call");

    BranchInst::Create(EndBB, ServiceBB, Cmp, currentBlock);

    currentBlock = ServiceBB;
  
    new StoreInst(MyID, IsolateIDPtr, currentBlock);
    IsolatePtr = GetElementPtrInst::Create(threadId, intrinsics->constantFour, "",
                                           currentBlock);
     
    OldIsolate = new LoadInst(IsolatePtr, "", currentBlock);
    NewIsolate = intrinsics->getIsolate(loader->getIsolate(), currentBlock);
    new StoreInst(NewIsolate, IsolatePtr, currentBlock);

#if DEBUG
    Value* GEP[2] = { OldIsolate, NewIsolate };
    CallInst::Create(intrinsics->ServiceCallStartFunction, GEP, GEP + 2,
                     "", currentBlock);
#endif
    BranchInst::Create(EndBB, currentBlock);
    currentBlock = EndBB;
  }
#endif

  readExceptionTable(reader, codeLen);
  
  // Lookup line number table attribute.
  uint16 nba = reader.readU2();
  for (uint16 i = 0; i < nba; ++i) {
    const UTF8* attName = compilingClass->ctpInfo->UTF8At(reader.readU2());
    uint32 attLen = reader.readU4();
    if (attName->equals(Attribut::lineNumberTableAttribut)) {
      uint16 lineLength = reader.readU2();
      for (uint16 i = 0; i < lineLength; ++i) {
        uint16 pc = reader.readU2();
        uint16 ln = reader.readU2();
        opcodeInfos[pc].lineNumber = ln;
      }
    } else {
      reader.seek(attLen, Reader::SeekCur);      
    }
  }
  
  exploreOpcodes(&compilingClass->bytes->elements[start], codeLen);
 
  endBlock = createBasicBlock("end");

  if (returnType != Type::getVoidTy(*llvmContext)) {
    endNode = llvm::PHINode::Create(returnType, "", endBlock);
  }
  
  if (isSynchro(compilingMethod->access))
    beginSynchronize();
  
  if (TheCompiler->useCooperativeGC()) {
    Value* threadId = getCurrentThread(intrinsics->MutatorThreadType);
    
    Value* GEP[2] = { intrinsics->constantZero, 
                      intrinsics->OffsetDoYieldInThreadConstant };
    
    Value* YieldPtr = GetElementPtrInst::Create(threadId, GEP, GEP + 2, "",
                                                currentBlock);

    Value* Yield = new LoadInst(YieldPtr, "", currentBlock);

    BasicBlock* continueBlock = createBasicBlock("After safe point");
    BasicBlock* yieldBlock = createBasicBlock("In safe point");
    BranchInst::Create(yieldBlock, continueBlock, Yield, currentBlock);

    currentBlock = yieldBlock;
    CallInst::Create(intrinsics->conditionalSafePoint, "", currentBlock);
    BranchInst::Create(continueBlock, currentBlock);

    currentBlock = continueBlock;
  }
  
  if (TheCompiler->hasExceptionsEnabled()) {
    // Variables have been allocated and the lock has been taken. Do the stack
    // check now: if there is an exception, we will go to the lock release code.
    currentExceptionBlock = opcodeInfos[0].exceptionBlock;
    Value* FrameAddr = CallInst::Create(intrinsics->llvm_frameaddress,
                                       	intrinsics->constantZero, "", currentBlock);
    FrameAddr = new PtrToIntInst(FrameAddr, intrinsics->pointerSizeType, "",
                                 currentBlock);
    Value* stackCheck = 
      BinaryOperator::CreateAnd(FrameAddr, intrinsics->constantStackOverflowMask,
                                "", currentBlock);

    stackCheck = new ICmpInst(*currentBlock, ICmpInst::ICMP_EQ, stackCheck,
                              intrinsics->constantPtrZero, "");
    BasicBlock* stackOverflow = createBasicBlock("stack overflow");
    BasicBlock* noStackOverflow = createBasicBlock("no stack overflow");
    BranchInst::Create(stackOverflow, noStackOverflow, stackCheck,
                       currentBlock);
    currentBlock = stackOverflow;
    throwException(intrinsics->StackOverflowErrorFunction, 0, 0);
    currentBlock = noStackOverflow;
  }

  compileOpcodes(&compilingClass->bytes->elements[start], codeLen); 
  
  assert(stack.size() == 0 && "Stack not empty after compiling bytecode");
  // Fix a javac(?) bug where a method only throws an exception and does
  // not return.
  pred_iterator PI = pred_begin(endBlock);
  pred_iterator PE = pred_end(endBlock);
  if (PI == PE && returnType != Type::getVoidTy(*llvmContext)) {
    Instruction* I = currentBlock->getTerminator();
    
    if (isa<UnreachableInst>(I)) {
      I->eraseFromParent();
      BranchInst::Create(endBlock, currentBlock);
      endNode->addIncoming(Constant::getNullValue(returnType),
                           currentBlock);
    } else if (InvokeInst* II = dyn_cast<InvokeInst>(I)) {
      II->setNormalDest(endBlock);
      endNode->addIncoming(Constant::getNullValue(returnType),
                           currentBlock);
    }

  }
  currentBlock = endBlock;

  if (isSynchro(compilingMethod->access))
    endSynchronize();

#if JNJVM_EXECUTE > 0
    {
    Value* arg = TheCompiler->getMethodInClass(compilingMethod); 
    CallInst::Create(intrinsics->PrintMethodEndFunction, arg, "", currentBlock);
    }
#endif
  
#if defined(SERVICE)
  if (Cmp) {
    BasicBlock* EndBB = createBasicBlock("After service check");
    BasicBlock* ServiceBB = createBasicBlock("End Service call");

    BranchInst::Create(EndBB, ServiceBB, Cmp, currentBlock);

    currentBlock = ServiceBB;
  
    new StoreInst(OldIsolateID, IsolateIDPtr, currentBlock);
    new StoreInst(OldIsolate, IsolatePtr, currentBlock);

#if DEBUG
    Value* GEP[2] = { OldIsolate, NewIsolate };
    CallInst::Create(intrinsics->ServiceCallStopFunction, GEP, GEP + 2,
                     "", currentBlock);
#endif
    BranchInst::Create(EndBB, currentBlock);
    currentBlock = EndBB;
  }
#endif

  PI = pred_begin(currentBlock);
  PE = pred_end(currentBlock);
  if (PI == PE) {
    currentBlock->eraseFromParent();
  } else {
    if (returnType != Type::getVoidTy(*llvmContext))
      ReturnInst::Create(*llvmContext, endNode, currentBlock);
    else
      ReturnInst::Create(*llvmContext, currentBlock);
  }

  currentBlock = endExceptionBlock;

  finishExceptions();
   
  removeUnusedLocals(intLocals);
  removeUnusedLocals(doubleLocals);
  removeUnusedLocals(floatLocals);
  removeUnusedLocals(longLocals);
  removeUnusedLocals(intStack);
  removeUnusedLocals(doubleStack);
  removeUnusedLocals(floatStack);
  removeUnusedLocals(longStack);
  
  removeUnusedObjects(objectLocals, intrinsics, TheCompiler->useCooperativeGC());
  removeUnusedObjects(objectStack, intrinsics, TheCompiler->useCooperativeGC());
 
  delete[] opcodeInfos;

  PRINT_DEBUG(JNJVM_COMPILE, 1, COLOR_NORMAL, "--> end compiling %s.%s\n",
              UTF8Buffer(compilingClass->name).cString(),
              UTF8Buffer(compilingMethod->name).cString());
  
#ifndef DWARF_EXCEPTIONS
  if (codeLen < 5 && !callsStackWalker && !TheCompiler->isStaticCompiling())
    compilingMethod->canBeInlined = false;
#endif
  
  Attribut* annotationsAtt =
    compilingMethod->lookupAttribut(Attribut::annotationsAttribut);
  
  if (annotationsAtt) {
    Reader reader(annotationsAtt, &(compilingClass->bytes));
    AnnotationReader AR(reader, compilingClass);
    uint16 numAnnotations = reader.readU2();
    for (uint16 i = 0; i < numAnnotations; ++i) {
      AR.readAnnotation();
      const UTF8* name =
        compilingClass->ctpInfo->UTF8At(AR.AnnotationNameIndex);
      if (name->equals(TheCompiler->InlinePragma)) {
        llvmFunction->addFnAttr(Attribute::AlwaysInline);
      } else if (name->equals(TheCompiler->NoInlinePragma)) {
        llvmFunction->addFnAttr(Attribute::NoInline);
      }
    }
  }
 
  if (codeInfo.size()) { 
    compilingMethod->codeInfo = new CodeLineInfo[codeInfo.size()];
    for (uint32 i = 0; i < codeInfo.size(); i++) {
      compilingMethod->codeInfo[i].lineNumber = codeInfo[i].lineNumber;
      compilingMethod->codeInfo[i].ctpIndex = codeInfo[i].ctpIndex;
      compilingMethod->codeInfo[i].bytecodeIndex = codeInfo[i].bytecodeIndex;
      compilingMethod->codeInfo[i].bytecode = codeInfo[i].bytecode;
    }
  }

  return llvmFunction;
}

void JavaJIT::compareFP(Value* val1, Value* val2, const Type* ty, bool l) {
  Value* one = intrinsics->constantOne;
  Value* zero = intrinsics->constantZero;
  Value* minus = intrinsics->constantMinusOne;

  Value* c = new FCmpInst(*currentBlock, FCmpInst::FCMP_UGT, val1, val2, "");
  Value* r = llvm::SelectInst::Create(c, one, zero, "", currentBlock);
  c = new FCmpInst(*currentBlock, FCmpInst::FCMP_ULT, val1, val2, "");
  r = llvm::SelectInst::Create(c, minus, r, "", currentBlock);
  c = new FCmpInst(*currentBlock, FCmpInst::FCMP_UNO, val1, val2, "");
  r = llvm::SelectInst::Create(c, l ? one : minus, r, "", currentBlock);

  push(r, false);

}

void JavaJIT::loadConstant(uint16 index) {
  JavaConstantPool* ctpInfo = compilingClass->ctpInfo;
  uint8 type = ctpInfo->typeAt(index);
  
  if (type == JavaConstantPool::ConstantString) {
#if defined(ISOLATE)
    abort();
#else
    
    if (TheCompiler->isStaticCompiling()) {
      const UTF8* utf8 = ctpInfo->UTF8At(ctpInfo->ctpDef[index]);
      JavaString* str = *(compilingClass->classLoader->UTF8ToStr(utf8));
      Value* val = TheCompiler->getString(str);
      push(val, false, upcalls->newString);
    } else {
      JavaString** str = (JavaString**)ctpInfo->ctpRes[index];
      if (str) {
        Value* val = TheCompiler->getStringPtr(str);
        val = new LoadInst(val, "", currentBlock);
        push(val, false, upcalls->newString);
      } else {
        // Lookup the constant pool cache
        const llvm::Type* Ty = PointerType::getUnqual(intrinsics->JavaObjectType);
        Value* val = getConstantPoolAt(index, intrinsics->StringLookupFunction,
                                       Ty, 0, false);
        val = new LoadInst(val, "", currentBlock);
        push(val, false, upcalls->newString);
      }
    }
#endif   
  } else if (type == JavaConstantPool::ConstantLong) {
    push(ConstantInt::get(Type::getInt64Ty(*llvmContext), ctpInfo->LongAt(index)),
         false);
  } else if (type == JavaConstantPool::ConstantDouble) {
    push(ConstantFP::get(Type::getDoubleTy(*llvmContext), ctpInfo->DoubleAt(index)),
         false);
  } else if (type == JavaConstantPool::ConstantInteger) {
    push(ConstantInt::get(Type::getInt32Ty(*llvmContext), ctpInfo->IntegerAt(index)),
         false);
  } else if (type == JavaConstantPool::ConstantFloat) {
    push(ConstantFP::get(Type::getFloatTy(*llvmContext), ctpInfo->FloatAt(index)),
         false);
  } else if (type == JavaConstantPool::ConstantClass) {
    UserCommonClass* cl = 0;
    Value* res = getResolvedCommonClass(index, false, &cl);

    res = CallInst::Create(intrinsics->GetClassDelegateeFunction, res, "",
                           currentBlock);
    push(res, false, upcalls->newClass);
  } else {
    fprintf(stderr, "I haven't verified your class file and it's malformed:"
                    " unknown ldc %d in %s.%s!\n", type,
                    UTF8Buffer(compilingClass->name).cString(),
                    UTF8Buffer(compilingMethod->name).cString());
    abort();
  }
}

void JavaJIT::JITVerifyNull(Value* obj) {

  if (TheCompiler->hasExceptionsEnabled()) {
    Constant* zero = intrinsics->JavaObjectNullConstant;
    Value* test = new ICmpInst(*currentBlock, ICmpInst::ICMP_EQ, obj, zero, "");

    BasicBlock* exit = createBasicBlock("verifyNullExit");
    BasicBlock* cont = createBasicBlock("verifyNullCont");

    BranchInst::Create(exit, cont, test, currentBlock);
    currentBlock = exit;
    throwException(intrinsics->NullPointerExceptionFunction, 0, 0);
    currentBlock = cont;
  }
 
}

Value* JavaJIT::verifyAndComputePtr(Value* obj, Value* index,
                                    const Type* arrayType, bool verif) {
  JITVerifyNull(obj);
  
  if (index->getType() != Type::getInt32Ty(*llvmContext)) {
    index = new SExtInst(index, Type::getInt32Ty(*llvmContext), "", currentBlock);
  }
  
  if (TheCompiler->hasExceptionsEnabled()) {
    Value* size = arraySize(obj);
    
    Value* cmp = new ICmpInst(*currentBlock, ICmpInst::ICMP_ULT, index, size,
                              "");

    BasicBlock* ifTrue =  createBasicBlock("true verifyAndComputePtr");
    BasicBlock* ifFalse = createBasicBlock("false verifyAndComputePtr");

    BranchInst::Create(ifTrue, ifFalse, cmp, currentBlock);
    
    currentBlock = ifFalse;
    Value* args[2] = { obj, index };
    throwException(intrinsics->IndexOutOfBoundsExceptionFunction, args, 2);
    currentBlock = ifTrue;
  }
  
  Constant* zero = intrinsics->constantZero;
  Value* val = new BitCastInst(obj, arrayType, "", currentBlock);
  
  Value* indexes[3] = { zero, intrinsics->JavaArrayElementsOffsetConstant, index };
  Value* ptr = GetElementPtrInst::Create(val, indexes, indexes + 3, "",
                                         currentBlock);

  return ptr;

}

void JavaJIT::makeArgs(FunctionType::param_iterator it,
                       uint32 index, std::vector<Value*>& Args, uint32 nb) {
#if defined(ISOLATE_SHARING)
  nb += 1;
#endif
  Args.reserve(nb + 2);
  Value** args = (Value**)alloca(nb*sizeof(Value*));
#if defined(ISOLATE_SHARING)
  args[nb - 1] = isolateLocal;
  sint32 start = nb - 2;
  it--;
  it--;
#else
  sint32 start = nb - 1;
#endif
  for (sint32 i = start; i >= 0; --i) {
    it--;
    if (it->get() == Type::getInt64Ty(*llvmContext) || it->get() == Type::getDoubleTy(*llvmContext)) {
      pop();
    }
    Value* tmp = pop();
    
    const Type* type = it->get();
    if (tmp->getType() != type) { // int8 or int16
      convertValue(tmp, type, currentBlock, false);
    }
    args[i] = tmp;

  }

  for (uint32 i = 0; i < nb; ++i) {
    Args.push_back(args[i]);
  }
  
}

Instruction* JavaJIT::lowerMathOps(const UTF8* name, 
                                   std::vector<Value*>& args) {
  JnjvmBootstrapLoader* loader = compilingClass->classLoader->bootstrapLoader;
  if (name->equals(loader->abs)) {
    const Type* Ty = args[0]->getType();
    if (Ty == Type::getInt32Ty(*llvmContext)) {
      Constant* const_int32_9 = intrinsics->constantZero;
      Constant* const_int32_10 = intrinsics->constantMinusOne;
      BinaryOperator* int32_tmpneg = 
        BinaryOperator::Create(Instruction::Sub, const_int32_9, args[0],
                               "tmpneg", currentBlock);
      ICmpInst* int1_abscond = 
        new ICmpInst(*currentBlock, ICmpInst::ICMP_SGT, args[0], const_int32_10,
                     "abscond");
      return llvm::SelectInst::Create(int1_abscond, args[0], int32_tmpneg,
                                      "abs", currentBlock);
    } else if (Ty == Type::getInt64Ty(*llvmContext)) {
      Constant* const_int64_9 = intrinsics->constantLongZero;
      Constant* const_int64_10 = intrinsics->constantLongMinusOne;
      
      BinaryOperator* int64_tmpneg = 
        BinaryOperator::Create(Instruction::Sub, const_int64_9, args[0],
                               "tmpneg", currentBlock);

      ICmpInst* int1_abscond = new ICmpInst(*currentBlock, ICmpInst::ICMP_SGT,
                                            args[0], const_int64_10, "abscond");
      
      return llvm::SelectInst::Create(int1_abscond, args[0], int64_tmpneg,
                                      "abs", currentBlock);
    } else if (Ty == Type::getFloatTy(*llvmContext)) {
      return llvm::CallInst::Create(intrinsics->func_llvm_fabs_f32, args[0],
                                    "tmp1", currentBlock);
    } else if (Ty == Type::getDoubleTy(*llvmContext)) {
      return llvm::CallInst::Create(intrinsics->func_llvm_fabs_f64, args[0],
                                    "tmp1", currentBlock);
    }
  } else if (name->equals(loader->sqrt)) {
    return llvm::CallInst::Create(intrinsics->func_llvm_sqrt_f64, args[0],
                                  "tmp1", currentBlock);
  } else if (name->equals(loader->sin)) {
    return llvm::CallInst::Create(intrinsics->func_llvm_sin_f64, args[0], 
                                  "tmp1", currentBlock);
  } else if (name->equals(loader->cos)) {
    return llvm::CallInst::Create(intrinsics->func_llvm_cos_f64, args[0], 
                                  "tmp1", currentBlock);
  } else if (name->equals(loader->tan)) {
    return llvm::CallInst::Create(intrinsics->func_llvm_tan_f64, args[0], 
                                  "tmp1", currentBlock);
  } else if (name->equals(loader->asin)) {
    return llvm::CallInst::Create(intrinsics->func_llvm_asin_f64, args[0], 
                                  "tmp1", currentBlock);
  } else if (name->equals(loader->acos)) {
    return llvm::CallInst::Create(intrinsics->func_llvm_acos_f64, args[0], 
                                  "tmp1", currentBlock);
  } else if (name->equals(loader->atan)) {
    return llvm::CallInst::Create(intrinsics->func_llvm_atan_f64, args[0],
                                  "tmp1", currentBlock);
  } else if (name->equals(loader->atan2)) {
    return llvm::CallInst::Create(intrinsics->func_llvm_atan2_f64, 
                                  args.begin(), args.end(), "tmp1",
                                  currentBlock);
  } else if (name->equals(loader->exp)) {
    return llvm::CallInst::Create(intrinsics->func_llvm_exp_f64, args[0],
                                  "tmp1", currentBlock);
  } else if (name->equals(loader->log)) {
    return llvm::CallInst::Create(intrinsics->func_llvm_log_f64, args[0],
                                  "tmp1", currentBlock);
  } else if (name->equals(loader->pow)) {
    return llvm::CallInst::Create(intrinsics->func_llvm_pow_f64, args.begin(),
                                  args.end(), "tmp1", currentBlock);
  } else if (name->equals(loader->ceil)) {
    return llvm::CallInst::Create(intrinsics->func_llvm_ceil_f64, args[0], "tmp1",
                                  currentBlock);
  } else if (name->equals(loader->floor)) {
    return llvm::CallInst::Create(intrinsics->func_llvm_floor_f64, args[0],
                                  "tmp1", currentBlock);
  } else if (name->equals(loader->rint)) {
    return llvm::CallInst::Create(intrinsics->func_llvm_rint_f64, args[0],
                                  "tmp1", currentBlock);
  } else if (name->equals(loader->cbrt)) {
    return llvm::CallInst::Create(intrinsics->func_llvm_cbrt_f64, args[0], "tmp1",
                                  currentBlock);
  } else if (name->equals(loader->cosh)) {
    return llvm::CallInst::Create(intrinsics->func_llvm_cosh_f64, args[0], "tmp1",
                                  currentBlock);
  } else if (name->equals(loader->expm1)) {
    return llvm::CallInst::Create(intrinsics->func_llvm_expm1_f64, args[0],
                                  "tmp1", currentBlock);
  } else if (name->equals(loader->hypot)) {
    return llvm::CallInst::Create(intrinsics->func_llvm_hypot_f64, args[0],
                                  "tmp1", currentBlock);
  } else if (name->equals(loader->log10)) {
    return llvm::CallInst::Create(intrinsics->func_llvm_log10_f64, args[0],
                                  "tmp1", currentBlock);
  } else if (name->equals(loader->log1p)) {
    return llvm::CallInst::Create(intrinsics->func_llvm_log1p_f64, args[0],
                                  "tmp1", currentBlock);
  } else if (name->equals(loader->sinh)) {
    return llvm::CallInst::Create(intrinsics->func_llvm_sinh_f64, args[0],
                                  "tmp1", currentBlock);
  } else if (name->equals(loader->tanh)) {
    return llvm::CallInst::Create(intrinsics->func_llvm_tanh_f64, args[0],
                                  "tmp1", currentBlock);
  }
  
  return 0;

}


Instruction* JavaJIT::invokeInline(JavaMethod* meth, 
                                   std::vector<Value*>& args) {
  JavaJIT jit(TheCompiler, meth, llvmFunction);
  jit.unifiedUnreachable = unifiedUnreachable;
  jit.inlineMethods = inlineMethods;
  jit.inlineMethods[meth] = true;
  jit.inlining = true;
  Instruction* ret = jit.inlineCompile(currentBlock, 
                                       currentExceptionBlock, args);
  inlineMethods[meth] = false;
  return ret;
}

void JavaJIT::invokeSpecial(uint16 index) {
  JavaConstantPool* ctpInfo = compilingClass->ctpInfo;
  JavaMethod* meth = 0;
  Signdef* signature = 0;
  const UTF8* name = 0;
  const UTF8* cl = 0;

  ctpInfo->nameOfStaticOrSpecialMethod(index, cl, name, signature);
  LLVMSignatureInfo* LSI = TheCompiler->getSignatureInfo(signature);
  const llvm::FunctionType* virtualType = LSI->getVirtualType();
  llvm::Instruction* val = 0;
  
  std::vector<Value*> args;
  FunctionType::param_iterator it  = virtualType->param_end();
  makeArgs(it, index, args, signature->nbArguments + 1);

  if (!meth) {
    meth = ctpInfo->infoOfStaticOrSpecialMethod(index, ACC_VIRTUAL, signature);
  }
  
  if (meth == compilingClass->classLoader->bootstrapLoader->upcalls->InitObject)
    return;
  
  JITVerifyNull(args[0]); 

#if defined(ISOLATE_SHARING)
  const Type* Ty = intrinsics->ConstantPoolType;
  Constant* Nil = Constant::getNullValue(Ty);
  GlobalVariable* GV = new GlobalVariable(*llvmFunction->getParent(),Ty, false,
                                          GlobalValue::ExternalLinkage, Nil,
                                          "");
  Value* res = new LoadInst(GV, "", false, currentBlock);
  Value* test = new ICmpInst(*currentBlock, ICmpInst::ICMP_EQ, res, Nil, "");
 
  BasicBlock* trueCl = createBasicBlock("UserCtp OK");
  BasicBlock* falseCl = createBasicBlock("UserCtp Not OK");
  PHINode* node = llvm::PHINode::Create(Ty, "", trueCl);
  node->addIncoming(res, currentBlock);
  BranchInst::Create(falseCl, trueCl, test, currentBlock);
  std::vector<Value*> Args;
  Args.push_back(ctpCache);
  Args.push_back(ConstantInt::get(Type::getInt32Ty(*llvmContext), index));
  Args.push_back(GV);
  res = CallInst::Create(intrinsics->SpecialCtpLookupFunction, Args.begin(),
                         Args.end(), "", falseCl);
  node->addIncoming(res, falseCl);
  BranchInst::Create(trueCl, falseCl);
  currentBlock = trueCl;
  args.push_back(node);
#endif

  if (meth && canBeInlined(meth)) {
    val = invokeInline(meth, args);
  } else {
    Value* func = 0;
    bool needsInit = false;
    if (TheCompiler->needsCallback(meth, &needsInit)) {
      if (needsInit) {
        // Make sure the class is loaded before materializing the method.
        uint32 clIndex = ctpInfo->getClassIndexFromMethod(index);
        UserCommonClass* cl = 0;
        Value* Cl = getResolvedCommonClass(clIndex, false, &cl);
        if (!cl) {
          CallInst::Create(intrinsics->ForceLoadedCheckFunction, Cl, "",
                           currentBlock);
        }
      }
      func = TheCompiler->addCallback(compilingClass, index, signature, false,
                                      currentBlock);
    } else {
      func = TheCompiler->getMethod(meth);
    }
    val = invoke(func, args, "", currentBlock);
  }
  
  const llvm::Type* retType = virtualType->getReturnType();
  if (retType != Type::getVoidTy(*llvmContext)) {
    if (retType == intrinsics->JavaObjectType) {
      JnjvmClassLoader* JCL = compilingClass->classLoader;
      push(val, false, signature->getReturnType()->findAssocClass(JCL));
    } else {
      push(val, signature->getReturnType()->isUnsigned());
      if (retType == Type::getDoubleTy(*llvmContext) ||
          retType == Type::getInt64Ty(*llvmContext)) {
        push(intrinsics->constantZero, false);
      }
    }
  }

}

void JavaJIT::invokeStatic(uint16 index) {
  JavaConstantPool* ctpInfo = compilingClass->ctpInfo;
  Signdef* signature = 0;
  const UTF8* name = 0;
  const UTF8* cl = 0;
  ctpInfo->nameOfStaticOrSpecialMethod(index, cl, name, signature);
  LLVMSignatureInfo* LSI = TheCompiler->getSignatureInfo(signature);
  const llvm::FunctionType* staticType = LSI->getStaticType();
  llvm::Instruction* val = 0;
  
  std::vector<Value*> args; // size = [signature->nbIn + 2]; 
  FunctionType::param_iterator it  = staticType->param_end();
  makeArgs(it, index, args, signature->nbArguments);
  ctpInfo->markAsStaticCall(index);

  JnjvmBootstrapLoader* loader = compilingClass->classLoader->bootstrapLoader;
  if (cl->equals(loader->mathName)) {
    val = lowerMathOps(name, args);
  }

  else if (cl->equals(loader->stackWalkerName)) {
    callsStackWalker = true;
  }

  if (!val) {
    JavaMethod* meth = ctpInfo->infoOfStaticOrSpecialMethod(index, ACC_STATIC,
                                                            signature);
    

#if defined(ISOLATE_SHARING)
    Value* newCtpCache = getConstantPoolAt(index,
                                           intrinsics->StaticCtpLookupFunction,
                                           intrinsics->ConstantPoolType, 0,
                                           false);
    args.push_back(newCtpCache);
#endif
    
    uint32 clIndex = ctpInfo->getClassIndexFromMethod(index);
    UserClass* cl = 0;
    Value* Cl = getResolvedClass(clIndex, true, true, &cl);
    if (!meth || (cl && needsInitialisationCheck(cl, compilingClass))) {
      CallInst::Create(intrinsics->ForceInitialisationCheckFunction, Cl, "",
                       currentBlock);
    }
    
    if (meth && canBeInlined(meth)) {
      val = invokeInline(meth, args);
    } else {
      Value* func = 0;
      bool needsInit = false;
      if (TheCompiler->needsCallback(meth, &needsInit)) {
        func = TheCompiler->addCallback(compilingClass, index, signature,
                                        true, currentBlock);
      } else {
        /*if (meth == upcalls->SystemArraycopy ||
            meth == upcalls->VMSystemArraycopy) {
          lowerArraycopy(args);
          return;
        }*/
        func = TheCompiler->getMethod(meth);
      }
      val = invoke(func, args, "", currentBlock);
    }
  }

  const llvm::Type* retType = staticType->getReturnType();
  if (retType != Type::getVoidTy(*llvmContext)) {
    if (retType == intrinsics->JavaObjectType) {
      JnjvmClassLoader* JCL = compilingClass->classLoader;
      push(val, false, signature->getReturnType()->findAssocClass(JCL));
    } else {
      push(val, signature->getReturnType()->isUnsigned());
      if (retType == Type::getDoubleTy(*llvmContext) ||
          retType == Type::getInt64Ty(*llvmContext)) {
        push(intrinsics->constantZero, false);
      }
    }
  }
}

Value* JavaJIT::getConstantPoolAt(uint32 index, Function* resolver,
                                  const Type* returnType,
                                  Value* additionalArg, bool doThrow) {

// This makes unswitch loop very unhappy time-wise, but makes GVN happy
// number-wise. IMO, it's better to have this than Unswitch.
#ifdef ISOLATE_SHARING
  Value* CTP = ctpCache;
  Value* Cl = GetElementPtrInst::Create(CTP, intrinsics->ConstantOne, "",
                                        currentBlock);
  Cl = new LoadInst(Cl, "", currentBlock);
#else
  JavaConstantPool* ctp = compilingClass->ctpInfo;
  Value* CTP = TheCompiler->getConstantPool(ctp);
  Value* Cl = TheCompiler->getNativeClass(compilingClass);
#endif

  std::vector<Value*> Args;
  Args.push_back(resolver);
  Args.push_back(CTP);
  Args.push_back(Cl);
  Args.push_back(ConstantInt::get(Type::getInt32Ty(*llvmContext), index));
  if (additionalArg) Args.push_back(additionalArg);

  Value* res = 0;
  if (doThrow) {
    res = invoke(intrinsics->GetConstantPoolAtFunction, Args, "",
                 currentBlock);
  } else {
    res = CallInst::Create(intrinsics->GetConstantPoolAtFunction, Args.begin(),
                           Args.end(), "", currentBlock);
  }
  
  const Type* realType = 
    intrinsics->GetConstantPoolAtFunction->getReturnType();
  if (returnType == Type::getInt32Ty(*llvmContext)) {
    return new PtrToIntInst(res, Type::getInt32Ty(*llvmContext), "", currentBlock);
  } else if (returnType != realType) {
    return new BitCastInst(res, returnType, "", currentBlock);
  } 
  
  return res;
}

Value* JavaJIT::getResolvedCommonClass(uint16 index, bool doThrow,
                                       UserCommonClass** alreadyResolved) {
    
  JavaConstantPool* ctpInfo = compilingClass->ctpInfo;
  CommonClass* cl = ctpInfo->getMethodClassIfLoaded(index);
  Value* node = 0;
  if (cl && (!cl->isClass() || cl->asClass()->isResolved())) {
    if (alreadyResolved) *alreadyResolved = cl;
    node = TheCompiler->getNativeClass(cl);
    // Since we only allocate for array classes that we own and
    // ony primitive arrays are already allocated, verify that the class
    // array is not external.
    if (TheCompiler->isStaticCompiling() && cl->isArray() && 
        node->getType() != intrinsics->JavaClassArrayType) {
      node = new LoadInst(node, "", currentBlock);
    }
    if (node->getType() != intrinsics->JavaCommonClassType) {
      node = new BitCastInst(node, intrinsics->JavaCommonClassType, "",
                             currentBlock);
    }
  } else {
    node = getConstantPoolAt(index, intrinsics->ClassLookupFunction,
                             intrinsics->JavaCommonClassType, 0, doThrow);
  }
  
  return node;
}

Value* JavaJIT::getResolvedClass(uint16 index, bool clinit, bool doThrow,
                                 Class** alreadyResolved) {
    
  JavaConstantPool* ctpInfo = compilingClass->ctpInfo;
  Class* cl = (Class*)(ctpInfo->getMethodClassIfLoaded(index));
  Value* node = 0;
  bool needsInit = true;
  if (cl && cl->isResolved()) {
    if (alreadyResolved) (*alreadyResolved) = cl;
    node = TheCompiler->getNativeClass(cl);
    needsInit = needsInitialisationCheck(cl, compilingClass);
  } else {
    node = getConstantPoolAt(index, intrinsics->ClassLookupFunction,
                             intrinsics->JavaClassType, 0, doThrow);
  }
 

  if (clinit && needsInit) {
    if (node->getType() != intrinsics->JavaClassType) {
      node = new BitCastInst(node, intrinsics->JavaClassType, "", currentBlock);
    }
    return invoke(intrinsics->InitialisationCheckFunction, node, "",
                  currentBlock);
  } else {
    return node;
  }
}

void JavaJIT::invokeNew(uint16 index) {
  
  Class* cl = 0;
  Value* Cl = getResolvedClass(index, true, true, &cl);
          
  Value* VT = 0;
  Value* Size = 0;
  
  if (cl) {
    VT = TheCompiler->getVirtualTable(cl->virtualVT);
    LLVMClassInfo* LCI = TheCompiler->getClassInfo(cl);
    Size = LCI->getVirtualSize();
    
    bool needsCheck = needsInitialisationCheck(cl, compilingClass);
    if (needsCheck) {
      Cl = invoke(intrinsics->ForceInitialisationCheckFunction, Cl, "",
                  currentBlock);
    }

  } else {
    VT = CallInst::Create(intrinsics->GetVTFromClassFunction, Cl, "",
                          currentBlock);
    Size = CallInst::Create(intrinsics->GetObjectSizeFromClassFunction, Cl,
                            "", currentBlock);
  }
 
  VT = new BitCastInst(VT, intrinsics->ptrType, "", currentBlock);
  Instruction* val = invoke(cl ? intrinsics->AllocateFunction :
                           intrinsics->AllocateUnresolvedFunction,
                           Size, VT, "", currentBlock);

  if (cl && cl->virtualVT->destructor) {
    CallInst::Create(intrinsics->AddFinalizationCandidate, val, "", currentBlock);
  }


  addHighLevelType(val, cl ? cl : upcalls->OfObject);
  val = new BitCastInst(val, intrinsics->JavaObjectType, "", currentBlock);
  push(val, false, cl ? cl : upcalls->OfObject);
}

Value* JavaJIT::ldResolved(uint16 index, bool stat, Value* object, 
                           const Type* fieldType, const Type* fieldTypePtr) {
  JavaConstantPool* info = compilingClass->ctpInfo;
  
  JavaField* field = info->lookupField(index, stat);
  if (field && field->classDef->isResolved()) {
    LLVMClassInfo* LCI = TheCompiler->getClassInfo(field->classDef);
    LLVMFieldInfo* LFI = TheCompiler->getFieldInfo(field);
    const Type* type = 0;
    if (stat) {
      type = LCI->getStaticType();
      Value* Cl = TheCompiler->getNativeClass(field->classDef);
      bool needsCheck = needsInitialisationCheck(field->classDef,
                                                 compilingClass);
      if (needsCheck) {
        Cl = invoke(intrinsics->InitialisationCheckFunction, Cl, "",
                    currentBlock);
      }
#if !defined(ISOLATE) && !defined(ISOLATE_SHARING)
      if (needsCheck) {
        CallInst::Create(intrinsics->ForceInitialisationCheckFunction, Cl, "",
                         currentBlock);
      }

      object = TheCompiler->getStaticInstance(field->classDef);
#else
      object = CallInst::Create(intrinsics->GetStaticInstanceFunction, Cl, "",
                                currentBlock); 
#endif
    } else {
      type = LCI->getVirtualType();
    }
    
    Value* objectConvert = new BitCastInst(object, type, "", currentBlock);

    Value* args[2] = { intrinsics->constantZero, LFI->getOffset() };
    Value* ptr = llvm::GetElementPtrInst::Create(objectConvert,
                                                 args, args + 2, "",
                                                 currentBlock);
    return ptr;
  }

  const Type* Pty = intrinsics->arrayPtrType;
  Constant* zero = intrinsics->constantZero;
    
  Function* func = stat ? intrinsics->StaticFieldLookupFunction :
                          intrinsics->VirtualFieldLookupFunction;
    
  const Type* returnType = 0;
  if (stat)
    returnType = intrinsics->ptrType;
  else
    returnType = Type::getInt32Ty(*llvmContext);

  Value* ptr = getConstantPoolAt(index, func, returnType, 0, true);
  if (!stat) {
    Value* tmp = new BitCastInst(object, Pty, "", currentBlock);
    Value* args[2] = { zero, ptr };
    ptr = GetElementPtrInst::Create(tmp, args, args + 2, "", currentBlock);
  }
    
  return new BitCastInst(ptr, fieldTypePtr, "", currentBlock);
}

void JavaJIT::convertValue(Value*& val, const Type* t1, BasicBlock* currentBlock,
                           bool usign) {
  const Type* t2 = val->getType();
  if (t1 != t2) {
    if (t1->isIntegerTy() && t2->isIntegerTy()) {
      if (t2->getPrimitiveSizeInBits() < t1->getPrimitiveSizeInBits()) {
        if (usign) {
          val = new ZExtInst(val, t1, "", currentBlock);
        } else {
          val = new SExtInst(val, t1, "", currentBlock);
        }
      } else {
        val = new TruncInst(val, t1, "", currentBlock);
      }    
    } else if (t1->isFloatTy() && t2->isFloatTy()) {
      if (t2->getPrimitiveSizeInBits() < t1->getPrimitiveSizeInBits()) {
        val = new FPExtInst(val, t1, "", currentBlock);
      } else {
        val = new FPTruncInst(val, t1, "", currentBlock);
      }    
    } else if (isa<PointerType>(t1) && isa<PointerType>(t2)) {
      val = new BitCastInst(val, t1, "", currentBlock);
    }    
  }
}
 

void JavaJIT::setStaticField(uint16 index) {
  Value* val = pop(); 
  
  Typedef* sign = compilingClass->ctpInfo->infoOfField(index);
  LLVMAssessorInfo& LAI = TheCompiler->getTypedefInfo(sign);
  const Type* type = LAI.llvmType;
  
  if (type == Type::getInt64Ty(*llvmContext) || type == Type::getDoubleTy(*llvmContext)) {
    val = pop();
  }
  
  Value* ptr = ldResolved(index, true, 0, type, LAI.llvmTypePtr);
  
  if (type != val->getType()) { // int1, int8, int16
    convertValue(val, type, currentBlock, false);
  }
  
  new StoreInst(val, ptr, false, currentBlock);
}

void JavaJIT::getStaticField(uint16 index) {
  Typedef* sign = compilingClass->ctpInfo->infoOfField(index);
  LLVMAssessorInfo& LAI = TheCompiler->getTypedefInfo(sign);
  const Type* type = LAI.llvmType;
  
  Value* ptr = ldResolved(index, true, 0, type, LAI.llvmTypePtr);
  
  bool final = false;
#if !defined(ISOLATE) && !defined(ISOLATE_SHARING)
  JnjvmBootstrapLoader* JBL = compilingClass->classLoader->bootstrapLoader;
  if (!compilingMethod->name->equals(JBL->clinitName)) {
    JavaField* field = compilingClass->ctpInfo->lookupField(index, true);
    if (field && field->classDef->isReady()) final = isFinal(field->access);
    if (final) {
      void* Obj = field->classDef->getStaticInstance();
      if (sign->isPrimitive()) {
        const PrimitiveTypedef* prim = (PrimitiveTypedef*)sign;
        if (prim->isInt()) {
          sint32 val = field->getInt32Field(Obj);
          push(ConstantInt::get(Type::getInt32Ty(*llvmContext), val), false);
        } else if (prim->isByte()) {
          sint8 val = (sint8)field->getInt8Field(Obj);
          push(ConstantInt::get(Type::getInt8Ty(*llvmContext), val), false);
        } else if (prim->isBool()) {
          uint8 val = (uint8)field->getInt8Field(Obj);
          push(ConstantInt::get(Type::getInt8Ty(*llvmContext), val), true);
        } else if (prim->isShort()) {
          sint16 val = (sint16)field->getInt16Field(Obj);
          push(ConstantInt::get(Type::getInt16Ty(*llvmContext), val), false);
        } else if (prim->isChar()) {
          uint16 val = (uint16)field->getInt16Field(Obj);
          push(ConstantInt::get(Type::getInt16Ty(*llvmContext), val), true);
        } else if (prim->isLong()) {
          sint64 val = (sint64)field->getLongField(Obj);
          push(ConstantInt::get(Type::getInt64Ty(*llvmContext), val), false);
        } else if (prim->isFloat()) {
          float val = (float)field->getFloatField(Obj);
          push(ConstantFP::get(Type::getFloatTy(*llvmContext), val), false);
        } else if (prim->isDouble()) {
          double val = (double)field->getDoubleField(Obj);
          push(ConstantFP::get(Type::getDoubleTy(*llvmContext), val), false);
        } else {
          abort();
        }
      } else {
        if (TheCompiler->isStaticCompiling()) {
          JavaObject* val = field->getObjectField(Obj);
          JnjvmClassLoader* JCL = field->classDef->classLoader;
          Value* V = TheCompiler->getFinalObject(val, sign->assocClass(JCL));
          CommonClass* cl = mvm::Collector::begOf(val) ? val->getClass() : NULL;
          push(V, false, cl);
        } else {
          Value* V = CallInst::Create(intrinsics->GetFinalObjectFieldFunction, ptr,
                                      "", currentBlock);

          JnjvmClassLoader* JCL = compilingClass->classLoader;
          push(V, false, sign->findAssocClass(JCL));
        } 
      }
    }
  }
#endif

  if (!final) {
    JnjvmClassLoader* JCL = compilingClass->classLoader;
    CommonClass* cl = sign->findAssocClass(JCL);
    push(new LoadInst(ptr, "", currentBlock), sign->isUnsigned(), cl);
  }
  if (type == Type::getInt64Ty(*llvmContext) ||
      type == Type::getDoubleTy(*llvmContext)) {
    push(intrinsics->constantZero, false);
  }
}

void JavaJIT::setVirtualField(uint16 index) {
  Value* val = pop();
  Typedef* sign = compilingClass->ctpInfo->infoOfField(index);
  LLVMAssessorInfo& LAI = TheCompiler->getTypedefInfo(sign);
  const Type* type = LAI.llvmType;
  
  if (type == Type::getInt64Ty(*llvmContext) ||
      type == Type::getDoubleTy(*llvmContext)) {
    val = pop();
  }
  
  Value* object = pop();
  JITVerifyNull(object);
  Value* ptr = ldResolved(index, false, object, type, LAI.llvmTypePtr);

  if (type != val->getType()) { // int1, int8, int16
    convertValue(val, type, currentBlock, false);
  }

  new StoreInst(val, ptr, false, currentBlock);
}

void JavaJIT::getVirtualField(uint16 index) {
  Typedef* sign = compilingClass->ctpInfo->infoOfField(index);
  JnjvmClassLoader* JCL = compilingClass->classLoader;
  CommonClass* cl = sign->findAssocClass(JCL);
  
  LLVMAssessorInfo& LAI = TheCompiler->getTypedefInfo(sign);
  const Type* type = LAI.llvmType;
  Value* obj = pop();
  JITVerifyNull(obj);
  
  Value* ptr = ldResolved(index, false, obj, type, LAI.llvmTypePtr);
  
  JnjvmBootstrapLoader* JBL = compilingClass->classLoader->bootstrapLoader;
  bool final = false;
  
  // In init methods, the fields have not been set yet.
  if (!compilingMethod->name->equals(JBL->initName)) {
    JavaField* field = compilingClass->ctpInfo->lookupField(index, false);
    if (field) final = isFinal(field->access);
    if (final) {
      Function* F = 0;
      if (sign->isPrimitive()) {
        const PrimitiveTypedef* prim = (PrimitiveTypedef*)sign;
        if (prim->isInt()) {
          F = intrinsics->GetFinalInt32FieldFunction;
        } else if (prim->isByte()) {
          F = intrinsics->GetFinalInt8FieldFunction;
        } else if (prim->isBool()) {
          F = intrinsics->GetFinalInt8FieldFunction;
        } else if (prim->isShort()) {
          F = intrinsics->GetFinalInt16FieldFunction;
        } else if (prim->isChar()) {
          F = intrinsics->GetFinalInt16FieldFunction;
        } else if (prim->isLong()) {
          F = intrinsics->GetFinalLongFieldFunction;
        } else if (prim->isFloat()) {
          F = intrinsics->GetFinalFloatFieldFunction;
        } else if (prim->isDouble()) {
          F = intrinsics->GetFinalDoubleFieldFunction;
        } else {
          abort();
        }
      } else {
        F = intrinsics->GetFinalObjectFieldFunction;
      }
      push(CallInst::Create(F, ptr, "", currentBlock), sign->isUnsigned(), cl);
    }
  }
 
  if (!final) push(new LoadInst(ptr, "", currentBlock), sign->isUnsigned(), cl);
  if (type == Type::getInt64Ty(*llvmContext) ||
      type == Type::getDoubleTy(*llvmContext)) {
    push(intrinsics->constantZero, false);
  }
}


void JavaJIT::invokeInterface(uint16 index, bool buggyVirtual) {
  
  // Do the usual
  JavaConstantPool* ctpInfo = compilingClass->ctpInfo;
  const UTF8* name = 0;
  Signdef* signature = ctpInfo->infoOfInterfaceOrVirtualMethod(index, name);
  
  LLVMSignatureInfo* LSI = TheCompiler->getSignatureInfo(signature);
  const llvm::FunctionType* virtualType = LSI->getVirtualType();
  const llvm::PointerType* virtualPtrType = LSI->getVirtualPtrType();

  std::vector<Value*> args; // size = [signature->nbIn + 3];

  FunctionType::param_iterator it  = virtualType->param_end();
  makeArgs(it, index, args, signature->nbArguments + 1);
  
  const llvm::Type* retType = virtualType->getReturnType();
  BasicBlock* endBlock = createBasicBlock("end interface invoke");
  PHINode * node = 0;
  if (retType != Type::getVoidTy(*llvmContext)) {
    node = PHINode::Create(retType, "", endBlock);
  }
  
  JITVerifyNull(args[0]);
 
  CommonClass* cl = 0;
  JavaMethod* meth = 0;
  ctpInfo->infoOfMethod(index, ACC_VIRTUAL, cl, meth);
  Value* Meth = 0;

  if (meth) {
    Meth = TheCompiler->getMethodInClass(meth);
  } else {
    Meth = getConstantPoolAt(index, intrinsics->InterfaceLookupFunction,
                             intrinsics->JavaMethodType, 0, true);
  }

  BasicBlock* label_bb = createBasicBlock("bb");
  BasicBlock* label_bb4 = createBasicBlock("bb4");
  BasicBlock* label_bb6 = createBasicBlock("bb6");
  BasicBlock* label_bb7 = createBasicBlock("bb7");
    
  // Block entry (label_entry)
  Value* VT = CallInst::Create(intrinsics->GetVTFunction, args[0], "",
                               currentBlock);
  Value* IMT = CallInst::Create(intrinsics->GetIMTFunction, VT, "",
                                currentBlock);

  uint32_t tableIndex = InterfaceMethodTable::getIndex(name, signature->keyName);
  Constant* Index = ConstantInt::get(Type::getInt32Ty(*llvmContext),
                                     tableIndex);

  Value* indices[2] = { intrinsics->constantZero, Index };
  Instruction* ptr_18 = GetElementPtrInst::Create(IMT, indices, indices + 2, "",
                                                  currentBlock);
  Instruction* int32_19 = new LoadInst(ptr_18, "", false, currentBlock);
  int32_19 = new PtrToIntInst(int32_19, intrinsics->pointerSizeType, "",
                              currentBlock);
  Value* one = ConstantInt::get(intrinsics->pointerSizeType, 1);
  Value* zero = ConstantInt::get(intrinsics->pointerSizeType, 0);
  BinaryOperator* int32_20 = BinaryOperator::Create(Instruction::And, int32_19,
                                                    one, "", currentBlock);
  ICmpInst* int1_toBool = new ICmpInst(*currentBlock, ICmpInst::ICMP_EQ,
                                       int32_20, zero, "toBool");
  BranchInst::Create(label_bb, label_bb4, int1_toBool, currentBlock);
    
  // Block bb (label_bb)
  currentBlock = label_bb;
  CastInst* ptr_22 = new IntToPtrInst(int32_19, virtualPtrType, "", currentBlock);
  Value* ret = invoke(ptr_22, args, "", currentBlock);
  if (node) node->addIncoming(ret, currentBlock);
  BranchInst::Create(endBlock, currentBlock);
    
  // Block bb4 (label_bb4)
  currentBlock = label_bb4;
  Constant* MinusTwo = ConstantInt::get(intrinsics->pointerSizeType, -2);
  BinaryOperator* int32_25 = BinaryOperator::Create(Instruction::And, int32_19,
                                                    MinusTwo, "", currentBlock);
  const PointerType* Ty = PointerType::getUnqual(intrinsics->JavaMethodType);
  CastInst* ptr_26 = new IntToPtrInst(int32_25, Ty, "", currentBlock);
  LoadInst* int32_27 = new LoadInst(ptr_26, "", false, currentBlock);
  ICmpInst* int1_28 = new ICmpInst(*currentBlock, ICmpInst::ICMP_EQ, int32_27,
                                   Meth, "");
  BranchInst::Create(label_bb6, label_bb7, int1_28, currentBlock);
    
  // Block bb6 (label_bb6)
  currentBlock = label_bb6;
  PHINode* ptr_table_0_lcssa = PHINode::Create(Ty, "table.0.lcssa",
                                               currentBlock);
  ptr_table_0_lcssa->reserveOperandSpace(2);
  ptr_table_0_lcssa->addIncoming(ptr_26, label_bb4);
   
  GetElementPtrInst* ptr_31 = GetElementPtrInst::Create(ptr_table_0_lcssa,
                                                        intrinsics->constantOne, "",
                                                        currentBlock);

  LoadInst* int32_32 = new LoadInst(ptr_31, "", false, currentBlock);
  CastInst* ptr_33 = new BitCastInst(int32_32, virtualPtrType, "",
                                     currentBlock);
  ret = invoke(ptr_33, args, "", currentBlock);
  if (node) node->addIncoming(ret, currentBlock);
  BranchInst::Create(endBlock, currentBlock);
    
  // Block bb7 (label_bb7)
  currentBlock = label_bb7;
  PHINode* int32_indvar = PHINode::Create(Type::getInt32Ty(*llvmContext),
                                          "indvar", currentBlock);
  int32_indvar->reserveOperandSpace(2);
  int32_indvar->addIncoming(intrinsics->constantZero, label_bb4);
    
  BinaryOperator* int32_table_010_rec =
    BinaryOperator::Create(Instruction::Shl, int32_indvar, intrinsics->constantOne,
                           "table.010.rec", currentBlock);

  BinaryOperator* int32__rec =
    BinaryOperator::Create(Instruction::Add, int32_table_010_rec,
                           intrinsics->constantTwo, ".rec", currentBlock);
  GetElementPtrInst* ptr_37 = GetElementPtrInst::Create(ptr_26, int32__rec, "",
                                                        currentBlock);
  LoadInst* int32_38 = new LoadInst(ptr_37, "", false, currentBlock);
  ICmpInst* int1_39 = new ICmpInst(*currentBlock, ICmpInst::ICMP_EQ, int32_38,
                                   Meth, "");
  BinaryOperator* int32_indvar_next =
    BinaryOperator::Create(Instruction::Add, int32_indvar, intrinsics->constantOne,
                           "indvar.next", currentBlock);
  BranchInst::Create(label_bb6, label_bb7, int1_39, currentBlock);
  
  int32_indvar->addIncoming(int32_indvar_next, currentBlock);
  ptr_table_0_lcssa->addIncoming(ptr_37, currentBlock);
      
  currentBlock = endBlock;
  if (node) {
    if (node->getType() == intrinsics->JavaObjectType) {
      JnjvmClassLoader* JCL = compilingClass->classLoader;
      push(node, false, signature->getReturnType()->findAssocClass(JCL));
    } else {
      push(node, signature->getReturnType()->isUnsigned());
      if (retType == Type::getDoubleTy(*llvmContext) ||
          retType == Type::getInt64Ty(*llvmContext)) {
        push(intrinsics->constantZero, false);
      }
    }
  }
}

void JavaJIT::lowerArraycopy(std::vector<Value*>& args) {
  Function* meth = TheCompiler->getMethod(upcalls->VMSystemArraycopy);

  Value* ptr_src = args[0];
  Value* int32_start = args[1];
  Value* ptr_dst = args[2];
  Value* int32_start2 = args[3];
  Value* int32_length = args[4];

  JITVerifyNull(ptr_src);
  JITVerifyNull(ptr_dst);

  BasicBlock* label_entry = currentBlock;
  BasicBlock* label_bb = createBasicBlock("bb");
  BasicBlock* label_bb2 = createBasicBlock("bb2");
  BasicBlock* label_bb4 = createBasicBlock("bb4");
  BasicBlock* label_bb5 = createBasicBlock("bb5");
  BasicBlock* label_bb12_preheader = createBasicBlock("bb12.preheader");
  BasicBlock* label_bb7 = createBasicBlock("bb7");
  BasicBlock* label_bb11 = createBasicBlock("bb11");
  BasicBlock* label_memmove = createBasicBlock("memmove");
  BasicBlock* label_backward = createBasicBlock("backward");
  BasicBlock* label_return = createBasicBlock("return");
  
  BasicBlock* log_label_entry = createBasicBlock("log_entry");
  BasicBlock* log_label_bb = createBasicBlock("log_bb");
    
  // Block entry (label_entry)
  CallInst* ptr_16 = CallInst::Create(intrinsics->GetVTFunction, ptr_src, "",
                                      label_entry);
  CallInst* ptr_17 = CallInst::Create(intrinsics->GetVTFunction, ptr_dst, "",
                                      label_entry);
  
  ICmpInst* int1_18 = new ICmpInst(*label_entry, ICmpInst::ICMP_EQ, ptr_16,
                                   ptr_17, "");
  BranchInst::Create(label_bb, label_bb2, int1_18, label_entry);
    
  // Block bb (label_bb)
  currentBlock = label_bb;
  CallInst* ptr_20 = CallInst::Create(intrinsics->GetClassFunction, ptr_src, "",
                                      label_bb);
  std::vector<Value*> ptr_21_indices;
  ptr_21_indices.push_back(intrinsics->constantZero);
  ptr_21_indices.push_back(intrinsics->OffsetAccessInCommonClassConstant);
  Instruction* ptr_21 =
    GetElementPtrInst::Create(ptr_20, ptr_21_indices.begin(),
                              ptr_21_indices.end(), "", label_bb);
  LoadInst* int32_22 = new LoadInst(ptr_21, "", false, label_bb);
  Value* cmp = BinaryOperator::CreateAnd(int32_22, intrinsics->IsArrayConstant, "",
                                         label_bb);
  Value* zero = ConstantInt::get(Type::getInt16Ty(*llvmContext), 0);
  ICmpInst* int1_23 = new ICmpInst(*label_bb, ICmpInst::ICMP_NE, cmp, zero, "");
  BranchInst::Create(label_bb4, label_bb2, int1_23, label_bb);
   

  // Block bb2 (label_bb2)
  currentBlock = label_bb2;
  invoke(meth, args, "", label_bb2);
  BranchInst::Create(label_return, currentBlock);
    
    
  // Block bb4 (label_bb4)
  currentBlock = label_bb4;
  BinaryOperator* int32_27 = BinaryOperator::Create(Instruction::Add,
                                                    int32_length, int32_start,
                                                    "", label_bb4);
  Value* int32_28 = arraySize(ptr_src);
    
  ICmpInst* int1_29 = new ICmpInst(*label_bb4, ICmpInst::ICMP_ULE, int32_27,
                                   int32_28, "");
  BranchInst::Create(label_bb5, label_bb7, int1_29, label_bb4);
    
  // Block bb5 (label_bb5)
  currentBlock = label_bb5;
  BinaryOperator* int32_31 = BinaryOperator::Create(Instruction::Add,
                                                    int32_length, int32_start2,
                                                    "", label_bb5);
  Value* int32_32 = arraySize(ptr_dst);
    
  ICmpInst* int1_33 = new ICmpInst(*label_bb5, ICmpInst::ICMP_ULE, int32_31,
                                   int32_32, "");
  BranchInst::Create(label_bb12_preheader, label_bb7, int1_33, label_bb5);
    
  // Block bb12.preheader (label_bb12_preheader)
  currentBlock = label_bb12_preheader;
  ICmpInst* int1_35 = new ICmpInst(*label_bb12_preheader, ICmpInst::ICMP_UGT,
                                   int32_length, intrinsics->constantZero, "");
  BranchInst::Create(log_label_entry, label_return, int1_35, label_bb12_preheader);
    
  // Block bb7 (label_bb7)
  currentBlock = label_bb7;
  Value* VTArgs[1] = { Constant::getNullValue(intrinsics->VTType) };
  throwException(intrinsics->ArrayStoreExceptionFunction, VTArgs, 1);
   

  
  // Block entry (label_entry)
  currentBlock = log_label_entry;
  Value* ptr_10_indices[2] = { intrinsics->constantZero,
                               intrinsics->OffsetBaseClassInArrayClassConstant };
  Instruction* temp = new BitCastInst(ptr_20, intrinsics->JavaClassArrayType, "",
                                      log_label_entry);
  Instruction* ptr_10 = GetElementPtrInst::Create(temp, ptr_10_indices,
                                                  ptr_10_indices + 2, "",
                                                  log_label_entry);

  LoadInst* ptr_11 = new LoadInst(ptr_10, "", false, log_label_entry);
    
  Value* ptr_12_indices[2] = { intrinsics->constantZero,
                               intrinsics->OffsetAccessInCommonClassConstant };
  Instruction* ptr_12 = GetElementPtrInst::Create(ptr_11, ptr_12_indices,
                                                  ptr_12_indices + 2, "",
                                                  log_label_entry);
  LoadInst* int16_13 = new LoadInst(ptr_12, "", false, log_label_entry);

  BinaryOperator* int32_15 = BinaryOperator::Create(Instruction::And, int16_13,
                                                    intrinsics->IsPrimitiveConstant,
                                                    "", log_label_entry);
  ICmpInst* int1_16 = new ICmpInst(*log_label_entry, ICmpInst::ICMP_EQ,
                                   int32_15, zero, "");
  BranchInst::Create(label_bb2, log_label_bb, int1_16, log_label_entry);
    
  // Block bb (log_label_bb)
  currentBlock = log_label_bb;
  Value* ptr_11_indices[2] = { intrinsics->constantZero,
                               intrinsics->OffsetLogSizeInPrimitiveClassConstant };
  temp = new BitCastInst(ptr_11, intrinsics->JavaClassPrimitiveType, "",
                         log_label_bb);
  GetElementPtrInst* ptr_18 = GetElementPtrInst::Create(temp, ptr_11_indices,
                                                        ptr_11_indices + 2, "",
                                                        log_label_bb);
  LoadInst* int32_20 = new LoadInst(ptr_18, "", false, log_label_bb);
   
  int32_start = BinaryOperator::CreateShl(int32_start, int32_20, "",
                                          log_label_bb);
  int32_start2 = BinaryOperator::CreateShl(int32_start2, int32_20, "",
                                           log_label_bb);
  int32_length = BinaryOperator::CreateShl(int32_length, int32_20, "",
                                           log_label_bb);

  ptr_src = new BitCastInst(ptr_src, intrinsics->JavaArrayUInt8Type, "",
                            log_label_bb);
  
  ptr_dst = new BitCastInst(ptr_dst, intrinsics->JavaArrayUInt8Type, "",
                            log_label_bb);
  
  Value* indexes[3] = { intrinsics->constantZero,
                        intrinsics->JavaArrayElementsOffsetConstant,
                        int32_start };
  Instruction* ptr_42 = GetElementPtrInst::Create(ptr_src, indexes, indexes + 3,
                                                  "", log_label_bb);
  
  indexes[2] = int32_start2;
  Instruction* ptr_44 = GetElementPtrInst::Create(ptr_dst, indexes, indexes + 3,
                                                  "", log_label_bb);
 
  BranchInst::Create(label_memmove, log_label_bb);

  // Block memmove
  currentBlock = label_memmove;
  Value* src_int = new PtrToIntInst(ptr_42, intrinsics->pointerSizeType, "",
                                    currentBlock);
  
  Value* dst_int = new PtrToIntInst(ptr_44, intrinsics->pointerSizeType, "",
                                    currentBlock);

  cmp = new ICmpInst(*currentBlock, ICmpInst::ICMP_ULT, dst_int, src_int, "");

  Value* increment = SelectInst::Create(cmp, intrinsics->constantOne,
                                        intrinsics->constantMinusOne, "",
                                        currentBlock);
  BranchInst::Create(label_bb11, label_backward, cmp, currentBlock);

  PHINode* phi_dst_ptr = PHINode::Create(ptr_44->getType(), "", label_bb11);
  PHINode* phi_src_ptr = PHINode::Create(ptr_44->getType(), "", label_bb11);
  phi_dst_ptr->addIncoming(ptr_44, currentBlock);
  phi_src_ptr->addIncoming(ptr_42, currentBlock);
 
  // Block backward
  currentBlock = label_backward;

  ptr_42 = GetElementPtrInst::Create(ptr_42, int32_length, "",
                                     currentBlock);
  
  ptr_44 = GetElementPtrInst::Create(ptr_44, int32_length, "",
                                     currentBlock);
  
  ptr_42 = GetElementPtrInst::Create(ptr_42, intrinsics->constantMinusOne, "",
                                     currentBlock);
  
  ptr_44 = GetElementPtrInst::Create(ptr_44, intrinsics->constantMinusOne, "",
                                     currentBlock);
  
  phi_dst_ptr->addIncoming(ptr_44, currentBlock);
  phi_src_ptr->addIncoming(ptr_42, currentBlock);

  BranchInst::Create(label_bb11, currentBlock);
  
  // Block bb11 (label_bb11)
  currentBlock = label_bb11;
  Argument* fwdref_39 = new Argument(Type::getInt32Ty(*llvmContext));
  PHINode* int32_i_016 = PHINode::Create(Type::getInt32Ty(*llvmContext),
                                         "i.016", label_bb11);
  int32_i_016->reserveOperandSpace(2);
  int32_i_016->addIncoming(fwdref_39, label_bb11);
  int32_i_016->addIncoming(intrinsics->constantZero, log_label_bb);
   
  LoadInst* ptr_43 = new LoadInst(phi_src_ptr, "", false, label_bb11);
  new StoreInst(ptr_43, phi_dst_ptr, false, label_bb11);


  ptr_42 = GetElementPtrInst::Create(phi_src_ptr, increment, "",
                                     label_bb11);
  
  ptr_44 = GetElementPtrInst::Create(phi_dst_ptr, increment, "",
                                     label_bb11);
  phi_dst_ptr->addIncoming(ptr_44, label_bb11);
  phi_src_ptr->addIncoming(ptr_42, label_bb11);

  BinaryOperator* int32_indvar_next =
    BinaryOperator::Create(Instruction::Add, int32_i_016, intrinsics->constantOne,
                           "indvar.next", label_bb11);
  ICmpInst* int1_exitcond = new ICmpInst(*label_bb11, ICmpInst::ICMP_EQ,
                                         int32_indvar_next, int32_length,
                                         "exitcond");
  BranchInst::Create(label_return, label_bb11, int1_exitcond, label_bb11);

  // Resolve Forward References
  fwdref_39->replaceAllUsesWith(int32_indvar_next); delete fwdref_39;

  currentBlock = label_return;
}

DebugLoc JavaJIT::CreateLocation() {
  LineInfo LI = { currentLineNumber, currentCtpIndex, currentBytecodeIndex,
                  currentBytecode };
  codeInfo.push_back(LI);
  DebugLoc DL = DebugLoc::get(callNumber++, 0, DbgSubprogram);
  return DL;
}

#ifdef DWARF_EXCEPTIONS
#include "ExceptionsDwarf.inc"
#else
#include "ExceptionsCheck.inc"
#endif
