//===--------- VirtualMachine.h - Registering a VM ------------------------===//
//
//                            The VMKit project
//
// This file is distributed under the University of Pierre et Marie Curie 
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Ultimately, this would be like a generic way of defining a VM. But we're not
// quite there yet.
//
//===----------------------------------------------------------------------===//

#ifndef MVM_VIRTUALMACHINE_H
#define MVM_VIRTUALMACHINE_H

#include "mvm/Allocator.h"
#include "mvm/MethodInfo.h"
#include "mvm/Threads/CollectionRV.h"
#include "mvm/Threads/Cond.h"
#include "mvm/Threads/Locks.h"
#include "mvm/GC/GC.h"

#include <cassert>
#include <map>

namespace jnjvm {
  class JavaCompiler;
  class JnjvmClassLoader;
}

class gc;

namespace mvm {

class FunctionMap {
public:
  /// Functions - Map of applicative methods to function pointers. This map is
  /// used when walking the stack so that VMKit knows which applicative method
  /// is executing on the stack.
  ///
  std::map<void*, MethodInfo*> Functions;

  /// FunctionMapLock - Spin lock to protect the Functions map.
  ///
  mvm::SpinLock FunctionMapLock;
};

/// StartEndFunctionMap - This map is for functions for which we have
/// a start and end address.
///
class StartEndFunctionMap : public FunctionMap {
public:
  /// addMethodInFunctionMap - A new method pointer in the function map.
  ///
  void addMethodInfo(MethodInfo* meth, void* start, void* end) {
    FunctionMapLock.acquire();
    Functions.insert(std::make_pair(start, meth));
    Functions.insert(std::make_pair(end, meth));
    FunctionMapLock.release();
  }
  
  /// IPToMethodInfo - Map an instruction pointer to the MethodInfo.
  ///
  MethodInfo* IPToMethodInfo(void* ip) {
    FunctionMapLock.acquire();
    std::map<void*, MethodInfo*>::iterator I = Functions.upper_bound(ip);
    MethodInfo* res = 0;
    if (I != Functions.end() && I != Functions.begin()) {
      res = I->second;
      if ((--I)->second != res) res = 0;
    }
    FunctionMapLock.release();
    return res;
  }
};

/// StartFunctionMap - This map is for static functions where getting an end
/// address is cumbersome.
///
class StartFunctionMap : public FunctionMap {
public: 
  /// addMethodInFunctionMap - A new method pointer in the function map.
  ///
  void addMethodInfo(MethodInfo* meth, void* addr) {
    FunctionMapLock.acquire();
    Functions.insert(std::make_pair((void*)addr, meth));
    FunctionMapLock.release();
  }
  
  /// IPToMethodInfo - Map an instruction pointer to the MethodInfo.
  ///
  MethodInfo* IPToMethodInfo(void* ip);
 
};

class SharedStartFunctionMap : public StartFunctionMap {
public: 
  BumpPtrAllocator* StaticAllocator;
  bool initialized;
  SharedStartFunctionMap() {
    initialized = false;
  }

  void initialize();
};



// Same values than JikesRVM
#define INITIAL_QUEUE_SIZE 256
#define GROW_FACTOR 2

class CompilationUnit;
class VirtualMachine;

class ReferenceQueue {
private:
  gc** References;
  uint32 QueueLength;
  uint32 CurrentIndex;
  mvm::SpinLock QueueLock;
  uint8_t semantics;

  gc* processReference(gc*, VirtualMachine*);
public:

  static const uint8_t WEAK = 1;
  static const uint8_t SOFT = 2;
  static const uint8_t PHANTOM = 3;



  ReferenceQueue(uint8_t s) {
    References = new gc*[INITIAL_QUEUE_SIZE];
    QueueLength = INITIAL_QUEUE_SIZE;
    CurrentIndex = 0;
    semantics = s;
  }
 
  void addReference(gc* ref) {
    QueueLock.acquire();
    if (CurrentIndex >= QueueLength) {
      uint32 newLength = QueueLength * GROW_FACTOR;
      gc** newQueue = new gc*[newLength];
      if (!newQueue) {
        fprintf(stderr, "I don't know how to handle reference overflow yet!\n");
        abort();
      }
      for (uint32 i = 0; i < QueueLength; ++i) newQueue[i] = References[i];
      delete[] References;
      References = newQueue;
      QueueLength = newLength;
    }
    References[CurrentIndex++] = ref;
    QueueLock.release();
  }
  
  void acquire() {
    QueueLock.acquire();
  }

  void release() {
    QueueLock.release();
  }

  void scan(VirtualMachine* vm);
};


/// VirtualMachine - This class is the root of virtual machine classes. It
/// defines what a VM should be.
///
class VirtualMachine : public mvm::PermanentObject {
  friend class ReferenceQueue;

protected:

  VirtualMachine(mvm::BumpPtrAllocator &Alloc) :
		allocator(Alloc),
    WeakReferencesQueue(ReferenceQueue::WEAK),
    SoftReferencesQueue(ReferenceQueue::SOFT), 
    PhantomReferencesQueue(ReferenceQueue::PHANTOM) {
#ifdef SERVICE
    memoryLimit = ~0;
    executionLimit = ~0;
    GCLimit = ~0;
    threadLimit = ~0;
    parent = this;
    status = 1;
    _since_last_collection = 4*1024*1024;
#endif
    FinalizationQueue = new gc*[INITIAL_QUEUE_SIZE];
    QueueLength = INITIAL_QUEUE_SIZE;
    CurrentIndex = 0;

    ToBeFinalized = new gc*[INITIAL_QUEUE_SIZE];
    ToBeFinalizedLength = INITIAL_QUEUE_SIZE;
    CurrentFinalizedIndex = 0;
    
    ToEnqueue = new gc*[INITIAL_QUEUE_SIZE];
    ToEnqueueLength = INITIAL_QUEUE_SIZE;
    ToEnqueueIndex = 0;
    
    mainThread = 0;
    NumberOfThreads = 0;
    if (!SharedStaticFunctions.initialized) SharedStaticFunctions.initialize();
  }
public:

  /// allocator - Bump pointer allocator to allocate permanent memory
  /// related to this VM.
  ///
  mvm::BumpPtrAllocator& allocator;

  /// mainThread - The main thread of this VM.
  ///
  mvm::Thread* mainThread;

  /// NumberOfThreads - The number of threads that currently run under this VM.
  ///
  uint32_t NumberOfThreads;

  /// ThreadLock - Lock to create or destroy a new thread.
  ///
  mvm::SpinLock ThreadLock;
  
  /// setMainThread - Set the main thread of this VM.
  ///
  void setMainThread(mvm::Thread* th) { mainThread = th; }
  
  /// getMainThread - Get the main thread of this VM.
  ///
  mvm::Thread* getMainThread() const { return mainThread; }

  /// addThread - Add a new thread to the list of threads.
  ///
  void addThread(mvm::Thread* th) {
    ThreadLock.lock();
    NumberOfThreads++;
    if (th != mainThread) {
      if (mainThread) th->append(mainThread);
      else mainThread = th;
    }
    ThreadLock.unlock();
  }
  
  /// removeThread - Remove the thread from the list of threads.
  ///
  void removeThread(mvm::Thread* th) {
    ThreadLock.lock();
    NumberOfThreads--;
    if (mainThread == th) mainThread = (Thread*)th->next();
    th->remove();
    if (!NumberOfThreads) mainThread = 0;
    ThreadLock.unlock();
  }


  virtual void tracer();

  virtual ~VirtualMachine() {}

  /// runApplication - Run an application. The application name is in
  /// the arguments, hence it is the virtual machine's job to parse them.
  virtual void runApplication(int argc, char** argv) = 0;
  
  /// waitForExit - Wait until the virtual machine stops its execution.
  virtual void waitForExit() = 0;

  static jnjvm::JnjvmClassLoader* initialiseJVM(jnjvm::JavaCompiler* C,
                                                bool dlLoad = true);
  static VirtualMachine* createJVM(jnjvm::JnjvmClassLoader* C = 0);
  
  static CompilationUnit* initialiseCLIVM();
  static VirtualMachine* createCLIVM(CompilationUnit* C = 0);

private:
  /// WeakReferencesQueue - The queue of weak references.
  ///
  ReferenceQueue WeakReferencesQueue;

  /// SoftReferencesQueue - The queue of soft references.
  ///
  ReferenceQueue SoftReferencesQueue;

  /// PhantomReferencesQueue - The queue of phantom references.
  ///
  ReferenceQueue PhantomReferencesQueue;

  
  /// FinalizationQueueLock - A lock to protect access to the queue.
  ///
  mvm::SpinLock FinalizationQueueLock;

  /// finalizationQueue - A list of allocated objets that contain a finalize
  /// method.
  ///
  gc** FinalizationQueue;

  /// CurrentIndex - Current index in the queue of finalizable objects.
  ///
  uint32 CurrentIndex;

  /// QueueLength - Current length of the queue of finalizable objects.
  ///
  uint32 QueueLength;

  /// growFinalizationQueue - Grow the queue of finalizable objects.
  ///
  void growFinalizationQueue();
  
  /// ToBeFinalized - List of objects that are scheduled to be finalized.
  ///
  gc** ToBeFinalized;
  
  /// ToBeFinalizedLength - Current length of the queue of objects scheduled
  /// for finalization.
  ///
  uint32 ToBeFinalizedLength;

  /// CurrentFinalizedIndex - The current index in the ToBeFinalized queue
  /// that will be sceduled for finalization.
  ///
  uint32 CurrentFinalizedIndex;
  
  /// growToBeFinalizedQueue - Grow the queue of the to-be finalized objects.
  ///
  void growToBeFinalizedQueue();
  
  /// finalizationCond - Condition variable to wake up finalization threads.
  ///
  mvm::Cond FinalizationCond;

  /// finalizationLock - Lock for the condition variable.
  ///
  mvm::LockNormal FinalizationLock;
  
  gc** ToEnqueue;
  uint32 ToEnqueueLength;
  uint32 ToEnqueueIndex;
  
  /// ToEnqueueLock - A lock to protect access to the queue.
  ///
  mvm::LockNormal EnqueueLock;
  mvm::Cond EnqueueCond;
  mvm::SpinLock ToEnqueueLock;
  
  void addToEnqueue(gc* obj) {
    if (ToEnqueueIndex >= ToEnqueueLength) {
      uint32 newLength = ToEnqueueLength * GROW_FACTOR;
      gc** newQueue = new gc*[newLength];
      if (!newQueue) {
        fprintf(stderr, "I don't know how to handle reference overflow yet!\n");
        abort();
      }
      for (uint32 i = 0; i < QueueLength; ++i) newQueue[i] = ToEnqueue[i];
      delete[] ToEnqueue;
      ToEnqueue = newQueue;
      ToEnqueueLength = newLength;
    }
    ToEnqueue[ToEnqueueIndex++] = obj;
  }

protected:
  /// invokeFinalizer - Invoke the finalizer of the object. This may involve
  /// changing the environment, e.g. going to native to Java.
  ///
  virtual void invokeFinalizer(gc*) {}


public:
  /// finalizerStart - The start function of a finalizer. Will poll the
  /// finalizationQueue.
  ///
  static void finalizerStart(mvm::Thread*);
  
  /// enqueueStart - The start function of a thread for references. Will poll
  /// ToEnqueue.
  ///
  static void enqueueStart(mvm::Thread*);

  /// addFinalizationCandidate - Add an object to the queue of objects with
  /// a finalization method.
  ///
  void addFinalizationCandidate(gc*);
  
  /// scanFinalizationQueue - Scan objets with a finalized method and schedule
  /// them for finalization if they are not live.
  ///
  void scanFinalizationQueue();

  /// wakeUpFinalizers - Wake the finalizers.
  ///
  void wakeUpFinalizers() { FinalizationCond.broadcast(); }
  
  /// wakeUpEnqueue - Wake the threads for enqueueing.
  ///
  void wakeUpEnqueue() { EnqueueCond.broadcast(); }

  virtual void startCollection() {
    FinalizationQueueLock.acquire();
    ToEnqueueLock.acquire();
    SoftReferencesQueue.acquire();
    WeakReferencesQueue.acquire();
    PhantomReferencesQueue.acquire();
  }
  
  virtual void endCollection() {
    FinalizationQueueLock.release();
    ToEnqueueLock.release();
    SoftReferencesQueue.release();
    WeakReferencesQueue.release();
    PhantomReferencesQueue.release();
  }
  
  /// scanWeakReferencesQueue - Scan all weak references. Called by the GC
  /// before scanning the finalization queue.
  /// 
  void scanWeakReferencesQueue() {
    WeakReferencesQueue.scan(this);
  }
  
  /// scanSoftReferencesQueue - Scan all soft references. Called by the GC
  /// before scanning the finalization queue.
  ///
  void scanSoftReferencesQueue() {
    SoftReferencesQueue.scan(this);
  }
  
  /// scanPhantomReferencesQueue - Scan all phantom references. Called by the GC
  /// after the finalization queue.
  ///
  void scanPhantomReferencesQueue() {
    PhantomReferencesQueue.scan(this);
  }
  
  /// addWeakReference - Add a weak reference to the queue.
  ///
  void addWeakReference(gc* ref) {
    WeakReferencesQueue.addReference(ref);
  }
  
  /// addSoftReference - Add a weak reference to the queue.
  ///
  void addSoftReference(gc* ref) {
    SoftReferencesQueue.addReference(ref);
  }
  
  /// addPhantomReference - Add a weak reference to the queue.
  ///
  void addPhantomReference(gc* ref) {
    PhantomReferencesQueue.addReference(ref);
  }

  /// clearReferent - Clear the referent in a reference. Should be overriden
  /// by the VM.
  ///
  virtual void clearReferent(gc*) {}

  /// getReferent - Get the referent of the reference. Should be overriden
  /// by the VM.
  //
  virtual gc** getReferentPtr(gc*) { return 0; }
  
  /// setReferent - Set the referent of the reference. Should be overriden
  /// by the VM.
  virtual void setReferent(gc* reference, gc* referent) { }

  /// enqueueReference - Calls the enqueue method. Should be overriden
  /// by the VM.
  ///
  virtual bool enqueueReference(gc*) { return false; }


public:

  /// scanner - Scanner of threads' stacks.
  ///
  mvm::StackScanner* scanner;

  mvm::StackScanner* getScanner() {
    return scanner;
  }

  /// rendezvous - The rendezvous implementation for garbage collection.
  ///
  CollectionRV rendezvous;


  StartEndFunctionMap RuntimeFunctions;
  static StartEndFunctionMap SharedRuntimeFunctions;
  StartFunctionMap StaticFunctions;
  static SharedStartFunctionMap SharedStaticFunctions;

  MethodInfo* IPToMethodInfo(void* ip);

#ifdef ISOLATE
  size_t IsolateID;
#endif

#ifdef SERVICE
  uint64_t memoryUsed;
  uint64_t gcTriggered;
  uint64_t executionTime;
  uint64_t numThreads;
  CompilationUnit* CU;
  virtual void stopService() {}

  uint64_t memoryLimit;
  uint64_t executionLimit;
  uint64_t threadLimit;
  uint64_t GCLimit;

  int _since_last_collection;
  VirtualMachine* parent;
  uint32 status; 
#endif

};


} // end namespace mvm
#endif // MVM_VIRTUALMACHINE_H
