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

vframe.h

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

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

# pragma interface

// vframes are "virtual" frames (as opposed to physical stack frames)

# if defined(FAST_COMPILER) || defined(SIC_COMPILER)

class compiled_vframe;
class nvframe;
class dummy_vframe;

typedef void (*vfValueDoFn)(compiled_vframe* vf1,
                            NameDesc* n1,
                            compiled_vframe* vf2,
                            NameDesc* n2);
                            
# endif

class abstract_vframe: public ResourceObj {
 unknown:
  frame* fr;

 unknown:

# if defined(FAST_COMPILER) || defined(SIC_COMPILER)

  compiled_vframe* as_compiled() {
    if (this == NULL) return NULL;
    assert_compiled();
    return (compiled_vframe*)this;
  }
# endif
    
  interpreted_vframe* as_interpreted() {
    if (this == NULL) return NULL;
    assert_interpreted();
    return (interpreted_vframe*)this;
  }

# if defined(FAST_COMPILER) || defined(SIC_COMPILER)

  nvframe* as_n() {
    if (this == NULL) return NULL;
    assert_n();
    return (nvframe*)this;
  }
  
# endif // defined(FAST_COMPILER) || defined(SIC_COMPILER)

  abstract_vframe* as_abstract() { return (abstract_vframe*) this; }

  void assert_compiled() {
    assert(is_compiled(), "must be compiled vframe"); }
    
  void assert_interpreted() {
    assert(is_interpreted(), "must be interpreted vframe"); }

  void assert_n() {
    assert(is_n(), "must be nvframe"); }

  virtual bool is_n() { return false; };
  
  virtual bool is_compiled() = 0;
  bool is_interpreted() {return !is_compiled();}
    
 protected:
  virtual abstract_vframe* get_sender(bool skipCFrames);

 public:
  virtual bool EQ(abstract_vframe *f) {
    return  this == f  ||  fr == f->fr; }
        
 public:
  virtual smiOop  descOffset() = 0;
  
  virtual int32   real_bci() = 0;
          int32        bci();

  bool  is_prologue(); 

 public:
  abstract_vframe* sendee(abstract_vframe* lastSelfVf = NULL);// vframe below the receiver; SLOW!
  
  virtual abstract_vframe* parent();
  abstract_vframe* sender()             { return get_sender(true); }
  abstract_vframe* immediateSender()    { return get_sender(false); }
  virtual abstract_vframe* home();
  virtual abstract_vframe* top();       // top vframe in same frame
  virtual bool is_top() = 0;

  virtual oop  selector()       = 0;
  virtual oop  delegatee()      = 0;
  virtual oop  method()         = 0;
  virtual oop  methodHolder_or_map()    = 0;

  virtual bool isDummy() { return false; }

  virtual int32 scopeID() = 0;

  virtual bool  is_primCall() = 0;          // currently executing a primitive call?
  virtual bool  is_uncommonTrap() = 0;

  bool  is_first_self_vframe() {
    return is_top() && fr->is_first_self_frame(); }

  virtual bool isCallerOf(ScopeDesc* callee) = 0; 

  virtual oop   get_slot(slotDesc* s) = 0;
  virtual void  set_slot(slotDesc* s,  oop x) = 0;

  virtual void get_expr_stack(oop*& stack,
                              smi& len,
                              bool badOopForUnknown = false) = 0;
  virtual oop self()     = 0;
  virtual oop receiver() = 0;
  virtual oop block()    = 0;
  virtual oop methodHolder_object() = 0;

  virtual void createBlocks(abstract_vframe* calleeOrNull,
                            OopOopTable*& blockValues) = 0;

  virtual void enumerate_references(enumeration *e);
  void enumerate_families(enumeration *e);

  virtual bool print_frame(fint curFrame = 0);
  void print_slot(slotDesc* s, oop meth);
  void print() { print_frame(); }
 protected:
  virtual void print_code(fint curFrame) = 0;
  virtual void print_contents();
};


class interpreted_vframe: public abstract_vframe {
 public:
  interpreter* interp() { return fr->get_interpreter(); }

  bool is_compiled() { return false; }

  interpreted_vframe(frame* f);
  interpreted_vframe() {fr = NULL;}

 public:
  smiOop  descOffset() { return smiOop_zero; }
  int32   real_bci();

  abstract_vframe* parent();

  bool is_top() { return true; }

  oop  selector();
  oop  delegatee();
  oop  method();
  oop  methodHolder_or_map();

  int32 scopeID()       { return BLOCK_PROTO_DESC->value(); }

  bool  is_primCall();      // currently executing a primitive call?
  bool  is_uncommonTrap() { return false; }
  bool  isCallerOf(ScopeDesc* callee) { Unused(callee);  return false; }

  oop   get_slot(slotDesc* s);
  void  set_slot(slotDesc* s,  oop x);

  void get_expr_stack(oop*& stack,
                      smi& len,
                      bool badOopForUnknown = false);

  oop self();
  oop receiver();
  oop block();
  oop methodHolder_object();

  void createBlocks(abstract_vframe* calleeOrNull, OopOopTable*& blockValues);

  void enumerate_references(enumeration *e);

 protected:
  void print_code(fint curFrame) {Unused(curFrame);}
};


# if defined(FAST_COMPILER) || defined(SIC_COMPILER)

class compiled_vframe: public abstract_vframe {
 unknown:
  nmethod* code;
  ScopeDesc* desc;
  RegisterLocator* rl;

 protected:
  int32 _bci;
  
 private:
  void set_rl(RegisterLocator* _rl);

 public:
  bool is_compiled() { return true; }
  RegisterLocator* reg_loc() { return rl; }
  void fix_frame(frame* f);

 unknown:
  
  void codeFromFrame() { code = fr->code(); }
  void descFromCode() {
    PcDesc* d = code->containingPcDesc(fr->return_addr());
    desc = d->containingDesc(code); _bci = d->byteCode; }

  int32 bciFromDesc(ScopeDesc* dc);
  void descFromOffset(smiOop offset) {
    desc = code->scopes->at(offset); _bci = bciFromDesc(desc); }
    
  void rlFromFrame();

  // constructors
  
  compiled_vframe() { fr = NULL, code = NULL, desc = NULL, rl = NULL, _bci = 0; }
  
  compiled_vframe(frame* f, nmethod* c, ScopeDesc* d, fint b, RegisterLocator* _r) {
    fr = f; code = c; desc = d; _bci = b; set_rl( _r); }

  compiled_vframe(frame* f, nmethod* c, ScopeDesc* d, fint b) {
    fr = f; code = c; desc = d; _bci = b; rlFromFrame(); }

  compiled_vframe(frame* f, RegisterLocator* _rl) {
    fr = f; codeFromFrame(); descFromCode(); set_rl(_rl); }

  compiled_vframe(frame* f) {
    fr = f; codeFromFrame(); descFromCode(); rlFromFrame(); }

  compiled_vframe(frame* f, smiOop offset, RegisterLocator* r) {
    fr = f; codeFromFrame(); descFromOffset(offset); set_rl(r); }

  compiled_vframe(frame* f, smiOop offset) {
    fr = f; codeFromFrame(); descFromOffset(offset); rlFromFrame(); }

  compiled_vframe(frame* f, nmethod* c, smiOop offset) {
    fr = f; code = c; descFromOffset(offset);  rlFromFrame(); }
  


  bool EQ(abstract_vframe *f) {
    return 
      this == f
      ||     fr == f->fr
         &&  desc->is_equal(f->as_compiled()->desc); }

  
 protected:
  abstract_vframe* get_sender(bool skipCFrames);
  
 public:
  int32   real_bci()            { return _bci; }

  smiOop  descOffset()          {
    return as_smiOop(code->scopes->offsetTo(desc)); 
  }

  abstract_vframe* parent();

  oop  selector()       { return desc->key.selector; }
  oop  delegatee()      { return desc->key.delegatee; }
  oop  method()         { return desc->method(); }
  oop  methodHolder_or_map()    { return desc->methodHolder_or_map(); }

  int32 scopeID();

  bool  is_primCall();      // currently executing a primitive call?
  bool  is_uncommonTrap();  // currently executing an uncommon trap?
  bool  is_top();
  bool isCallerOf(ScopeDesc* callee);
  

  // only for compiled_vframe's
  
  NameDesc* get_name_desc(slotDesc* s, bool canFail = false);
  
  NameDesc* get_self_name();
  NameDesc* get_cachedSelf_name();
  NameDesc* get_receiver_name();
  NameDesc* get_block_name();
  NameDesc* get_cachedBlock_name();
  
  int32 register_offset(Location r);
  
  virtual oop* register_contents_addr(Location r);
  virtual oop* register_contents_secondary_addr(Location r);
  # if defined(SIC_COMPILER)
   protected:
    oop* special_register_contents_addr(Location r);
   public:
# endif
  oop register_contents(Location r) { return *register_contents_addr(r); }
 public:
  oop  get_contents(NameDesc* n, bool cloneMemoizedBlocks = true,
                    bool cloneEliminatedBlocks = false);
 protected:
  void get_search_locations_for_liveness_check(NameDesc* n, frame*& fr_to_search, RegisterLocator*& rl_to_search);
 
 public:
  void set_contents(NameDesc* n, oop p);

  oop  get_slot(slotDesc* s);
  // this one is just for compiled frames
  oop  get_slot2(slotDesc* s, bool clone1, bool clone2);

  void  set_slot(slotDesc* s,  oop x);

  void get_expr_stack(oop*& stack,
                      smi& len,
                      bool badOopForUnknown = false);

  // only for compiled
  void get_exprStackInfo(compiled_vframe* calleeOrNull,
                         compiled_vframe**& vfs,
                         NameDesc**& nds,
                         smi& len,
                         bool includeArgs = true);

 protected:
  // helpers for get_exprStackInfo
  void get_exprStackInfo_outgoing_args(
                        methodMap*          mm,
                        compiled_vframe*    calleeOrNull,
                        compiled_vframe**   vfs,
                        NameDesc**          nds,
                        fint                i,
                        smi                 len,
                        IntListElem*        e2 );
                        
  void get_outgoing_arg_info_from_dummy_callee( 
                        bool               isReceiverExplicit,
                        compiled_vframe*   calleeOrNull,
                        compiled_vframe**  vfs,
                        NameDesc**         nds,
                        fint&              i,
                        smi                len,
                        oop                sel );
                        
  NameDesc* make_up_fake_name_desc_for_outgoing_receiver();

  void get_outgoing_arg_info_no_sendee( 
                        compiled_vframe**  vfs,
                        NameDesc**         nds,
                        fint&              i,
                        smi                len,
                        IntListElem*       e2 );
                        
  void get_outgoing_arg_info_from_sendee( 
                        bool               isReceiverExplicit, 
                        compiled_vframe*   calleeOrNull,
                        compiled_vframe**  vfs, 
                        NameDesc**         nds, 
                        fint&              i );

 
 public:
  oop self()  { return get_contents(get_self_name()); }
  oop receiver() { return get_contents(get_receiver_name()); }
  oop block() { return get_contents(get_block_name()); }
  
  oop methodHolder_object() {
    if (desc->isDeadBlockScope())
      return self(); // methodHolder_or_map() would fail -- dmu 6/99
    oop mh = methodHolder_or_map();
    if (mh->is_map()) {
      // method holder is the same as self
      return self();
    } else {
      return mh;
    } }

  
  // conversion functions
  // XXXXX not done yet for interp

  // (internal)
  
  oop  copyValueFrom( compiled_vframe* toVF, NameDesc* fromNd, frame* oldBlockHome, OopOopTable* blockValues);
  
  void copyValueTo( NameDesc* n, oop x );
  
  void copyValue(NameDesc* n, compiled_vframe* vf2, NameDesc* n2, frame* f,
                 OopOopTable* blockValues);

  void valuesDo( compiled_vframe* vf,
                 compiled_vframe* calleeOrNull,
                 vfValueDoFn fn,
                 bool wasInInterruptCheck);

  void createBlock(NameDesc* n, OopOopTable*& blockValues);

  // (external)
  
  void copyValuesFrom  (compiled_vframe* vf,
                        compiled_vframe* callee,
                        frame* blockHome,
                        OopOopTable*& blockValues,
                        bool wasInInterruptCheck);
  void copyOutgoingArgs(compiled_vframe* vf,
                        frame* oldBlockHome,
                        OopOopTable*& blockValues,
                        bool lastOnly);
 protected:
  Location location_of_saved_outgoing_arg(fint argNo);
  
  void copy_outgoing_arg( fint argNo,          // -1 for rcvr
                          NameDesc* nd2,       // for src caller's expr stack elem
                          compiled_vframe* vf, // src caller's vframe
                          dummy_vframe* dummy, // old callee
                          NameDesc* nd,        // dst nameDesc
                          frame* oldBlkHome, 
                          OopOopTable* blkValues);
 
 public:
  void createBlocks(abstract_vframe* calleeOrNull, OopOopTable*& blockValues);

  
  void enumerate_references(enumeration *e);
  
  bool print_frame(fint curFrame = 0);
 protected:
  void print_code(fint curFrame);
};



// used to represent the callee of the actual last vframe (to get at out-
// going args)...somewhat hacky - only get_contents is guaranteed to work
struct dummy_vframe : compiled_vframe {
  friend dummy_vframe* new_dummy_vframe(frame* sender);
  dummy_vframe(frame* f, nmethod* c, ScopeDesc* d, fint b)
    : compiled_vframe(f, c, d, b) {}
  oop* register_contents_addr(Location r);
  bool isDummy() { return true; }
  void print();
};


# endif // defined(FAST_COMPILER) || defined(SIC_COMPILER)


extern abstract_vframe* new_vframe(frame* f, RegisterLocator* _rl = NULL);
extern abstract_vframe* new_vframe(frame* f, smiOop offset, RegisterLocator* _rl = NULL);

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