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


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

#include <cstring>

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

#include "mvm/JIT.h"

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

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

using namespace j3;
using namespace llvm;

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

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

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

  return true;
#endif
}

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

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

  // If the method is in fact a method defined in an interface,
  // call invokeInterface instead.
  if (meth && isInterface(meth->classDef->access)) {
    return invokeInterface(index, true);
  }
 
  const UTF8* name = 0;
  Signdef* signature = ctpInfo->infoOfInterfaceOrVirtualMethod(index, name);

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

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

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

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

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

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

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

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

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

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

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

  return threadId;
}

extern "C" void j3ThrowExceptionFromJIT();

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

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

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


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

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

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

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

  nativeArgs.push_back(jniEnv);

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

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

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

      currentBlock = NotZero;

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

      currentBlock = BB;

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

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

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

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

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

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

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

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

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


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

  CallInst::Create(intrinsics->EndJNIFunction, Args2, Args2 + 1, "", currentBlock);
  
  // Synchronize after leaving native.
  if (isSynchro(compilingMethod->access))
    endSynchronize();
  
  if (returnType != Type::getVoidTy(*llvmContext))
    ReturnInst::Create(*llvmContext, endNode, currentBlock);
  else
    ReturnInst::Create(*llvmContext, currentBlock);
  
  PRINT_DEBUG(JNJVM_COMPILE, 1, COLOR_NORMAL, "end native compile %s.%s\n",
              UTF8Buffer(compilingClass->name).cString(),
              UTF8Buffer(compilingMethod->name).cString());
  
 
  return llvmFunction;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

  currentBlock = OverflowCounterBB;

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

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

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

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

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

  currentBlock = FatLockBB;

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



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

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

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

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


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

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

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

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

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

  currentBlock = curBB;
  endExceptionBlock = endExBlock;

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

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

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

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

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

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

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

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

  curBB = endBlock;


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


  delete[] opcodeInfos;
  return endNode;
    
}

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

  DbgSubprogram = TheCompiler->GetDbgSubprogram(compilingMethod);

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

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

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

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

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

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

  

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

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

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

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

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

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

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

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

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

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

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

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

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

    stackCheck = new ICmpInst(*currentBlock, ICmpInst::ICMP_EQ, stackCheck,
                              intrinsics->constantPtrZero, "");
    BasicBlock* stackOverflow = createBasicBlock("stack overflow");
    BasicBlock* noStackOverflow = createBasicBlock("no stack overflow");
    BranchInst::Create(stackOverflow, noStackOverflow, stackCheck,
                       currentBlock);
    currentBlock = stackOverflow;
    throwException(intrinsics->StackOverflowErrorFunction, 0, 0);
    currentBlock = noStackOverflow;
  }
  
  if (TheCompiler->useCooperativeGC()) {
    Value* threadId = getCurrentThread(intrinsics->MutatorThreadType);
    
    Value* GEP[2] = { intrinsics->constantZero, 
                      intrinsics->OffsetDoYieldInThreadConstant };
    
    Value* YieldPtr = GetElementPtrInst::Create(threadId, GEP, GEP + 2, "",
                                                currentBlock);

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

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

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

    currentBlock = continueBlock;
  }

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

  }
  currentBlock = endBlock;

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

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

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

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

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

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

  currentBlock = endExceptionBlock;

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

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

  return llvmFunction;
}

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

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

  push(r, false);

}

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

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

void JavaJIT::JITVerifyNull(Value* obj) {

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

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

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

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

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

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

  return ptr;

}

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

  }

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

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

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

}


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

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

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

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

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

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

}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

  JITVerifyNull(ptr_src);
  JITVerifyNull(ptr_dst);

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

  currentBlock = label_return;
}

MDNode* JavaJIT::CreateLocation() {
  uint32_t first = currentLineNumber | (currentBytecodeIndex << 16);
  uint32_t second = currentCtpIndex | (callNumber << 16);
  DILocation Location = TheCompiler->getDebugFactory()->CreateLocation(
      first, second, DIScope(DbgSubprogram));
  callNumber++;
  return Location.getNode();
}

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