Main Page   Class Hierarchy   Compound List   File List   Header Files   Compound Members   File Members  

process.h

This is the verbatim text of the process.h include file.
/* Sun-$Revision: 23.10 $ */

/* Copyright 1992-9 Sun Microsystems, Inc. and Stanford University.
   See the LICENSE file for license information. */

# pragma interface

// A Process is the VM-level process descriptor of a Self process;
// Self-level process objects (see processOop/Map) contain a pointer
// to their respective Process object and vice versa.

extern Process* prevProcess;
extern Process* currentProcess;
extern Process* twainsProcess;
extern Process* vmProcess;
extern bool8 processSemaphore;  // "semaphore" to protect some critical sections
extern bool ConversionInProgress;       // true during programming conversions


extern bool traceP;
extern bool traceV;

class CSect {
  bool b;
  bool* sem;
 public:
  CSect(bool& sema) { b = sema; sem = &sema; sema = true; }
  ~CSect()          { *sem = b; }
};

struct PreservedList {
  preservedVmObjBList list;
  
  PreservedList() : list(32, true) {  }
  void clear()          { list.clear(); }
  void oops_do(oopsDoFn f, Process* p);
};

enum ProcessState {
  initialized,          // ready, but has no stack yet and hasn't run Self code
  ready,                // could continue at any time, or is currently running
  stopped,              // stopped because of error; cannot continue but
                        // still has a stack which can be inspected
  aborting,             // currently unwinding its stack, or already dead
                        // but not yet destroyed; has no stack
  defunct               // not a real process
  };

typedef void (*process_p)();

class Process: public CHeapObj {
  char* suspendedSP;    // process state - saved in runtime_(sparc_mac_ppc).s
  char* suspendedPC;

  Process* next;
  Stack stk;
  oop method;           // top-level doIt method
  PreservedList preservedList;
  processOop procObj;

  frame* check_vfo_locals;           // for checking vframeOop liveness
  frame* check_vfo_locals_sender;    // check_vfo_locals->sender()
  // for debugging only
  bool check_vfo_locals_is_uncommon; // is check_vfo_locals's nmethod an uncommon branch?

  bool stepping;        // are we in single-step mode?
  bool stopping;        // just returned from "finish" operation; stop ASAP
  char* _uncommonPC;    // PC of uncommon trap (if currently handling unc.trap)
  vframeOop _killUpToVF;// first survivor when cutting back the stack
  bool deoptimizing;    // currently deoptimizing the last stack frame
 public:
  bool zombie;                  // true if it was unreachable at the last GC
  bool restartAfterConversion;  // for controlling restarting after conversion
  
 protected:  
  Process* aborter;     // process aborting us
  
 public:
  ResourceArea resource_area;
  int32 nesting;        // e.g. 2 means Self called VM called Self
  int32 current_hash;   // Counter used when assigning hash-values to objects.
  ProcessState state;
  
  vframeOop  stopActivation; // activation of "finish" operation

  Profiler* profiler;   // profiler for this process.
  
  friend void startCurrentProcess();
  friend void interruptCheck();
  friend class Processes;
  friend class processOopClass;
  friend class vframeMirror;
  
  Process(processOop p, int32 sSize, oop rcvr = NULL,
          stringOop sel = NULL, objVectorOop args = NULL);
  ~Process();

  void init(char* pcVal);
  void print();
  void print_short();
  
  // execution
  bool hasStack() { return stk.base != NULL; }
  bool allocate();
  void start();
  void terminate();                     
  void abort();
  void transfer();                      // coroutine transfer to this process
  
  // termination functions
  static void volatile abort_process();
  static void volatile terminate_process();


  void setupPreemption()   { setSPLimit(stackEnd()); } // set up for preemption
  void clearPreemption()   { setSPLimit(spLimit()); }    // reset
  bool preemptionPending();
  
  void nonLifoError();
  
  void setSingleStepping();     // set up single step mode
  void patchForSingleStepping(frame* f = NULL);
                                // sets SPLimit & frame patch if necessary
  bool isSingleStepping()       { return stepping; }
  void resetSingleStepping();
  
  void setUncommon(char* pc)    { _uncommonPC = pc; }
  char* uncommonPC()            { return _uncommonPC; }
  bool isUncommon()             { return _uncommonPC != NULL; }
  void resetUncommon()          { _uncommonPC = NULL; }
  
  void setStopPoint(vframeOop stop);
  bool isStopping()             { return stopping; }
  frame* stopFrame();
  void resetStopping()          { stopping = false; }

  void killFrames(abstract_vframe* vf);
  bool isKilling()              { return _killUpToVF != NULL; }
  void resetKilling()           { _killUpToVF = NULL; }
  vframeOop killVF()            { return _killUpToVF; }

  void setDeoptimizing()        { deoptimizing = true; }
  bool isDeoptimizing()         { return deoptimizing; }
  void resetDeoptimizing()      { deoptimizing = false; }
  void deoptimize(frame* last);    // deoptimize last stack frame

  bool isKillingOrDeoptimizing() { return isKilling() || isDeoptimizing(); }
  bool verifyFramePatches();

  void gotoByteCode(abstract_vframe* last, smi bci, objVectorOop exprStack, void* FH);

  bool isClean() {
    return  !stopping
        &&  !stepping
        &&  !isUncommon()
        &&  !check_vfo_locals
        &&  !isKilling()
        &&  !isDeoptimizing(); }


  // methods for top-level running of self code
  
  oop runDoItMethod( oop rcv,
                     oop meth,
                     oop* args = NULL,
                     fint arg_count = 0);

  oop  prepare_to_call_self();
  void cleanup_after_calling_self();
  void cleanup_after_eval_prim(oop res);
  
 private:
  void initialize(oop rcvr, stringOop sel, objVectorOop args);
  void kill();
  
 public:
  // stack operations
  int32 selfNesting()           { return nesting; }
  bool  inSelf(bool including_prologue = false);       // "in Self" = has visible Self activations
                                                       // (false if !including_prologue && topmost activation is in prologue)
  char* stackEnd()              { return stk.end(); }
  bool  contains(void* sp)      { return stk.contains(sp); }
  char* spLimit()                 { return stk.spLimit(); }
  char* lastSP()                { return suspendedSP; }
  bool  isStackOverflow(char* sp) { return stk.isStackOverflow(sp); }
  bool  hadStackOverflow()      { return stk.markDestroyed(); }
  bool  hasEmptyStack();
  void  resetStackOverflow()    { stk.mark(); }
  frame* last_self_frame(bool includePrologue,  RegisterLocator** rl = NULL)  {
    return stk.last_self_frame(includePrologue, rl); }
  
  void  setPC(process_p newPC)  { suspendedPC= first_inst_addr(newPC); }
  bool  isRunnable()            { return state <= ready; }
  processOop processObj()       { return procObj; }
  Stack* stack()                { return &stk; }
  
  // memory operations
  void preserve(preservedVmObj* p);
  void un_preserve(preservedVmObj* p);
  void scavenge_contents();
  void gc_mark_contents();
  void gc_unmark_contents();
  void verify();
  void switch_pointers();
  void read_snapshot(FILE* f);
  void write_snapshot(FILE* f);
  void chainFrames()    { if (nesting > 0) stack()->chainFrames(); }
  void unchainFrames()  { if (nesting > 0) stack()->unchainFrames(); }
  
  // programming operations
  void convert();
  
  // vframe mirror operations

  vframeOop insertVFrameOop(vframeOop vfm);
  vframeOop findVFrameOop(abstract_vframe* vfs);
  vframeOop findInsertionPoint(abstract_vframe* vf);

 protected:
  void killVFrameOops(abstract_vframe* currentVF);
  void killVFrameOopsInCurrentFrame(abstract_vframe* currentVF);
  frame* frame_for_check_vfo_locals(abstract_vframe* currentVF);

  void trace_killVFrameOopsInCurrentFrame(vframeOop, abstract_vframe*);

  void set_check_vfo_locals( abstract_vframe* currentVF);
  void clear_check_vfo_locals();

  
 public:
  void convertVFrameOops(frame* fr, frame* vfoLocals,
                         nmethod* invalidNM,
                         int32 vdepth, abstract_vframe** old_vf, abstract_vframe** new_vf);
  void killVFrameOopsAndSetWatermark(frame* currentFrame);
  
  void printVFrameList(fint howMany);
  bool verifyVFrameList();
  
 protected:
  void clearWatermark();
  void setWatermark(abstract_vframe*);
  
  void traceAndLog_killVFrameOopsAndSetWatermark(frame*, abstract_vframe*);
  void traceEpilog_killVFrameOopsAndSetWatermark();

  // queuing
 public:
  void addAfter(Process* p)     { next = p->next; p->next = this; }
  void remove(Process* p)       { p->next = next; next = NULL; }
};

bool isStackOverflow(char* sp);
bool isOnVMStack(void* sp);
extern frame* frameSwitchingToVMStack;

enum PreemptCause {
  cNoCause = -1,
  cTerminated, cAborted, cStackOverflowed, cNonLIFOBlock,
  cLastFatalCause = cNonLIFOBlock,
  cYielded,
  cSingleStepped, cFinishedActivation,
  cSignal,
  cLowOnSpace,
  cCouldntAllocateStack, // this isn't really a source of preemption; the
                         // process never got started
  cLast                                 // insert new causes before this line
  };

inline bool isFatalCause(PreemptCause c) {
  return c <= cLastFatalCause && c != cNoCause; }

extern PreemptCause preemptCause;
extern int32 causeString[cLast]; // translates  PreemptCause --> VMString index
extern oop yieldArg;             // argument passed with _Yield
extern oop yieldRcvr;            // receiver of _Yield

class Processes: public CHeapObj {
 public:
  bool idle;
  bool needsInvalidate;                 // needs to mark invalid stack frames
  
  Processes();
  void startVMProcess();        // init and start; won't return!
  
  void discardAll();
  void processesDo(processesDoFn f, bool doItForAll = false);
  
  bool isIdle() { return idle; }
  void print();
  
  // memory operations
  void scavenge_contents();
  void gc_mark_contents();
  void gc_unmark_contents();
  void gc_mark_remaining_processes();
  void enumerate_references(enumeration *e);
  void enumerate_families(enumeration *e);
  void verify();
  void switch_pointers(oop from, oop to);
  void read_snapshot(FILE* f);
  void write_snapshot(FILE* f);
  void chainFrames();
  void unchainFrames();
  objVectorOop zombies();
  
  // programming
  void convert();       // convert all stacks after programming change
  void convert_cont();
  
  // son-of operation
  Stack* stackFor(void* f) {
    // try it the fast way (covers almost all calls)
    return currentProcess->contains(f) || isOnVMStack(f)
            ? currentProcess->stack()
            : slowStackFor(f); // have to do it the slow way
  }
  
 private:
  void init();
  Stack* slowStackFor(void* f);
  
 public:
  friend void doTerminateAll_VM();
  friend void doAbortAll_VM();
  friend void doDiscardAll_VM();
};

extern Processes* processes;

oop zombie_prim();

void preemptor();       // set up things to preempt Self process
void interruptCheck();

inline char* allocateResource(size_t size) {
  return currentProcess->resource_area.allocate_bytes(size);
}

// stack-switching functions; execute the continuation function on the VM stack
void switchToVMStack(doFn continuation);        
oop  switchToVMStack(fntype continuation, void* arg1);  

nmethod* switchToVMStack(nmethod *cont(compilingLookup *),
                         compilingLookup *L);   

typedef nmethod* (*constructDoItMethodContinuation)(oop receiver, oop method);
nmethod* switchToVMStack(oop receiver,
                         oop method,
                         constructDoItMethodContinuation continuation);


typedef void (*intLookupContinuation)( simpleLookup* L, int32 arg_count );

void switchToVMStack_intSend( simpleLookup* L, 
                              int32 arg_count,
                              intLookupContinuation continuation);

Generated at Tue Jun 27 12:09:18 2000 for SelfVM by doxygen 1.0.0 written by Dimitri van Heesch, © 1997-1999