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

generation.h

This is the verbatim text of the generation.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 generation is a bunch of spaces of similarly-aged objects

class generation: public CHeapObj {

  friend class rSet;
  friend class universe;
  friend class memOopClass;
  // these call the alloc_ routines directly
  // friend oopsOop oopsOopClass::copy(fint, bool, oop, bool);
  // friend oopsOop oopsOopClass::insert(fint, fint, fint, bool, bool);
  // friend oopsOop oopsOopClass::remove(fint, fint, fint, bool, bool);
  friend class oopsOopClass;
  // friend byteVectorOop byteVectorOopClass::copy(fint, bool, oop, bool);
  // friend byteVectorOop byteVectorOopClass::insert(fint, fint, fint,
  //                                                 bool, bool);
  // friend byteVectorOop byteVectorOopClass::remove(fint, fint, fint,
  //                                                 bool, bool);
  friend class byteVectorOopClass;
  friend class oldGeneration;

 protected:
  // allocators; called by Memory and scavenger
  virtual oop* alloc_objs(fint size, bool mustAllocate= true) = 0;
  virtual oop* alloc_objs_and_bytes(fint size, fint bsize, char*& bytes,
                                    bool mustAllocate= true) = 0;

  // Minimum and maximum addresses, used by card marking code.
  // Must not overlap with address ranges of other generation(s).
  char *low_boundary;
  char *high_boundary;

 public:
  // space enquiries
  virtual int32 capacity() = 0;
  virtual int32 oops_used() = 0;
  virtual int32 bytes_used() = 0;
  virtual int32 oops_free() = 0;
  virtual int32 used() = 0;
  virtual int32 bytes_free() = 0;

  void print();
};


class MapList : public CHeapObj {
public:
  MapList *next;
  slotsMapDeps *map;
 
  MapList(slotsMapDeps *m, MapList *n) { next= n; map= m; }
};

class newGeneration: public generation {

  friend class rSet;
  friend class universe;
  friend class MemoryHistogram;
  friend class blockOopClass;
  friend class TrackObjectHeapInMonitor;
  friend class SelfMonitor;
  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 class AllocationMonitor;
#ifndef NOASM
  friend void itrace(fint);
#endif

 private:
  newSpace* eden_space;
  newSpace* from_space;
  newSpace* to_space;

  // allocators; called by Memory and scavenger
  oop* alloc_objs(fint size, bool mustAllocate= true) {
    return eden_space->alloc_objs(size, mustAllocate); }
  oop* alloc_objs_and_bytes(fint size, fint bsize, char*& bytes,
                            bool mustAllocate= true) {
    return eden_space->alloc_objs_and_bytes(size, bsize, bytes,
                                            mustAllocate); }

 public:
  // space enquiries
  int32 capacity();
  int32 oops_used();
  int32 bytes_used();
  int32 oops_free();
  int32 used();
  int32 bytes_free();

  void print();
  void verify();

  bool contains(void* p) {
    return (char*)p >= low_boundary && (char*)p < high_boundary; }

  bool objs_contains(void* p);

 private:
  // these are used to determine if an oop is in the new or old generation
  // when we have many similar tests to do; the first can be hoisted out of
  // the loop and then passed as the 2nd arg to is_new (for speed).
  // friend void OopNCode::check_store(oop, char*);
  friend class OopNCode;
  // friend nmethod::nmethod(AbstractCompiler*, nmln*, bool);
  friend class nmethod;
  char *boundary() { return high_boundary; }
  inline bool is_new(memOop p, char *boundary); // inlined in generation.dcl.h
  inline bool is_new(oop p,    char *boundary); // ditto

  // constructor, called by Memory
  newGeneration(int32 &eden_size, int32 &surv_size, FILE *snap = NULL);

  // scavenger-related items
  oop* objs_scavenge_point; // always within to_space
  // these are actually called by Memory
  void prepare_for_scavenge(); 
  bool scavenge_contents();

  MapList* map_list;
  void init_map_list() {
    while (map_list != NULL) {
      MapList *n= map_list->next;
      delete map_list;
      map_list= n; }
  }
  friend class slotsMapDeps;
  friend class mapMap;
  // friend Map* Map::init();
  // friend bool mapMap::verify(oop);
  void add_map(slotsMapDeps *m) {  // add m to map chain if new
    if ((char*)m < high_boundary)
      map_list= new MapList(m, map_list); }
  bool has_map(slotsMapDeps *m);
  void adjust_maps();
  void verify_new_maps();

  void switch_pointers(oop from, oop to);

  void write_snapshot(FILE* file);
};


class oldGeneration: public generation {

  friend class rSet;
  friend class universe;
  friend class SelfMonitor;

#ifndef NOASM
  friend void itrace(fint);
#endif
  friend class TrackObjectHeapInMonitor;
  friend oop expand_heap_prim(oop, smi);
  friend class oldSpace;
  // these alloc_ directly here
  friend stringOop create_string(fint);
  // friend stringOop stringOopClass::make_string(char*, fint, bool);
  friend class stringOopClass;

// the following does not work with Metroworks precompiled headers
  friend oop* newSpace::alloc_more_objs(fint, bool);
  friend oop* newSpace::alloc_more_objs_and_bytes(fint, fint, char*&, bool);
  friend oop* oldSpace::alloc_more_objs(fint, oldSpace*&, bool);
  friend oop* oldSpace::alloc_more_objs_and_bytes(fint, fint, char*&,
                                                  oldSpace*&, bool);
  friend bool oldSpace::reserveFree();

  friend inline void handlePreemption();
 private:
  unsigned nSpaces;
  oldSpace *first_space;
  oldSpace *last_space;
  oldSpace *reserve_space; // the space (other than first_space) with reserve
                           // memory for scavenge
  oldSpace *old0; // the first space to be created
  caddr_t top_of_old_space; // keep track of where old space ends so that
                // old space addresses are all near each other

  // for signalling low space 
  int32 VM_reserved_mem;
 public:
  int32 get_VM_reserved_mem() { return VM_reserved_mem; }

 private:
  int32 cached_free;
  void update_cached_free() { cached_free= bytes_free(); }
  int32 lowSpaceThreshold;
 public:
  int32 getLowSpaceThreshold() { return lowSpaceThreshold; }
  void setLowSpaceThreshold(int32 newLST) {
    assert(newLST >= VM_reserved_mem, "red line too low");
    lowSpaceThreshold= newLST;
    lowOnSpace= false; // let next alloc trip if already over the line
    needToSignalLowOnSpace= false;
  }
  bool lowOnSpace;
  bool needToSignalLowOnSpace;
  void check_for_end_of_low_space();
  inline void check_for_low_space();
  int expand(int32 size);

  void update_caches(bool postScavenge);

  // allocators; called by Memory and scavenger
  oop* alloc_objs(fint size, bool mustAllocate= true) {
    oop *p= first_space->alloc_objs_first(size, reserve_space, mustAllocate);
    if (p) {
#     ifdef GENERATE_ASSERTIONS
      if (CheckAssertions  &&  p == (oop*)catchThisOne) {
        warning1("oldGeneration::alloc_objs caught 0x%lx", p);
      }
#     endif
      cached_free -= size*oopSize;
      check_for_low_space();
    }
    return p;
  }
  oop* alloc_objs_and_bytes(fint size, fint bsize, char*& bytes,
                            bool mustAllocate= true) {
    oop *p= first_space->alloc_objs_and_bytes_first(size, bsize, bytes,
                                                    reserve_space,
                                                    mustAllocate);
    if (p) {
#     ifdef GENERATE_ASSERTIONS
        if (CheckAssertions  &&  (p == (oop*)catchThisOne || bytes == (char*)catchThisOne)) {
          warning1("oldGeneration::alloc_objs_and_bytes caught 0x%lx",
                   catchThisOne);
        }
#     endif
      cached_free -= (size + bsize)*oopSize;
      check_for_low_space();
    }
    return p;
  }

  // constructors, called by Memory
  oldGeneration(            int32 initial_size, int32 reserved_amount);
  oldGeneration(FILE* snap, int32 initial_size, int32 reserved_amount);

  // only called at startup
  friend void create_initial_strings(oop);
  char* empty_bytes_addr() {
    assert(first_space != NULL && first_space->next_space == NULL,
           "empty_bytes_addr called too late");
    return first_space->bytesStart();
  }
  
 public:
  bool objs_contains(void* p);

  // space enquiries
  int32 capacity();
  int32 oops_used();
  int32 bytes_used();
  int32 oops_free();
  int32 used();
  int32 bytes_free();

  void print();
  void verify();

  bool contains(void* p);

 private:
  // scavenger-related items; only meaningful during scavenges.
  oldSpace *scavenge_space;

  oop* objs_scavenge_point1; // always within first_space
  oop* objs_scavenge_point2; // always within scavenge_space

  oldSpace* biggest_free_space(oldSpace *f);

  // these are actually called by Memory  
  void prepare_for_scavenge();
  bool scavenge_promotions();
  void cleanup_after_scavenge();
  void switch_pointers(oop from, oop to);
  void switch_pointers_by_card(oop from, oop to);
  void reselect_scavenge_space();
  void reselect_reserve_space();
  bool split_scavenge; // set to true if scavenge goes across two spaces

  space *scavenge_space_for(fint size, fint bsize) {
    if (first_space->would_fit(size, bsize))
      return first_space;
    else {
      assert(scavenge_space->would_fit(size, bsize),
             "scavenger ran out of space");
      split_scavenge= true;
      return scavenge_space;
    }
  }

  void sorted_space_list(oldSpace *sp[], int (*cmp)(oldSpace**, oldSpace**));
  void prepare_for_compaction();

  void first_space_full();

  void append_space(oldSpace *last);

  void read_snapshot(FILE* file);
  bool write_only_old0;
  void set_write_only_old0();
  void write_snapshot(FILE* file);

  void coalesce_spaces();
  void record_new_pointers();
};


int addr_cmp(oldSpace **s1, oldSpace **s2);
smi set_memory_low_space_threshold_prim(oop rcvr, smi newLST, void *FH);


// ensure that you surround the call with {} to prevent s leaking out!
#define FOR_EACH_OLD_SPACE(s) \
  for (oldSpace *s= Memory->old_gen->first_space;               \
       s != NULL;                                               \
       s= s->next_space)




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