//===----------- 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 2
#define JNJVM_EXECUTE 0

#include <string>
#include <sstream>
#include <cstring>

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

#include "vmkit/JIT.h"
#include "vmkit/GC.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;
using namespace std;

void JavaJIT::updateStackInfo(Opinfo& info) {
  if (stackSize()) {
    if (!info.stack.size()) {
      info.stack = stack;
    } else {
      int size = stack.size();
      info.stack.clear();
      for (int i = 0 ; i < size; i++) {
        info.stack.push_back(MetaInfo(stack[i].type, NOP));
      }
    }
  }
}

bool JavaJIT::needsInitialisationCheck(Class* cl) {
  if (cl->isReadyForCompilation() || 
      (!cl->isInterface() && compilingClass->isSubclassOf(cl))) {
    return false;
  }

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

  return true;
}

void JavaJIT::checkYieldPoint() {
  if (!TheCompiler->useCooperativeGC()) return;
  Value* YieldPtr = getDoYieldPtr(getMutatorThreadPtr());

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

  BasicBlock* continueBlock = createBasicBlock("afterSafePoint");
  BasicBlock* yieldBlock = createBasicBlock("inSafePoint");
  BranchInst::Create(yieldBlock, continueBlock, Yield, currentBlock);

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

  currentBlock = continueBlock;
}

bool JavaJIT::canBeInlined(JavaMethod* meth, bool customizing) {
  if (inlineMethods[meth]) return false;
  if (isSynchro(meth->access)) return false;
  if (isNative(meth->access)) return false;

  JavaAttribute* codeAtt = meth->lookupAttribute(JavaAttribute::codeAttribute);
  if (codeAtt == NULL) return false;

  Reader reader(codeAtt, meth->classDef->bytes);
  /* uint16 maxStack = */ reader.readU2();
  /* uint16 maxLocals = */ reader.readU2();
  uint32 codeLen = reader.readU4();
  uint32 start = reader.cursor; 
  reader.seek(codeLen, Reader::SeekCur);
  uint16 handlers = reader.readU2();
  if (handlers != 0) return false;
  reader.cursor = start;

  JavaJIT jit(TheCompiler, meth, llvmFunction, customizing ? customizeFor : NULL);
  jit.inlineMethods = inlineMethods;
  jit.inlineMethods[meth] = true;
  if (!jit.analyzeForInlining(reader, codeLen)) return false;
  jit.inlineMethods[meth] = false;
  return true;
}

bool JavaJIT::isThisReference(int stackIndex) {
  return !overridesThis
      && (stack[stackIndex].bytecode == ALOAD_0)
      && !isStatic(compilingMethod->access);
}

void JavaJIT::invokeVirtual(uint16 index) {
  JavaObject* source = 0;
  llvm_gcroot(source, 0);
  
  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.
  const UTF8* name = 0;
  Signdef* signature = ctpInfo->infoOfInterfaceOrVirtualMethod(index, name);

  bool customized = false;
  bool thisReference =
    isThisReference(stackSize() - signature->getNumberOfSlots() - 1);
  if (thisReference && meth) {
    isCustomizable = true;
    if ((customizeFor != NULL)
        && customizeFor->isSubclassOf(cl)) {
      meth = customizeFor->lookupMethodDontThrow(
          meth->name, meth->type, false, true, NULL);
      assert(meth);
      canBeDirect = true;
      customized = true;
      assert(!meth->classDef->isInterface());
      assert(!isAbstract(meth->access));
    }
  }
 
  if (meth && ((cl && isFinal(cl->access)) ||
      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);
	}
 
 
  if (TheCompiler->isStaticCompiling()) {
    Value* obj = objectStack[stack.size() - signature->nbArguments - 1];
    source = TheCompiler->getFinalObject(obj);
    if (source) {
      canBeDirect = true;
      CommonClass* sourceClass = JavaObject::getClass(source);
      Class* lookup = sourceClass->isArray() ? sourceClass->super :
                                               sourceClass->asClass();
      meth = lookup->lookupMethodDontThrow(name, signature->keyName, false,
                                           true, 0);
    }
    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);
    }
  }
  assert((meth || !canBeDirect) && "Can't directly call a method we don't have");
 
  Typedef* retTypedef = signature->getReturnType();
  std::vector<Value*> args; // size = [signature->nbIn + 3];
  LLVMSignatureInfo* LSI = TheCompiler->getSignatureInfo(signature);
  llvm::FunctionType* virtualType = LSI->getVirtualType();
  FunctionType::param_iterator it  = virtualType->param_end();
  llvm::Type* retType = virtualType->getReturnType();

  bool needsInit = false;
  if (canBeDirect && canBeInlined(meth, customized)) {
    makeArgs(it, index, args, signature->nbArguments + 1);
    if (!thisReference) JITVerifyNull(args[0]);
    val = invokeInline(meth, args, customized);
  } else if (canBeDirect &&
      !TheCompiler->needsCallback(meth, customized ? customizeFor : NULL, &needsInit)) {
    makeArgs(it, index, args, signature->nbArguments + 1);
    if (!thisReference) JITVerifyNull(args[0]);
    val = invoke(TheCompiler->getMethod(meth, customized ? customizeFor : NULL),
                 args, "", currentBlock);
  } else {

    BasicBlock* endBlock = 0;
    PHINode* node = 0;
    Value* indexes2[2];
    indexes2[0] = intrinsics->constantZero;
    bool nullChecked = false;

    if (meth) {
      LLVMMethodInfo* LMI = TheCompiler->getMethodInfo(meth);
      Constant* Offset = LMI->getOffset();
      indexes2[1] = Offset;
    } else {
      nullChecked = true;
      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), 2, "",
                                      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);
      Value* targetObject = getTarget(signature);
      targetObject = new LoadInst(targetObject, "", false, currentBlock);
      if (!thisReference) JITVerifyNull(targetObject);
      Args.push_back(targetObject);
      load = invoke(intrinsics->VirtualLookupFunction, Args, "", currentBlock);
      node->addIncoming(load, currentBlock);
      BranchInst::Create(endResolveVirtual, currentBlock);
      currentBlock = endResolveVirtual;

      indexes2[1] = node;
    }

    makeArgs(it, index, args, signature->nbArguments + 1);
    if (!nullChecked && !thisReference) JITVerifyNull(args[0]);
    Value* VT = CallInst::Create(intrinsics->GetVTFunction, args[0], "",
                                 currentBlock);
 
    Value* FuncPtr = GetElementPtrInst::Create(VT, indexes2, "", currentBlock);
    
    Value* Func = new LoadInst(FuncPtr, "", currentBlock);
  
    Func = new BitCastInst(Func, LSI->getVirtualPtrType(), "", currentBlock);
    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);
      }
    }
  }
}

llvm::Value* JavaJIT::getMutatorThreadPtr() {
  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, intrinsics->MutatorThreadType, "MutatorThreadPtr", currentBlock);

  return threadId;
}

llvm::Value* JavaJIT::getJavaThreadPtr(llvm::Value* mutatorThreadPtr) {
  return new BitCastInst(mutatorThreadPtr, intrinsics->JavaThreadType, "JavaThreadPtr", currentBlock);
}

llvm::Value* JavaJIT::getIsolateIDPtr(llvm::Value* mutatorThreadPtr) { 
	Value* GEP[3] = { intrinsics->constantZero,
										intrinsics->OffsetThreadInMutatorThreadConstant,
										intrinsics->OffsetIsolateIDInThreadConstant };
    
	return GetElementPtrInst::Create(mutatorThreadPtr, GEP, "isolateIDPtr", currentBlock);
}

llvm::Value* JavaJIT::getVMPtr(llvm::Value* mutatorThreadPtr) { 
	Value* GEP[3] = { intrinsics->constantZero,
										intrinsics->OffsetThreadInMutatorThreadConstant,
										intrinsics->OffsetVMInThreadConstant };
    
	return GetElementPtrInst::Create(mutatorThreadPtr, GEP, "VMPtr", currentBlock);
}

llvm::Value* JavaJIT::getDoYieldPtr(llvm::Value* mutatorThreadPtr) {
	Value* GEP[3] = { intrinsics->constantZero,
										intrinsics->OffsetThreadInMutatorThreadConstant,
										intrinsics->OffsetDoYieldInThreadConstant };
    
	return GetElementPtrInst::Create(mutatorThreadPtr, GEP, "doYieldPtr", currentBlock);
}

llvm::Value* JavaJIT::getJNIEnvPtr(llvm::Value* javaThreadPtr) { 
	Value* GEP[2] = { intrinsics->constantZero,
										intrinsics->OffsetJNIInJavaThreadConstant };
    
	return GetElementPtrInst::Create(javaThreadPtr, GEP, "JNIPtr", currentBlock);
}

llvm::Value* JavaJIT::getJavaExceptionPtr(llvm::Value* javaThreadPtr) { 
	Value* GEP[2] = { intrinsics->constantZero,
										intrinsics->OffsetJavaExceptionInJavaThreadConstant };
    
	return GetElementPtrInst::Create(javaThreadPtr, GEP, "pendingExceptionPtr", currentBlock);
}

static llvm::Function* GetNativeCallee(JavaLLVMCompiler* TheCompiler,
                                       JavaMethod* compilingMethod) {
  LLVMSignatureInfo* LSI =
    TheCompiler->getSignatureInfo(compilingMethod->getSignature());
  FunctionType* FTy = LSI->getNativeStubType();
  string methName;
  Function* callee = Function::Create(FTy,
                                      GlobalValue::ExternalLinkage,
                                      compilingMethod->getName(methName, true),
                                      TheCompiler->getLLVMModule());
  std::vector<Value*> args;
  Function::arg_iterator i = callee->arg_begin();
  Value* nativeFunc = i;
  i++;
  for (Function::arg_iterator e = callee->arg_end(); i != e; i++) {
    args.push_back(i);
  }

  LLVMContext& llvmContext = TheCompiler->getLLVMContext();
  BasicBlock* BB = BasicBlock::Create(llvmContext, "", callee);
  Value* res = CallInst::Create(nativeFunc, args, "", BB);
  if (callee->getFunctionType()->getReturnType() != Type::getVoidTy(llvmContext)) {
    ReturnInst::Create(llvmContext, res, BB);
  } else {
    ReturnInst::Create(llvmContext, BB);
  }
  callee->setGC("vmkit");

  TheCompiler->GenerateStub(callee);
  return callee;
}

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

  FunctionType *funcType = llvmFunction->getFunctionType();
  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;

  vmkit::ThreadAllocator allocator;
  char* functionName = (char*)allocator.Allocate(
      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) {
    Function* callee = Function::Create(llvmFunction->getFunctionType(),
                                        GlobalValue::ExternalLinkage,
                                        functionName,
                                        llvmFunction->getParent());
    TheCompiler->setMethod(callee, (void*)natPtr, functionName);
    currentBlock = createBasicBlock("start");
    std::vector<Value*> args;
    for (Function::arg_iterator i = func->arg_begin(), e = func->arg_end();
         i != e;
         i++) {
      args.push_back(i);
    }
    Value* res = CallInst::Create(callee, args, "", currentBlock);
    if (returnType != Type::getVoidTy(*llvmContext)) {
      ReturnInst::Create(*llvmContext, res, currentBlock);
    } else {
      ReturnInst::Create(*llvmContext, currentBlock);
    }
    return llvmFunction;
  }

  currentExceptionBlock = endExceptionBlock = 0;
  currentBlock = createBasicBlock("start");
  endBlock = createBasicBlock("end block");
  
  if (returnType != Type::getVoidTy(*llvmContext)) {
    endNode = PHINode::Create(returnType, 0, "", 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), sizeof(vmkit::KnownFrame));
  Value* Frame = new AllocaInst(Type::getInt8Ty(*llvmContext), sizeF, "", currentBlock);
  
  uint32 nargs = func->arg_size() + 1 + (stat ? 1 : 0); 
  std::vector<Value*> nativeArgs;
  nativeArgs.push_back(NULL); // Will contain the callee
  
  
  Value* jniEnv = getJNIEnvPtr(getJavaThreadPtr(getMutatorThreadPtr()));
 
  jniEnv = new BitCastInst(jniEnv, intrinsics->ptrType, "", currentBlock);

  nativeArgs.push_back(jniEnv);

  uint32 index = 0;
  if (stat) {
    Value* cl = TheCompiler->getJavaClassPtr(compilingClass);
    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("");
      Type* Ty = PointerType::getUnqual(intrinsics->JavaObjectType);
      PHINode* node = PHINode::Create(Ty, 2, "", 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 (i == func->arg_begin() && !stat) {
        this->thisObject = temp;
      }
      
      if (TheCompiler->useCooperativeGC()) {
        Value* GCArgs[2] = { 
          new BitCastInst(temp, intrinsics->ptrPtrType, "",
                          func->begin()->getTerminator()),
          intrinsics->constantPtrNull
        };
        
        CallInst::Create(intrinsics->llvm_gc_gcroot, GCArgs, "",
                         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, "",
                       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);
    Type* Ty = test->getType();
    PHINode* node = PHINode::Create(Ty, 2, "", 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;
  }
  nativeArgs[0] = nativeFunc;

  // Synchronize before saying we're entering native
  if (isSynchro(compilingMethod->access)) {
    nbHandlers = 1;
    beginSynchronize();
  }
  
  Value* Args4[3] = { temp, oldCLIN, Frame };

  CallInst::Create(intrinsics->StartJNIFunction, Args4, "", currentBlock);
  
  Function* callee = GetNativeCallee(TheCompiler, compilingMethod);
  Value* result = llvm::CallInst::Create(callee, nativeArgs, "", currentBlock);

  if (returnType == intrinsics->JavaObjectType) {
    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, "", false, 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, "", currentBlock);
  
  // Synchronize after leaving native.
  if (isSynchro(compilingMethod->access))
    endSynchronize();

  BasicBlock* ifNormal = createBasicBlock("");
  BasicBlock* ifException = createBasicBlock("");
  Value* javaExceptionPtr = getJavaExceptionPtr(getJavaThreadPtr(getMutatorThreadPtr()));
  Value* obj = new LoadInst(javaExceptionPtr, "", currentBlock);
  Value* test = new ICmpInst(*currentBlock, ICmpInst::ICMP_NE, obj, intrinsics->JavaObjectNullConstant, "");
  BranchInst::Create(ifException, ifNormal, test, currentBlock);

  currentBlock = ifException;
  // Clear exception.
  new StoreInst(intrinsics->JavaObjectNullConstant, javaExceptionPtr,
                currentBlock);
  CallInst::Create(intrinsics->ThrowExceptionFunction, obj, "", currentBlock);
  new UnreachableInst(*llvmContext, currentBlock);
  currentBlock = ifNormal;
  
  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());
  
  return llvmFunction;
}

llvm::Value* JavaJIT::objectToHeader(Value* obj) {
  obj = new PtrToIntInst(obj, intrinsics->pointerSizeType, "", currentBlock);
  Value* d = ConstantInt::get(intrinsics->pointerSizeType, gcHeader::hiddenHeaderSize());
	obj = BinaryOperator::CreateSub(obj, d, "", currentBlock);
	return new IntToPtrInst(obj, intrinsics->ObjectHeaderType, "objectHeader", currentBlock);
}

void JavaJIT::monitorEnter(Value* obj) {
  Value* lockPtr = objectToHeader(obj);

  Value* lock = new LoadInst(lockPtr, "", currentBlock);

  Value* NonLockBitsMask = ConstantInt::get(intrinsics->pointerSizeType,
                                            vmkit::ThinLock::NonLockBitsMask);

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

  Value* threadId = getMutatorThreadPtr();
  threadId = new PtrToIntInst(threadId, intrinsics->pointerSizeType, "",
                              currentBlock);
  Value* newValMask = BinaryOperator::CreateOr(threadId, lock, "",
                                               currentBlock);

  // Do the atomic compare and swap.
  Value* atomic = new AtomicCmpXchgInst(
      lockPtr, lock, newValMask, SequentiallyConsistent, CrossThread,
      currentBlock);
  
  Value* cmp = new ICmpInst(*currentBlock, ICmpInst::ICMP_EQ, atomic,
                            lock, "");
  
  BasicBlock* OK = createBasicBlock("synchronize passed");
  BasicBlock* NotOK = createBasicBlock("synchronize did not pass");

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

  // The atomic CAS did not work.
  currentBlock = NotOK;
  CallInst::Create(intrinsics->AquireObjectFunction, obj, "", currentBlock);
  BranchInst::Create(OK, currentBlock);

  currentBlock = OK;
}

void JavaJIT::monitorExit(Value* obj) {
	// obj should not be null if we are here.
    BasicBlock* nonNullObjBlock = createBasicBlock("monitorExit_nonNullObj");
    BasicBlock* EndBlock = createBasicBlock("monitorExit_End");

	Value* test = new ICmpInst(*currentBlock, ICmpInst::ICMP_EQ, obj, intrinsics->JavaObjectNullConstant, "isObjectNull");
	BranchInst::Create(EndBlock, nonNullObjBlock, test, currentBlock);

	currentBlock = nonNullObjBlock;

	Value* lockPtr = objectToHeader(obj);

  Value* lock = new LoadInst(lockPtr, "", currentBlock);

  Value* NonLockBitsMask = ConstantInt::get(
      intrinsics->pointerSizeType, vmkit::ThinLock::NonLockBitsMask);

  Value* lockedMask = BinaryOperator::CreateAnd(
      lock, NonLockBitsMask, "", currentBlock);
  
  Value* threadId = getMutatorThreadPtr();
  threadId = new PtrToIntInst(threadId, intrinsics->pointerSizeType, "",
                              currentBlock);
  
  Value* oldValMask = BinaryOperator::CreateOr(threadId, lockedMask, "",
                                               currentBlock);

  std::vector<Value*> atomicArgs;
  atomicArgs.push_back(lockPtr);
  atomicArgs.push_back(oldValMask);
  atomicArgs.push_back(lockedMask);

  // Do the atomic compare and swap.
  Value* atomic = new AtomicCmpXchgInst(
      lockPtr, oldValMask, lockedMask, SequentiallyConsistent, CrossThread,
      currentBlock);
  
  Value* cmp = new ICmpInst(*currentBlock, ICmpInst::ICMP_EQ, atomic,
                            oldValMask, "");
  
  BasicBlock* LockFreeCASFailed = createBasicBlock("Lock-Free CAS Failed");

  BranchInst::Create(EndBlock, LockFreeCASFailed, cmp, currentBlock);

  // The atomic cas did not work.
  currentBlock = LockFreeCASFailed;
  CallInst::Create(intrinsics->ReleaseObjectFunction, obj, "", currentBlock);
  BranchInst::Create(EndBlock, currentBlock);

  currentBlock = EndBlock;
}

void JavaJIT::beginSynchronize() {
  Value* obj = 0;
  if (isVirtual(compilingMethod->access)) {
    assert(thisObject != NULL && "beginSynchronize without this");
    obj = new LoadInst(
        thisObject, "", false, currentBlock);
  } else {
    obj = TheCompiler->getJavaClassPtr(compilingClass);
    obj = new LoadInst(obj, "", false, currentBlock);
  }
  monitorEnter(obj);
}

void JavaJIT::endSynchronize() {
  Value* obj = 0;
  if (isVirtual(compilingMethod->access)) {
    assert(thisObject != NULL && "endSynchronize without this");
    obj = new LoadInst(
        thisObject, "", false, currentBlock);
  } else {
    obj = TheCompiler->getJavaClassPtr(compilingClass);
    obj = new LoadInst(obj, "", false, currentBlock);
  }
  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, "");
        C->insertAfter(I);
      }
    }
  }
}

Instruction* JavaJIT::inlineCompile(BasicBlock*& curBB,
                                    BasicBlock* endExBlock,
                                    std::vector<Value*>& args) {
  JavaAttribute* codeAtt = compilingMethod->lookupAttribute(JavaAttribute::codeAttribute);
  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);
  
  LLVMAssessorInfo& LAI = TheCompiler->getTypedefInfo(
      compilingMethod->getSignature()->getReturnType());
  Type* returnType = LAI.llvmType;

  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;
  uint32 max = args.size();

  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;
    thisObject = objectLocals[0];
  }

  for (;count < max; ++i, ++index, ++count, ++type) {
    
    const Typedef* cur = arguments[type];
    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));
    }
  }
  
  nbHandlers = readExceptionTable(reader, codeLen);
  
  reader.cursor = start;
  exploreOpcodes(reader, codeLen);

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

  reader.cursor = start;
  compileOpcodes(reader, codeLen);
  
  PRINT_DEBUG(JNJVM_COMPILE, 1, DARK_MAGENTA,
              "--> end inlineCompile for %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;
}

static char* setInstructionName(char *s, size_t maxlen, const char * format, ...)
{
	va_list args;
	va_start(args, format);
    vsnprintf(s, maxlen, format, args);
    va_end(args);
    return s;
}

llvm::Function* JavaJIT::javaCompile() {

  PRINT_DEBUG(JNJVM_COMPILE, 1, DARK_CYAN, "javacompile for (%s.)%s.%s\n",
			  (compilingClass->super)?UTF8Buffer(compilingClass->super->name).cString():"",
              UTF8Buffer(compilingClass->name).cString(),
              UTF8Buffer(compilingMethod->name).cString());

  string methName, methNameLink;
  DbgSubprogram = TheCompiler->getDebugFactory()->createFunction(
      DIDescriptor(), compilingMethod->getName(methName, false),
      compilingMethod->getName(methNameLink, true), DIFile(), 0,
      TheCompiler->getDebugFactory()->createSubroutineType(DIFile(), DIArray()),
      false, false, 0);

  JavaAttribute* codeAtt = compilingMethod->lookupAttribute(JavaAttribute::codeAttribute);
  
  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);

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

  const size_t instNameLen = 4096;
  char instName[instNameLen];

  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;
  }

  Instruction* returnValue = NULL;
  if (returnType == intrinsics->JavaObjectType &&
      TheCompiler->useCooperativeGC()) {
    returnValue = new AllocaInst(intrinsics->JavaObjectType, "returnValue",
                                 currentBlock);
    Instruction* cast = 
        new BitCastInst(returnValue, intrinsics->ptrPtrType, "", currentBlock);
    Value* GCArgs[2] = { cast, intrinsics->constantPtrNull };
        
    CallInst::Create(intrinsics->llvm_gc_gcroot, GCArgs, "", currentBlock);
  }

  for (int i = 0; i < maxLocals; i++) {
    intLocals.push_back(new AllocaInst(Type::getInt32Ty(*llvmContext), setInstructionName(instName, instNameLen, "int_%d", i), currentBlock));
    new StoreInst(Constant::getNullValue(Type::getInt32Ty(*llvmContext)), intLocals.back(), false, currentBlock);
    doubleLocals.push_back(new AllocaInst(Type::getDoubleTy(*llvmContext), setInstructionName(instName, instNameLen, "double_%d", i), currentBlock));
    new StoreInst(Constant::getNullValue(Type::getDoubleTy(*llvmContext)), doubleLocals.back(), false, currentBlock);
    longLocals.push_back(new AllocaInst(Type::getInt64Ty(*llvmContext), setInstructionName(instName, instNameLen, "long_%d", i), currentBlock));
    new StoreInst(Constant::getNullValue(Type::getInt64Ty(*llvmContext)), longLocals.back(), false, currentBlock);
    floatLocals.push_back(new AllocaInst(Type::getFloatTy(*llvmContext), setInstructionName(instName, instNameLen, "float_%d", i), currentBlock));
    new StoreInst(Constant::getNullValue(Type::getFloatTy(*llvmContext)), floatLocals.back(), false, currentBlock);
    objectLocals.push_back(new AllocaInst(intrinsics->JavaObjectType, setInstructionName(instName, instNameLen, "object_%d", i), 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, setInstructionName(instName, instNameLen, "stack_object_%d", i), currentBlock));
    addHighLevelType(objectStack.back(), upcalls->OfObject);
    intStack.push_back(new AllocaInst(Type::getInt32Ty(*llvmContext), setInstructionName(instName, instNameLen, "stack_int_%d", i), currentBlock));
    doubleStack.push_back(new AllocaInst(Type::getDoubleTy(*llvmContext), setInstructionName(instName, instNameLen, "stack_double_%d", i), currentBlock));
    longStack.push_back(new AllocaInst(Type::getInt64Ty(*llvmContext), setInstructionName(instName, instNameLen, "stack_long_%d", i), currentBlock));
    floatStack.push_back(new AllocaInst(Type::getFloatTy(*llvmContext), setInstructionName(instName, instNameLen, "stack_float_%d", i), currentBlock));
  }
 
  uint32 index = 0;
  uint32 count = 0;
  uint32 max = func->arg_size();

  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;
    thisObject = objectLocals[0];
  }

  for (;count < max; ++i, ++index, ++count, ++type) {
    
    const Typedef* cur = arguments[type];
    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));
    }
  }

  // Now that arguments have been setup, we can proceed with runtime calls.
#if JNJVM_EXECUTE > 0
    {
    Value* arg = TheCompiler->getMethodInClass(compilingMethod);

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

  nbHandlers = readExceptionTable(reader, codeLen);
  if (nbHandlers != 0) {
    jmpBuffer = new AllocaInst(ArrayType::get(Type::getInt8Ty(*llvmContext), sizeof(vmkit::ExceptionBuffer)), "", currentBlock);
    jmpBuffer = new BitCastInst(jmpBuffer, intrinsics->ptrType, "exceptionSavePoint", currentBlock);
  }

  reader.cursor = start;
  exploreOpcodes(reader, codeLen);
 
  endBlock = createBasicBlock("end");

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

  checkYieldPoint();
  
  if (isSynchro(compilingMethod->access)) {
    beginSynchronize();
  }
  
  if (TheCompiler->hasExceptionsEnabled() &&
      !vmkit::System::SupportsHardwareStackOverflow()) {
    // 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;
    throwRuntimeException(intrinsics->StackOverflowErrorFunction, 0, 0);
    currentBlock = noStackOverflow;
  }

  reader.cursor = start;
  compileOpcodes(reader, codeLen);

  // This isn't a real requirement, although javac-produced bytcode does
  // seem to adhere to it.  However jython and similar (clojure, etc) don't
  // always create bytecode that matches this, and AFAICT rejecting the
  // code is incorrect.
  //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 (returnValue != NULL) {
    new StoreInst(endNode, returnValue, currentBlock);
  }

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

#if JNJVM_EXECUTE > 0
    {
    Value* arg = TheCompiler->getMethodInClass(compilingMethod); 
    CallInst::Create(intrinsics->PrintMethodEndFunction, arg, "", currentBlock);
    }
#endif

  finishExceptions();
  
  PI = pred_begin(currentBlock);
  PE = pred_end(currentBlock);
  if (PI == PE) {
    currentBlock->eraseFromParent();
  } else {
    if (nbHandlers != 0) {
      BasicBlock* ifNormal = createBasicBlock("No exception was thrown");
      BasicBlock* ifException = createBasicBlock("Rethrow Exception");
      Value* javaExceptionPtr = getJavaExceptionPtr(getJavaThreadPtr(getMutatorThreadPtr()));
      Value* obj = new LoadInst(javaExceptionPtr, "pendingException", currentBlock);
      Value* test = new ICmpInst(*currentBlock, ICmpInst::ICMP_NE, obj, intrinsics->JavaObjectNullConstant, "");
      BranchInst::Create(ifException, ifNormal, test, currentBlock);

      currentBlock = ifException;
      // Clear exception.
      new StoreInst(intrinsics->JavaObjectNullConstant, javaExceptionPtr,
                    currentBlock);
      CallInst::Create(intrinsics->ThrowExceptionFunction, obj, "", currentBlock);
      new UnreachableInst(*llvmContext, currentBlock);
      currentBlock = ifNormal;
    }

    if (returnType != Type::getVoidTy(*llvmContext)) {
      if (returnValue != NULL) {
        Value* obj = new LoadInst(
            returnValue, "", false, currentBlock);
        ReturnInst::Create(*llvmContext, obj, currentBlock);
      } else {
        ReturnInst::Create(*llvmContext, endNode, currentBlock);
      }
    } else {
      ReturnInst::Create(*llvmContext, currentBlock);
    }
  }

   
  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, DARK_CYAN, "--> end of javacompile for %s.%s\n",
              UTF8Buffer(compilingClass->name).cString(),
              UTF8Buffer(compilingMethod->name).cString());
   
  JavaAttribute* annotationsAtt =
    compilingMethod->lookupAttribute(JavaAttribute::annotationsAttribute);
  
  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->removeAttributes(llvm::AttributeSet::FunctionIndex,
          llvm::AttributeSet::get(*llvmContext,
            llvm::AttributeSet::FunctionIndex, llvm::Attribute::NoInline));
        llvmFunction->addFnAttr(llvm::Attribute::AlwaysInline);
      } else if (name->equals(TheCompiler->NoInlinePragma)) {
        llvmFunction->addFnAttr(llvm::Attribute::NoInline);
      }
    }
  }
 
  return llvmFunction;
}

void JavaJIT::compareFP(Value* val1, Value* val2, 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) {
  JavaString* str = NULL;
  llvm_gcroot(str, 0);
  JavaConstantPool* ctpInfo = compilingClass->ctpInfo;
  uint8 type = ctpInfo->typeAt(index);
  
  if (type == JavaConstantPool::ConstantString) {
    if (TheCompiler->isStaticCompiling() && !TheCompiler->useCooperativeGC()) {
      const UTF8* utf8 = ctpInfo->UTF8At(ctpInfo->ctpDef[index]);
      str = *(compilingClass->classLoader->UTF8ToStr(utf8));
      Value* val = TheCompiler->getString(str);
      push(val, false, upcalls->newString);
    } else {
      JavaString** str = (JavaString**)ctpInfo->ctpRes[index];
      if ((str != NULL) && !TheCompiler->isStaticCompiling()) {
        Value* val = TheCompiler->getStringPtr(str);
        val = new LoadInst(val, "", currentBlock);
        push(val, false, upcalls->newString);
      } else {
        // Lookup the constant pool cache
        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);
      }
    }
  } 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()) {
    if (nbHandlers == 0 && vmkit::System::SupportsHardwareNullCheck()) {
      Value* indexes[2] = { intrinsics->constantZero, intrinsics->JavaObjectVTOffsetConstant };
      Value* VTPtr = GetElementPtrInst::Create(obj, indexes, "", currentBlock);
      Instruction* VT = new LoadInst(VTPtr, "", true, currentBlock);
      VT->setDebugLoc(DebugLoc::get(currentBytecodeIndex, 1, DbgSubprogram));
    } else {
      Value* test = new ICmpInst(*currentBlock, ICmpInst::ICMP_EQ, obj, intrinsics->JavaObjectNullConstant, "");

      BasicBlock* nullObjBlock = createBasicBlock("object is null");
      BasicBlock* notNullObjBlock = createBasicBlock("object is not null");

      BranchInst::Create(nullObjBlock, notNullObjBlock, test, currentBlock);
      currentBlock = nullObjBlock;
      throwRuntimeException(intrinsics->NullPointerExceptionFunction, 0, 0);
      currentBlock = notNullObjBlock;
    }
  } 
}

Value* JavaJIT::verifyAndComputePtr(Value* obj, Value* index,
                                    Type* arrayType, bool doNullCheck) {
  if (doNullCheck) {
    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 };
    throwRuntimeException(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, "", currentBlock);

  return ptr;

}

void JavaJIT::makeArgs(FunctionType::param_iterator it,
                       uint32 index, std::vector<Value*>& Args, uint32 nb) {
  Args.reserve(nb + 2);
  vmkit::ThreadAllocator threadAllocator;
  Value** args = (Value**)threadAllocator.Allocate(nb*sizeof(Value*));
  sint32 start = nb - 1;

  for (sint32 i = start; i >= 0; --i) {
    it--;
    if (*it == Type::getInt64Ty(*llvmContext)
        || *it == Type::getDoubleTy(*llvmContext)) {
      pop();
    }
    Value* tmp = pop();
    
    Type* type = *it;
    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]);
  }
}

Value* JavaJIT::getTarget(Signdef* signature) {
  int offset = 0;
  Typedef* const* arguments = signature->getArgumentsType();
  for (uint32 i = 0; i < signature->nbArguments; i++) {
    if (arguments[i]->isDouble() || arguments[i]->isLong()) {
      offset++;
    }
    offset++;
  }
  return objectStack[currentStackIndex - 1 - offset];
}

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, "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,
                                  "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::lowerFloatOps(const UTF8* name, 
                                    std::vector<Value*>& args) {
  JnjvmBootstrapLoader* loader = compilingClass->classLoader->bootstrapLoader;
  if (name->equals(loader->floatToRawIntBits)) {
    return new BitCastInst(args[0], Type::getInt32Ty(*llvmContext), "", currentBlock);
  } else if (name->equals(loader->intBitsToFloat)) {
    return new BitCastInst(args[0], Type::getFloatTy(*llvmContext), "", currentBlock);
  }
  return NULL;
}

Instruction* JavaJIT::lowerDoubleOps(const UTF8* name, 
                                    std::vector<Value*>& args) {
  JnjvmBootstrapLoader* loader = compilingClass->classLoader->bootstrapLoader;
  if (name->equals(loader->doubleToRawLongBits)) {
    return new BitCastInst(args[0], Type::getInt64Ty(*llvmContext), "", currentBlock);
  } else if (name->equals(loader->longBitsToDouble)) {
    return new BitCastInst(args[0], Type::getDoubleTy(*llvmContext), "", currentBlock);
  }
  return NULL;
}


Instruction* JavaJIT::invokeInline(JavaMethod* meth, 
                                   std::vector<Value*>& args,
                                   bool customized) {
  JavaJIT jit(TheCompiler, meth, llvmFunction, customized ? customizeFor : NULL);
  jit.unifiedUnreachable = unifiedUnreachable;
  jit.inlineMethods = inlineMethods;
  jit.inlineMethods[meth] = true;
  jit.inlining = true;
  jit.DbgSubprogram = DbgSubprogram;
#if DEBUG
  static int inlineNb = 0;
  fprintf(stderr, "inline compile %d %s.%s%s from %s.%s (%d)\n", inlineNb++,
              UTF8Buffer(meth->classDef->name).cString(),
              UTF8Buffer(meth->name).cString(),
              UTF8Buffer(meth->getSignature()->keyName).cString(),
              UTF8Buffer(compilingClass->name).cString(),
              UTF8Buffer(compilingMethod->name).cString(),
              customized);
#endif
  
  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);
  FunctionType* virtualType = LSI->getVirtualType();
  meth = ctpInfo->infoOfStaticOrSpecialMethod(index, ACC_VIRTUAL, signature);
  bool thisReference =
    isThisReference(stackSize() - signature->getNumberOfSlots() - 1);

  Value* func = 0;
  bool needsInit = false;
  if (TheCompiler->needsCallback(meth, NULL, &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 == NULL) {
        CallInst::Create(intrinsics->ForceLoadedCheckFunction, Cl, "",
                         currentBlock);
      }
    }
    func = TheCompiler->addCallback(compilingClass, index, signature, false,
                                    currentBlock);
  } else {
    func = TheCompiler->getMethod(meth, NULL);
  }

  std::vector<Value*> args;
  FunctionType::param_iterator it  = virtualType->param_end();
  makeArgs(it, index, args, signature->nbArguments + 1);
  if (!thisReference) JITVerifyNull(args[0]);
  
  if (meth == compilingClass->classLoader->bootstrapLoader->upcalls->InitObject) {
    return;
  }

  llvm::Instruction* val = 0;
  if (meth && canBeInlined(meth, false)) {
    val = invokeInline(meth, args, false);
  } else {
    val = invoke(func, args, "", currentBlock);
  }

  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* className = 0;
  ctpInfo->nameOfStaticOrSpecialMethod(index, className, name, signature);
  LLVMSignatureInfo* LSI = TheCompiler->getSignatureInfo(signature);
  FunctionType* staticType = LSI->getStaticType();
  ctpInfo->markAsStaticCall(index);
  JnjvmBootstrapLoader* loader = compilingClass->classLoader->bootstrapLoader;
  llvm::Instruction* val = 0;
  
  if (className->equals(loader->stackWalkerName)) {
    callsStackWalker = true;
  }

  JavaMethod* meth = ctpInfo->infoOfStaticOrSpecialMethod(index, ACC_STATIC,
                                                          signature);
    

  uint32 clIndex = ctpInfo->getClassIndexFromMethod(index);
  UserClass* cl = 0;
  Value* Cl = getResolvedClass(clIndex, true, true, &cl);
  if (!meth || (cl && needsInitialisationCheck(cl))) {
    CallInst::Create(intrinsics->ForceInitialisationCheckFunction, Cl, "",
                     currentBlock);
  }
  
  Value* func = 0;
  bool needsInit = false;
  if (TheCompiler->needsCallback(meth, NULL, &needsInit)) {
    func = TheCompiler->addCallback(compilingClass, index, signature,
                                    true, currentBlock);
  } else {
    func = TheCompiler->getMethod(meth, NULL);
  }

  std::vector<Value*> args; // size = [signature->nbIn + 2]; 
  FunctionType::param_iterator it  = staticType->param_end();
  makeArgs(it, index, args, signature->nbArguments);

  if (className->equals(loader->mathName)) {
    val = lowerMathOps(name, args);
  } else if (className->equals(loader->VMFloatName)) {
    val = lowerFloatOps(name, args);
  } else if (className->equals(loader->VMDoubleName)) {
    val = lowerDoubleOps(name, args);
  }
    
  if (val == NULL) {
    if (meth != NULL && canBeInlined(meth, false)) {
      val = invokeInline(meth, args, false);
    } else {
      val = invoke(func, args, "", currentBlock);
    }
  }

  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,
                                  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.
  JavaConstantPool* ctp = compilingClass->ctpInfo;
  Value* CTP = TheCompiler->getResolvedConstantPool(ctp);
  Value* Cl = TheCompiler->getNativeClass(compilingClass);

  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,
                           "", currentBlock);
  }
  
  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
    // only 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);
  } 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);
    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->VTAllocateFunction :
                           intrinsics->VTAllocateUnresolvedFunction,
                           Size, VT, "", currentBlock);

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

  // Make sure to add the object to the finalization list after it has been
  // pushed.
  if (cl && cl->virtualVT->hasDestructor()) {
    CallInst::Create(intrinsics->AddFinalizationCandidate, val, "", currentBlock);
  }
}

Value* JavaJIT::ldResolved(uint16 index, bool stat, Value* object, 
                           Type* fieldTypePtr, bool thisReference) {
  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);
    Type* type = NULL;
    if (stat) {
      type = LCI->getStaticType();
      Value* Cl = TheCompiler->getNativeClass(field->classDef);
      bool needsCheck = needsInitialisationCheck(field->classDef);
      if (needsCheck) {
        Cl = invoke(intrinsics->InitialisationCheckFunction, Cl, "",
                    currentBlock);
        CallInst::Create(intrinsics->ForceInitialisationCheckFunction, Cl, "",
                         currentBlock);
      }

      object = TheCompiler->getStaticInstance(field->classDef);
    } else {
      object = new LoadInst(
          object, "", false, currentBlock);
      if (!thisReference) JITVerifyNull(object);
      type = LCI->getVirtualType();
    }
    
    Value* objectConvert = new BitCastInst(object, type, "", currentBlock);

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

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

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

void JavaJIT::convertValue(Value*& val, Type* t1, BasicBlock* currentBlock,
                           bool usign) {
  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) {
  Typedef* sign = compilingClass->ctpInfo->infoOfField(index);
  LLVMAssessorInfo& LAI = TheCompiler->getTypedefInfo(sign);
  Type* type = LAI.llvmType;
   
  Value* ptr = ldResolved(index, true, NULL, LAI.llvmTypePtr);

  Value* val = pop(); 
  if (type == Type::getInt64Ty(*llvmContext) ||
      type == Type::getDoubleTy(*llvmContext)) {
    val = pop();
  }

  if (type != val->getType()) { // int1, int8, int16
    convertValue(val, type, currentBlock, false);
  }
  
  if (vmkit::Collector::needsNonHeapWriteBarrier() && type == intrinsics->JavaObjectType) {
    ptr = new BitCastInst(ptr, intrinsics->ptrPtrType, "", currentBlock);
    val = new BitCastInst(val, intrinsics->ptrType, "", currentBlock);
    Value* args[2] = { ptr, val };
    CallInst::Create(intrinsics->NonHeapWriteBarrierFunction, args, "", currentBlock);
  } else {
    new StoreInst(val, ptr, false, currentBlock);
  }
}

void JavaJIT::getStaticField(uint16 index) {
  JavaObject* val = 0;
  llvm_gcroot(val, 0);

  Typedef* sign = compilingClass->ctpInfo->infoOfField(index);
  LLVMAssessorInfo& LAI = TheCompiler->getTypedefInfo(sign);
  Type* type = LAI.llvmType;
  
  Value* ptr = ldResolved(index, true, NULL, LAI.llvmTypePtr);
  
  bool final = false;
  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) {
      if (sign->isPrimitive()) {
        const PrimitiveTypedef* prim = (PrimitiveTypedef*)sign;
        if (prim->isInt()) {
          sint32 val = field->getStaticInt32Field();
          push(ConstantInt::get(Type::getInt32Ty(*llvmContext), val), false);
        } else if (prim->isByte()) {
          sint8 val = (sint8)field->getStaticInt8Field();
          push(ConstantInt::get(Type::getInt8Ty(*llvmContext), val), false);
        } else if (prim->isBool()) {
          uint8 val = (uint8)field->getStaticInt8Field();
          push(ConstantInt::get(Type::getInt8Ty(*llvmContext), val), true);
        } else if (prim->isShort()) {
          sint16 val = (sint16)field->getStaticInt16Field();
          push(ConstantInt::get(Type::getInt16Ty(*llvmContext), val), false);
        } else if (prim->isChar()) {
          uint16 val = (uint16)field->getStaticInt16Field();
          push(ConstantInt::get(Type::getInt16Ty(*llvmContext), val), true);
        } else if (prim->isLong()) {
          sint64 val = (sint64)field->getStaticLongField();
          push(ConstantInt::get(Type::getInt64Ty(*llvmContext), val), false);
        } else if (prim->isFloat()) {
          float val = (float)field->getStaticFloatField();
          push(ConstantFP::get(Type::getFloatTy(*llvmContext), val), false);
        } else if (prim->isDouble()) {
          double val = (double)field->getStaticDoubleField();
          push(ConstantFP::get(Type::getDoubleTy(*llvmContext), val), false);
        } else {
          abort();
        }
      } else {
        if (TheCompiler->isStaticCompiling() && !TheCompiler->useCooperativeGC()) {
          val = field->getStaticObjectField();
          JnjvmClassLoader* JCL = field->classDef->classLoader;
          Value* V = TheCompiler->getFinalObject(val, sign->assocClass(JCL));
          CommonClass* cl = vmkit::Collector::begOf(val) ?
              JavaObject::getClass(val) : NULL;
          push(V, false, cl);
        } else {
          // Do not call getFinalObject, as the object may move in-between two
          // loads of this static.
          Value* V = new LoadInst(ptr, "", currentBlock);
          JnjvmClassLoader* JCL = compilingClass->classLoader;
          push(V, false, sign->findAssocClass(JCL));
        } 
      }
    }
  }

  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) {
  Typedef* sign = compilingClass->ctpInfo->infoOfField(index);
  LLVMAssessorInfo& LAI = TheCompiler->getTypedefInfo(sign);
  Type* type = LAI.llvmType;
  int stackIndex = currentStackIndex - 2;
  if (type == Type::getInt64Ty(*llvmContext) ||
      type == Type::getDoubleTy(*llvmContext)) {
    stackIndex--;
  }
  Value* object = objectStack[stackIndex];
  bool thisReference = isThisReference(stackIndex);
  Value* ptr = ldResolved(index, false, object, LAI.llvmTypePtr, thisReference);

  Value* val = pop();
  if (type == Type::getInt64Ty(*llvmContext) ||
      type == Type::getDoubleTy(*llvmContext)) {
    val = pop();
  }
  pop(); // Pop the object
  
  if (type != val->getType()) { // int1, int8, int16
    convertValue(val, type, currentBlock, false);
  }
  
  if (vmkit::Collector::needsWriteBarrier() && type == intrinsics->JavaObjectType) {
    ptr = new BitCastInst(ptr, intrinsics->ptrPtrType, "", currentBlock);
    val = new BitCastInst(val, intrinsics->ptrType, "", currentBlock);
    object = new LoadInst(object, "", false, currentBlock);
    object = new BitCastInst(object, intrinsics->ptrType, "", currentBlock);
    Value* args[3] = { object, ptr, val };
    CallInst::Create(intrinsics->FieldWriteBarrierFunction, args, "", currentBlock);
  } else {
    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);
  Type* type = LAI.llvmType;
  Value* obj = objectStack[currentStackIndex - 1];
  bool thisReference = isThisReference(currentStackIndex - 1);
  pop(); // Pop the object
  
  Value* ptr = ldResolved(index, false, obj, LAI.llvmTypePtr, thisReference);
  
  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) && sign->isPrimitive();
    }
    if (final) {
      Function* F = 0;
      assert(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();
      }
      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) {
  
  // Do the usual
  JavaConstantPool* ctpInfo = compilingClass->ctpInfo;
  const UTF8* name = 0;
  Signdef* signature = ctpInfo->infoOfInterfaceOrVirtualMethod(index, name);
  bool thisReference =
    isThisReference(stackSize() - signature->getNumberOfSlots() - 1);
  
  LLVMSignatureInfo* LSI = TheCompiler->getSignatureInfo(signature);
  FunctionType* virtualType = LSI->getVirtualType();
  PointerType* virtualPtrType = LSI->getVirtualPtrType();
 
  Type* retType = virtualType->getReturnType();
   
  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);
  }

  uint32_t tableIndex = InterfaceMethodTable::getIndex(name, signature->keyName);
  Constant* Index = ConstantInt::get(Type::getInt32Ty(*llvmContext),
                                     tableIndex);
  Value* targetObject = getTarget(signature);
  targetObject = new LoadInst(
          targetObject, "", false, currentBlock);
  if (!thisReference) JITVerifyNull(targetObject);
  // TODO: The following code needs more testing.
#if 0
  BasicBlock* endBlock = createBasicBlock("end interface invoke");
  PHINode * node = PHINode::Create(virtualPtrType, "", endBlock);

  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, targetObject, "",
                               currentBlock);
  Value* IMT = CallInst::Create(intrinsics->GetIMTFunction, VT, "",
                                currentBlock);


  Value* indices[2] = { intrinsics->constantZero, Index };
  Instruction* ptr_18 = GetElementPtrInst::Create(IMT, indices, "",
                                                  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);
  
  node->addIncoming(ptr_22, 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);
  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, 2, "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);
  node->addIncoming(ptr_33, 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;
#else
  std::vector<Value*> Args;
  Args.push_back(targetObject);
  Args.push_back(Meth);
  Args.push_back(Index);
  Value* node = invoke(intrinsics->ResolveInterfaceFunction,
                       Args, "invokeinterface", currentBlock);
  node = new BitCastInst(node, virtualPtrType, "", currentBlock);
#endif

  std::vector<Value*> args; // size = [signature->nbIn + 3];
  FunctionType::param_iterator it  = virtualType->param_end();
  makeArgs(it, index, args, signature->nbArguments + 1);
  Value* ret = invoke(node, args, "", currentBlock);
  if (retType != Type::getVoidTy(*llvmContext)) {
    if (ret->getType() == intrinsics->JavaObjectType) {
      JnjvmClassLoader* JCL = compilingClass->classLoader;
      push(ret, false, signature->getReturnType()->findAssocClass(JCL));
    } else {
      push(ret, signature->getReturnType()->isUnsigned());
      if (retType == Type::getDoubleTy(*llvmContext) ||
          retType == Type::getInt64Ty(*llvmContext)) {
        push(intrinsics->constantZero, false);
      }
    }
  }
}

DebugLoc JavaJIT::CreateLocation() {
  DebugLoc DL = DebugLoc::get(currentBytecodeIndex, 0, DbgSubprogram);
  return DL;
}

Instruction* JavaJIT::invoke(Value *F, std::vector<llvm::Value*>& args,
                       const char* Name,
                       BasicBlock *InsertAtEnd) {
  assert(!inlining);
 
  BasicBlock* ifException = NULL;
  if (jmpBuffer != NULL) {
    BasicBlock* doCall = createBasicBlock("Perform call");
    ifException = createBasicBlock("Exception thrown");
    Instruction* check = CallInst::Create(intrinsics->SetjmpFunction, jmpBuffer, "", currentBlock);
    check = new ICmpInst(*currentBlock, ICmpInst::ICMP_EQ, check, intrinsics->constantZero, "");
    BranchInst::Create(doCall, ifException, check, currentBlock);
    currentBlock = doCall;
    CallInst::Create(intrinsics->RegisterSetjmpFunction, jmpBuffer, "", currentBlock);
  }

  Instruction* res = CallInst::Create(F, args, Name,  currentBlock);
  DebugLoc DL = CreateLocation();
  res->setDebugLoc(DL);
  
  if (jmpBuffer != NULL) {
    CallInst::Create(intrinsics->UnregisterSetjmpFunction, jmpBuffer, "", currentBlock);
    BasicBlock* ifNormal = createBasicBlock("no exception block");
    BranchInst::Create(ifNormal, currentBlock);

    currentBlock = ifException;
    CallInst::Create(intrinsics->UnregisterSetjmpFunction, jmpBuffer, "", currentBlock);
    BranchInst::Create(currentExceptionBlock, currentBlock);
    currentBlock = ifNormal; 
  }

  return res;
}

Instruction* JavaJIT::invoke(Value *F, Value* arg1, const char* Name,
                       BasicBlock *InsertAtEnd) {
  std::vector<Value*> args;
  args.push_back(arg1);
  return invoke(F, args, Name, InsertAtEnd);
}

Instruction* JavaJIT::invoke(Value *F, Value* arg1, Value* arg2,
                       const char* Name, BasicBlock *InsertAtEnd) {
  std::vector<Value*> args;
  args.push_back(arg1);
  args.push_back(arg2);
  return invoke(F, args, Name, InsertAtEnd);
}

Instruction* JavaJIT::invoke(Value *F, const char* Name,
                       BasicBlock *InsertAtEnd) {
  std::vector<Value*> args;
  return invoke(F, args, Name, InsertAtEnd);
}

void JavaJIT::throwException(Value* obj, bool checkNull) {
  if (checkNull) JITVerifyNull(obj);
  if (nbHandlers == 0) {
    CallInst::Create(intrinsics->ThrowExceptionFunction, obj, "", currentBlock);
    new UnreachableInst(*llvmContext, currentBlock);
  } else {
    Value* javaExceptionPtr = getJavaExceptionPtr(getJavaThreadPtr(getMutatorThreadPtr()));
    if (vmkit::Collector::needsNonHeapWriteBarrier()) {
      Instruction* ptr = new BitCastInst(javaExceptionPtr, intrinsics->ptrPtrType, "", currentBlock);
      Instruction* val = new BitCastInst(obj, intrinsics->ptrType, "", currentBlock);
      Value* args[2] = { ptr, val };
      CallInst::Create(intrinsics->NonHeapWriteBarrierFunction, args, "", currentBlock);
    } else {
      new StoreInst(obj, javaExceptionPtr, currentBlock);
    }

    BranchInst::Create(currentExceptionBlock, currentBlock);
  }
}

void JavaJIT::throwRuntimeException(llvm::Function* F, Value* arg1) {
  Value* args[1] = { arg1 };
  throwRuntimeException(F, args, 1);
}

void JavaJIT::throwRuntimeException(llvm::Function* F, Value** args, uint32 nbArgs) {
  Instruction* obj = CallInst::Create(F, ArrayRef<Value*>(args, nbArgs), "exceptionObject", currentBlock);
  DebugLoc DL = CreateLocation();
  obj->setDebugLoc(DL);
  throwException(obj, false);
}

/// Handler - This class represents an exception handler. It is only needed
/// when parsing the .class file in the JIT, therefore it is only defined
/// here. The readExceptionTable function is the only function that makes
/// use of this class.
struct Handler {
  
  /// startpc - The bytecode number that begins the try clause.
  uint32 startpc;

  /// endpc - The bytecode number that ends the try clause.
  uint32 endpc;

  /// handlerpc - The bytecode number where the handler code starts.
  uint32 handlerpc;

  /// catche - Index in the constant pool of the exception class.
  uint16 catche;

  /// catchClass - The class of the exception: it must always be loaded before
  /// reading the exception table so that we do not throw an exception
  /// when compiling.
  UserClass* catchClass;

  /// tester - The basic block that tests if the exception is handled by this
  /// handler. If the handler is not the first of a list of handlers with the
  /// same range, than this block is the catcher block. Otherwise, it is the
  /// destination of the catcher block and of the handlers that do not handler
  /// the exception.
  llvm::BasicBlock* tester;

  /// javaHandler - The Java code that handles the exception. At this point, we
  /// know we have caught and are handling the exception. The Java exception
  /// object is the PHI node that begins this block.
  llvm::BasicBlock* javaHandler;

};

unsigned JavaJIT::readExceptionTable(Reader& reader, uint32 codeLen) {

  // This function uses currentBlock to simplify things. We save the current
  // value of currentBlock to restore it at the end of the function
  BasicBlock* temp = currentBlock;
  
  sint16 nbe = reader.readU2();
  sint16 sync = isSynchro(compilingMethod->access) ? 1 : 0;
  nbe += sync;
 
  vmkit::ThreadAllocator allocator;
  // Loop over all handlers in the bytecode to initialize their values.
  Handler* handlers =
      (Handler*)allocator.Allocate(sizeof(Handler) * (nbe - sync));
  for (uint16 i = 0; i < nbe - sync; ++i) {
    Handler* ex   = &handlers[i];
    ex->startpc   = reader.readU2();
    ex->endpc     = reader.readU2();
    ex->handlerpc = reader.readU2();

    opcodeInfos[ex->handlerpc].isReachable = true;

    ex->catche = reader.readU2();

    if (ex->catche) {
      UserClass* cl = 
        (UserClass*)(compilingClass->ctpInfo->isClassLoaded(ex->catche));
      // When loading the class, we made sure that all exception classes
      // were loaded, so cl must have a value.
      assert(cl && "exception class has not been loaded");
      ex->catchClass = cl;
    } else {
      ex->catchClass = Classpath::newThrowable;
    }
    
    ex->tester = createBasicBlock("testException");
    
    // Set the unwind destination of the instructions in the range of this
    // handler to the test block of the handler. If an instruction already has
    // a handler and thus is not the synchronize or regular end handler block,
    // leave it as-is.
    for (uint16 i = ex->startpc; i < ex->endpc; ++i) {
      if (opcodeInfos[i].exceptionBlock == endExceptionBlock) {
        opcodeInfos[i].exceptionBlock = ex->tester;
        //opcodeInfos[i].handlerPC = ex->handlerpc;
      }
    }

    // If the handler pc does not already have a block, create a new one.
    if (!(opcodeInfos[ex->handlerpc].newBlock)) {
      opcodeInfos[ex->handlerpc].newBlock = createBasicBlock("javaHandler");
    }
    
    // Set the Java handler for this exception.
    ex->javaHandler = opcodeInfos[ex->handlerpc].newBlock;
    opcodeInfos[ex->handlerpc].handler = true;
  }

  // Loop over all handlers to implement their tester.
  for (sint16 i = 0; i < nbe - sync; ++i) {
    Handler* cur = &handlers[i];
    BasicBlock* bbNext = 0;
    currentExceptionBlock = opcodeInfos[cur->handlerpc].exceptionBlock;

    // Look out where we go if we're not the handler for the exception.
    if (i + 1 != nbe - sync) {
      Handler* next = &handlers[i + 1];
      if (!(cur->startpc >= next->startpc && cur->endpc <= next->endpc)) {
        // If there is no handler to go to (either one that has the same range
        // or one that contains the range), then we jump to the end handler.
        bbNext = endExceptionBlock;
      } else {
        // If there's a handler to goto, we jump to its tester block and record
        // the exception PHI node to give our exception to the tester.
        bbNext = next->tester;
      }
    } else {
      // If there's no handler after us, we jump to the end handler.
      bbNext = endExceptionBlock;
    }

    currentBlock = cur->tester;
    
    assert(cur->catchClass && 
           "Class not loaded when reading the exception table");

    Value* VTVar = TheCompiler->getVirtualTable(cur->catchClass->virtualVT);

    // Get the Java exception.
    Value* javaExceptionPtr = getJavaExceptionPtr(getJavaThreadPtr(getMutatorThreadPtr()));
    Value* obj = new LoadInst(javaExceptionPtr, "pendingException", currentBlock);
    
    Value* objVT = CallInst::Create(intrinsics->GetVTFunction, obj, "objectVT",
                                    currentBlock);

    uint32 depth = cur->catchClass->virtualVT->depth;
    Value* depthCl = ConstantInt::get(Type::getInt32Ty(*llvmContext), depth);
    Value* cmp = 0;

    if (depth >= JavaVirtualTable::getDisplayLength()) {
      Value* classArgs[2] = { objVT, VTVar };

      if (TheCompiler->isStaticCompiling())
    	  cmp = CallInst::Create(intrinsics->IsSecondaryClassFunction,
                             classArgs, "isSecondaryClass", currentBlock);
      else
    	  cmp = CallInst::Create(intrinsics->IsSecondaryClassFunctionInner,
    	                               classArgs, "isSecondaryClass", currentBlock);

    } else {
     
      Value* inDisplay = CallInst::Create(intrinsics->GetDisplayFunction,
                                          objVT, "objectDisplay", currentBlock);
            
      Value* displayArgs[2] = { inDisplay, depthCl };
      Value* VTInDisplay = CallInst::Create(intrinsics->GetVTInDisplayFunction,
                                            displayArgs, "objectVTInDisplay", currentBlock);
             
      cmp = new ICmpInst(*currentBlock, ICmpInst::ICMP_EQ, VTInDisplay, VTVar,
                         "");
    }
   
    // If we are catching this exception, then jump to the Java Handler,
    // otherwise jump to our next handler.
    BranchInst::Create(cur->javaHandler, bbNext, cmp, currentBlock);

    currentBlock = cur->javaHandler;
  }
 
  // Restore currentBlock.
  currentBlock = temp;
  return nbe;
}

void JavaJIT::finishExceptions() {
  pred_iterator PI = pred_begin(endExceptionBlock);
  pred_iterator PE = pred_end(endExceptionBlock);
  if (PI == PE) {
    endExceptionBlock->eraseFromParent();
  } else {
    if (endNode) {
      endNode->addIncoming(Constant::getNullValue(endNode->getType()),
                           endExceptionBlock);
    }
    BranchInst::Create(endBlock, endExceptionBlock);
  }
 

  PI = pred_begin(unifiedUnreachable);
  PE = pred_end(unifiedUnreachable);
  if (PI == PE) {
    unifiedUnreachable->eraseFromParent();
  } else {
    new UnreachableInst(*llvmContext, unifiedUnreachable);
  }
  
  for (Function::iterator BI = llvmFunction->begin(), BE = llvmFunction->end();
       BI != BE; BI++) {
    PI = pred_begin(BI);
    PE = pred_end(BI);
    if (PI == PE) {
      Instruction* insn = BI->begin();
      PHINode* node = dyn_cast<PHINode>(insn);
      if (node) {
        node->replaceAllUsesWith(Constant::getNullValue(node->getType()));
        node->eraseFromParent();
      }
    }
  }
}


#ifdef USE_OPENJDK
#include "JavaJITOpenJDK.inc"
#else
#include "JavaJITClasspath.inc"
#endif
