//===-------- LLVMMaterializer.cpp - LLVM Materializer for J3 -------------===//
//
//                            The VMKit project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/Constants.h"
#include "llvm/Module.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"

#include "mvm/JIT.h"

#include "JavaAccess.h"
#include "JavaClass.h"
#include "JavaConstantPool.h"
#include "JavaThread.h"
#include "JavaTypes.h"
#include "Jnjvm.h"

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

using namespace llvm;
using namespace j3;


JavaLLVMLazyJITCompiler::JavaLLVMLazyJITCompiler(const std::string& ModuleID)
    : JavaJITCompiler(ModuleID) {
  TheMaterializer = new LLVMMaterializer(TheModule, this);      
}

JavaLLVMLazyJITCompiler::~JavaLLVMLazyJITCompiler() {
  // The module already destroys the materializer.
}

void* JavaLLVMLazyJITCompiler::loadMethod(void* handle, const char* symbol) {
  Function* F = mvm::MvmModule::globalModule->getFunction(symbol);
  if (F) {
    void* res = mvm::MvmModule::executionEngine->getPointerToFunctionOrStub(F);
    return res;
  }

  return JavaCompiler::loadMethod(handle, symbol);
}

uintptr_t JavaLLVMLazyJITCompiler::getPointerOrStub(JavaMethod& meth,
                                                    int side) {
  ExecutionEngine* EE = mvm::MvmModule::executionEngine;
  LLVMMethodInfo* LMI = getMethodInfo(&meth);
  Function* func = LMI->getMethod();
  return (uintptr_t)EE->getPointerToFunctionOrStub(func);
}

static JavaMethod* staticLookup(CallbackInfo& F) {
  Class* caller = F.cl;
  uint16 index = F.index; 
  bool isStatic = F.stat;
  JavaConstantPool* ctpInfo = caller->getConstantPool();

  CommonClass* cl = 0;
  const UTF8* utf8 = 0;
  Signdef* sign = 0;

  ctpInfo->resolveMethod(index, cl, utf8, sign);
  UserClass* lookup = cl->isArray() ? cl->super : cl->asClass();
  JavaMethod* meth = lookup->lookupMethod(utf8, sign->keyName, isStatic, true,
                                          0);

  assert(lookup->isInitializing() && "Class not ready");
 
  return meth;
}


Value* JavaLLVMLazyJITCompiler::addCallback(Class* cl, uint16 index,
                                            Signdef* sign, bool stat,
                                            BasicBlock* insert) {
  
  Function* F = 0;
  LLVMSignatureInfo* LSI = getSignatureInfo(sign);
  
  const UTF8* name = cl->name;
  char* key = (char*)alloca(name->size + 16);
  for (sint32 i = 0; i < name->size; ++i)
    key[i] = name->elements[i];
  sprintf(key + name->size, "%d", index);
  F = TheModule->getFunction(key);
  if (F) return F;
  
  const FunctionType* type = stat ? LSI->getStaticType() : 
                                    LSI->getVirtualType();
  
  F = Function::Create(type, GlobalValue::ExternalWeakLinkage, key, TheModule);
  
  CallbackInfo A(cl, index, stat);
  callbacks.insert(std::make_pair(F, A));
  
  return F;
}


bool LLVMMaterializer::Materialize(GlobalValue *GV, std::string *ErrInfo) {
  
  Function* F = dyn_cast<Function>(GV);
  assert(F && "Not a function");
  if (F->getLinkage() == GlobalValue::ExternalLinkage) return false;

  // The caller of materializeFunction *must* always hold the JIT lock.
  // Because we are materializing a function here, we must release the
  // JIT lock and get the global vmkit lock to be thread-safe.
  // This prevents jitting the function while someone else is doing it.
  mvm::MvmModule::executionEngine->lock.release(); 
  mvm::MvmModule::protectIR();

  // Don't use hasNotBeenReadFromBitcode: materializeFunction is called
  // by the pass manager, and we don't want another thread to JIT the
  // function while all passes have not been run.
  if (!(F->isDeclaration())) {
    mvm::MvmModule::unprotectIR(); 
    // Reacquire and go back to the JIT function.
    mvm::MvmModule::executionEngine->lock.acquire();
    return false;
  }

  if (mvm::MvmModule::executionEngine->getPointerToGlobalIfAvailable(F)) {
    mvm::MvmModule::unprotectIR(); 
    // Reacquire and go back to the JIT function.
    mvm::MvmModule::executionEngine->lock.acquire();
    return false;
  }
  
  JavaMethod* meth = Comp->getJavaMethod(F);
  
  if (!meth) {
    // It's a callback
    JavaLLVMLazyJITCompiler::callback_iterator I = Comp->callbacks.find(F);
    assert(I != Comp->callbacks.end() && "No callbacks found");
    meth = staticLookup(I->second);
  }
  
  void* val = meth->compiledPtr();

  if (isVirtual(meth->access)) {
    LLVMMethodInfo* LMI = Comp->getMethodInfo(meth);
    uint64_t offset = dyn_cast<ConstantInt>(LMI->getOffset())->getZExtValue();
    assert(meth->classDef->isResolved() && "Class not resolved");
#if !defined(ISOLATE_SHARING) && !defined(SERVICE)
    assert(meth->classDef->isInitializing() && "Class not ready");
#endif
    assert(meth->classDef->virtualVT && "Class has no VT");
    assert(meth->classDef->virtualTableSize > offset && 
        "The method's offset is greater than the virtual table size");
    ((void**)meth->classDef->virtualVT)[offset] = val;
  } else {
    assert(meth->classDef->isInitializing() && "Class not ready");
  }

  mvm::MvmModule::unprotectIR();
  
  // Reacquire to go back to the JIT function.
  mvm::MvmModule::executionEngine->lock.acquire();
  
  if (F->isDeclaration())
    mvm::MvmModule::executionEngine->updateGlobalMapping(F, val);
  
  return false;
}

bool LLVMMaterializer::isMaterializable(const llvm::GlobalValue* GV) const {
  return GV->getLinkage() == GlobalValue::ExternalWeakLinkage;
}


LLVMMaterializer::LLVMMaterializer(
    llvm::Module* m, JavaLLVMLazyJITCompiler* C) {
  Comp = C;
  TheModule = m;
  m->setMaterializer(this);
}
