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

space.h

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

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

# pragma interface

class space: public CHeapObj {
  
  friend class universe;
  friend class generation;
  friend class newGeneration;
  friend class oldGeneration;
  friend class Monitor;
  friend class abstract_monitor;
  friend class byteVectorOopClass;
  // friend oopsOop oopsOopClass::scavenge(fint);
  friend class oopsOopClass;
  // friend void nmethod::printDeps();
  friend class nmethod;

  // instance variables
 protected:
  // invariant: objs_bottom and bytes_top are on page_size boundaries
  oop* objs_bottom;
  oop* objs_top;
  oop* bytes_bottom;      // invariant: keep at least one word free between
                          // object and byte areas, for sentinels,
                          // ie, objs_top < bytes_bottom.
  oop* bytes_top;
  
  oop* old_objs_bottom;   // these are used after a snapshot is read in
  oop* old_objs_top;
  oop* old_bytes_bottom;
  oop* old_bytes_top;

  int32 old_size_bytes() { // the extra 1 is for the invariant
    return oopSize * (1
                      + (old_bytes_top - old_bytes_bottom)
                      + (old_objs_top - old_objs_bottom)); }

  friend bool rSet::verify(bool);

 public:
  char* name;
  
  // constructors; none allocate object space
  space(char *nm, int32 &size) {
    Unused(size); name= nm; } // dummy just for oldSpace
  space(char* nm, int32 &size, char *bottom) {
    init_space(nm, size, bottom); };
  space(char* nm, char *bottom, char *top);
  space(char* nm, FILE *snap);

  void read_snapshot(FILE* snap, char *bottom, char *top);

  // destructor
  ~space() { delete [] name; }

 protected:
  void init_space(char* nm, int32 &size, char *bottom);

 public:
  // allocation test
  bool would_fit(fint size, fint bsize = 0) {
    return objs_top + size  <  bytes_bottom - bsize; }
    
 protected:
  // allocators; called by new,oldGeneration, and by string and block
  // allocators.
  oop* alloc_objs_local(fint size) {
    oop* p = objs_top;
    oop* p1 = p + size;
    if (p1 < bytes_bottom) {
      objs_top = p1;
      return p;
    } else {
      return NULL;
    } }
  void unalloc_objs_local(fint size) { objs_top -= size; }    
  oop* alloc_objs_and_bytes_local(fint size, fint bsize, char*& bytes) {
    oop* p = objs_top;
    oop* p1 = p + size;
    oop* bp = bytes_bottom;
    oop* bp1 = bp - bsize;
    if (bp1 > p1  &&  bp1 <= bp) {
      objs_top = p1;
      bytes_bottom = bp1;
      bytes = (char*) bp1;
      return p;
    } else {
      return NULL;
    } }
  void unalloc_objs_and_bytes_local(fint size, fint bsize) {
    objs_top -= size;
    bytes_bottom += bsize; }
 public:
  oop* oopsStart()   { return objs_bottom; }
  oop* oopsEnd()     { return objs_top; }
  char* bytesStart() { return (char*) bytes_bottom; }
  char* spaceStart() { return (char*)  objs_bottom; }
  char* spaceEnd()   { return (char*) bytes_top; }
  int32 capacity()   { return (char*) bytes_top    - (char*) objs_bottom - oopSize; }
  int32 oops_used()  { return          objs_top    - objs_bottom; }
  int32 bytes_used() { return (char*) bytes_top    - (char*) bytes_bottom; }
  int32 oops_free()  { return         bytes_bottom - objs_top - 1; }
  int32 used()       { return (char*)  objs_top    - (char*) objs_bottom 
                       +      (char*) bytes_top    - (char*) bytes_bottom; }
  int32 bytes_free() { return (char*) bytes_bottom - (char*) objs_top - oopSize; }
  
  bool contains(void* p) {
    return (oop*) p >= objs_bottom && (oop*) p <= bytes_top; }
  bool objs_contains(void* p) {
    return (oop*) p >= objs_bottom && (oop*) p < objs_top; }
  bool in_objs_bounds(void* p) {
    return (oop*) p >= objs_bottom && (oop*) p <= objs_top; }
  bool bytes_contains(void* p) {
    return (oop*) p >= bytes_bottom && (oop*) p <= bytes_top; }
  bool really_contains(void *p) { 
    return objs_contains(p) || bytes_contains(p);}
  bool old_objs_contains(void* p) {
    return (oop*) p >= old_objs_bottom && (oop*) p < old_objs_top; }
  bool old_bytes_contains(void* p) {
    return (oop*) p >= old_bytes_bottom && (oop*) p <= old_bytes_top; }
  
  oop get_allocation_vector();

 protected:
  void set_objs_top_sentinel(oop s) { *objs_top= s; }

  // operations
  inline void clear();                  // inlined below
  void compact(mapOop unmarked_map_map, space*& copySpace, oop*& d, oop*& bd);
  virtual void gc_unmark_contents();
  void verify();

  // for debugging & fun
  oop find_oop_backwards(void* start);
  void oops_do(oopsDoFn f);

  void switch_pointers_in_region(oop from, oop to, oop* bottom, oop* top);
  void switch_pointers(oop from, oop to) {
    switch_pointers_in_region(from, to, objs_bottom, objs_top); }
  void write_snapshot_header(FILE* file);
  void write_snapshot(FILE* file);
  void relocate();
  void relocate_bytes();
  void fixup_maps();
  void fixup_killables();
  void canonicalize_maps(); 
 
  bool need_to_relocate() {
    return objs_bottom != old_objs_bottom ||
      bytes_bottom != old_bytes_bottom; }
  bool need_to_relocate_objs() {
    return objs_bottom != old_objs_bottom; }
  
  memOop relocate_objs(memOop p) {
    assert(old_objs_contains(p), "not correctly relocating");
    return memOop((oop*) p + (objs_bottom - old_objs_bottom)); }
  char* relocate_bytes(char* p) {
    assert(old_bytes_contains(p), "not correctly relocating");
    return (char*) ((oop*) p + (bytes_bottom - old_bytes_bottom)); }
  
 public:
  void enumerate_matches(enumeration *e);
  void enumerate_maps(enumeration *e);
  void enumerate_families(enumeration *e);
  void enumerate_all_objs(enumeration *e);

 protected:
  void enumerate_families_small(enumeration *e);

 public:
  void print();
};

inline void space::clear() {
  objs_top = objs_bottom; bytes_bottom = bytes_top;
# ifdef GENERATE_ASSERTIONS 
    if (CheckAssertions) {
      // to detect scavenging bugs
      set_oops(objs_bottom, oops_free(), oop(1));
    }
# endif
}

class newSpace: public space {
  friend class universe;
  friend class generation;
  friend class newGeneration;
  friend class oldGeneration;
  // these allocate directly in a newSpace
  // friend oop blockOopClass::clone_block(oop);
  friend class blockOopClass;
  friend oop clone0_prim(slotsOop rcvr);
  friend oop clone1_prim(slotsOop rcvr);
  friend oop clone2_prim(slotsOop rcvr);
  friend oop clone3_prim(slotsOop rcvr);
  friend oop clone4_prim(slotsOop rcvr);
  friend oop clone5_prim(slotsOop rcvr);
  friend oop clone6_prim(slotsOop rcvr);
  friend oop clone7_prim(slotsOop rcvr);
  friend oop clone8_prim(slotsOop rcvr);
  friend oop clone9_prim(slotsOop rcvr);

  // friend byteVectorOop byteVectorOopClass::scavenge(fint);
  friend class ::byteVectorOopClass;

  newSpace* next_space;

 private: // see friends for other callers
  oop* alloc_objs(fint size, bool mustAllocate= true) {
    assert(size > 0, "should be a positive allocation");
    oop* p= alloc_objs_local(size);
    if (p) {
#     ifdef GENERATE_ASSERTIONS
        if (CheckAssertions  &&  p == (oop*)catchThisOne) {
          warning1("space::alloc_objs caught 0x%lx", p);
        }
#     endif
      return p;
    } else {
      return alloc_more_objs(size, mustAllocate);
    } }
  oop* alloc_more_objs(fint size, bool mustAllocate);
  
  oop* alloc_objs_and_bytes(fint size, fint bsize, char*& bytes,
                            bool mustAllocate= true) {
    assert(size > 0, "should be a positive allocation");
    assert(bsize >= 0, "should be a non-negative allocation");
    oop* p= alloc_objs_and_bytes_local(size, bsize, bytes);
    if (p) {
#     ifdef GENERATE_ASSERTIONS
        if (CheckAssertions  &&  (p == (oop*)catchThisOne || bytes == (char*)catchThisOne)) {
          warning1("space::alloc_objs_and_bytes caught 0x%lx", catchThisOne);
        }
#     endif
      return p;
    } else {
      return alloc_more_objs_and_bytes(size, bsize, bytes, mustAllocate);
    } }
  oop* alloc_more_objs_and_bytes(fint size, fint bsize, char*& bytes,
                                 bool mustAllocate);
  
  bool scavenge_contents(oop*& start);

  // called by Memory
  newSpace(char* n, int32 &size, char* bottom) : space(n, size, bottom) {}
  newSpace(char* n, int32 &size, FILE* snap);
};


class oldSpace: public space {
  friend class universe;
  friend class generation;
  friend class newGeneration;
  friend class oldGeneration;
  friend class Monitor;
  friend class SelfMonitor;
  friend class abstract_monitor;
  friend class rSet;
  friend void space::compact(mapOop, space*&, oop*&, oop*&);


 private: 
  oldSpace *next_space;

  inline bool reserveFree();
  // called by oldGeneration
  oop* alloc_objs_first(fint size, oldSpace*& reserve_space,
                        bool mustAllocate) {
    oop *p= alloc_objs_local(size);
    if (p) {
      if (mustAllocate || reserve_space || reserveFree())
        return p;
      unalloc_objs_local(size);
    }
    return alloc_objs_second(size, reserve_space, mustAllocate);
  }
  oop* alloc_objs_and_bytes_first(fint size,
                                  fint bsize,
                                  char*& bytes,
                                  oldSpace*& reserve_space,
                                  bool mustAllocate) {
    oop *p= alloc_objs_and_bytes_local(size, bsize, bytes);
    if (p) {
      if (mustAllocate || reserve_space || reserveFree())
        return p;
      unalloc_objs_and_bytes_local(size, bsize);
    }
    return alloc_objs_and_bytes_second(size, bsize, bytes, reserve_space,
                                       mustAllocate);
  }

  oop* alloc_objs_second(fint size, oldSpace*& reserve_space,
                         bool mustAllocate);
  oop* alloc_objs_and_bytes_second(fint size,
                                   fint bsize,
                                   char*& bytes,
                                   oldSpace*& reserve_space,
                                   bool mustAllocate);

  oop* alloc_more_objs(fint size, oldSpace*& reserve_space, bool mustAllocate);
  oop* alloc_more_objs_and_bytes(fint size,
                                 fint bsize,
                                 char*& bytes,
                                 oldSpace*& reserve_space,
                                 bool mustAllocate);

  // constructors
  // allocates object space too; sets size to amount allocated, 0 if none
  // tries to start space at desiredAddress if non-zero.
  oldSpace(char* nm, int32 &size, caddr_t desiredAddress);

  // constructors which do not allocate object space
  oldSpace(char *nm, FILE *snap) : space(nm, snap) { next_space= NULL; }
  oldSpace(char *nm, char *bottom, char *top) : space(nm, bottom, top) {
    next_space= NULL; }

  bool scavenge_promotions(oop*&);
  bool scavenge_recorded_stores();
  virtual void gc_unmark_contents();
  void switch_pointers_by_card(oop from, oop to);
  void record_new_pointers();
};


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