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

allocation.h

This is the verbatim text of the allocation.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


// Superclass for all (or most) VM objects.
// Used for debugging purposes: objects can can be printed with pp()
// (and with C-c C-p in emacs/gdb).  -Urs

struct VMObj {
  virtual ~VMObj(){}

  virtual void print();

  virtual void print_short();
  
  void print_zero();
  void print_short_zero();
  void print_short_null() { if (this != NULL) print_short(); }  
  void print_null()     { if (this != NULL) print(); }

  virtual void oops_do(oopsDoFn f) { Unused((void*)f); }

  VtblPtr_t vtbl_value() { return *((VtblPtr_t*) this); }
  void set_vtbl_value(VtblPtr_t v) { *((VtblPtr_t*) this) = v; }
  void kill_vtbl_value() { set_vtbl_value(0); }
};


struct ResourceArea;

// Base class for all objects using the resource area.

struct ResourceObj: public VMObj {
  void* operator new(size_t size);
  void  operator delete(void* p);
  void* new_array(size_t size);
};


// Base class for all objects allocated in the c-heap.

struct CHeapObj: public VMObj {
  void* operator new(size_t size);
  void  operator delete(void* p);
  void* new_array(size_t size);
};


// Base class for catching new or delete.
// Calling new or delete will result in fatal error.

struct NoExplicitAllocationObj: VMObj {
  void* operator new(size_t size) {
    Unused(size);
    ShouldNotCallThis();
    return 0;
  };

  void  operator delete(void* p) {
    Unused(p);
    ShouldNotCallThis();
  };
};

// Base class for all objects allocated on the stack only.
// Calling new or delete will result in fatal error.

struct StackObj: NoExplicitAllocationObj {
};


// Base class for all objects allocated as part of another object only.
// Added after main framework, dmu 6/96.

struct PartObj: NoExplicitAllocationObj {
};


// Base class for class that is no general, cannot commit
// to whether it is a StackObj, ResourceObj, or whatever.

struct AnywhereObj: VMObj {
};


// One of the following macros must be used when allocating an array to
// determine which area the array should reside in.
# define NEW_RESOURCE_ARRAY( type, size )\
    (type*) allocateResource( (size) * sizeof(type))

# define NEW_C_HEAP_ARRAY( type, size )\
    (type*) AllocateHeap( (size) * sizeof(type), XSTR(type) " in " __FILE__)

# define NEW_RESOURCE_OBJ( type ) NEW_RESOURCE_ARRAY( type, 1 )

// The resource area holds temporary data structures of the VM.  Things
// in the resource area can be deallocated very efficiently using
// ResourceMarks.  (The destructor of a ResourceMark will deallocate
// everything that was created since the ResourceMark was created.)

const fint min_resource_chunk_size = 100 * K;
const fint min_resource_free_size  =  32 * K;

class ResourceAreaChunk: VMObj {
  friend class ResourceMark;
  friend class ResourceArea;
  friend class Resources;
  char* bottom;
  char* top;
  char* first_free;
  ResourceAreaChunk* prev;

  fint _allocated;     // Allocated bytes in this and previous chunks.
  fint _previous_used; // Used bytes in previous chunks.

  void clear(char *start, char *endArg) { memset(start, 33, endArg - start); }
  void clear() { clear(bottom, first_free); }
  void freeTo(char *new_first_free);

public:
  char* allocate_bytes(fint size) {
    char* p = first_free;
    if (first_free + size <= top) {
#     ifdef DEBUG
        extern bool PrintResourceAllocation; // to break cycle in includeDB
        if (PrintResourceAllocation) {
          lprintf("allocating %ld bytes at 0x%lx\n", (long)size, p);
        }
#     endif
#     ifdef GENERATE_ASSERTIONS
      if (CheckAssertions  &&  p == (char*)catchThisOne) {
        warning1("ResourceAreaChunk::allocate_bytes caught 0x%lx", p);
      }
#     endif
      first_free += size;
      return p;
    } else return NULL;
  }

  ResourceAreaChunk(fint min_capacity, ResourceAreaChunk* previous);
  ~ResourceAreaChunk();

  void initialize(ResourceAreaChunk* previous);

  fint capacity() { return top        - bottom; }
  fint used()     { return first_free - bottom; }
  
  bool contains(void* p) {
    if (p >= (void*) bottom && p < (void*) top) return true;
    else if (prev) return prev->contains(p);
    else return false; }

  void print();
  void print_short() { lprintf("ResourceAreaChunk %#lx", this); }
};

struct ResourceArea {
  ResourceAreaChunk* chunk;       // current chunk
  fint nesting;      // current # of nested ResourceMarks
                          // (will warn if alloc with nesting == 0)
  
  ResourceArea();
  ~ResourceArea();

  char* allocate_more_bytes(int32 size);
  char* allocate_bytes(int32 size) {
    assert(size    >= 0, "negative size in allocate_bytes");
    assert(nesting >= 0, "memory leak!");
    if (size == 0) {
      // want to return an invalid pointer for a zero-sized allocation,
      // but not NULL, because routines may want to use NULL for failure.
      return (char*) 1;
    }
    size = roundTo(size, oopSize);
    if (chunk) {
      char* p = chunk->allocate_bytes(size);
      if (p)
        return p;
    }
    return allocate_more_bytes(size);
  }

  fint capacity() { return chunk ? chunk->_allocated : 0; }
  
  int32 used();
  bool contains(void* p) { return chunk != NULL && chunk->contains(p); }
};

// A resource mark releases all resources allocated after it was created
// when the mark is deleted.  Typically used as a local variable.
struct ResourceMark: ResourceObj {
 private:
  ResourceArea* area;
  ResourceAreaChunk* chunk;
  char* top;
 public:
  ResourceMark();
  ~ResourceMark();
};

struct Resources {
 private:
  ResourceAreaChunk* freeChunks;  // list of unused chunks
  fint               _allocated;    // total number of bytes allocated
  bool               _in_consistent_state;
  ResourceAreaChunk* getFromFreeList(fint min_capacity);
 public:
  Resources();
  ResourceAreaChunk* new_chunk(fint min_capacity, ResourceAreaChunk* area);
  
  void addToFreeList(ResourceAreaChunk* c);
  bool in_consistent_state() { return _in_consistent_state; }

  bool  contains(char* p);
  int32 capacity();
  int32 used();
};

extern Resources resources;

extern void* selfs_malloc(size_t size);
extern void selfs_free(void* ptr);
extern void malloc_init();
extern bool MallocInProgress;  // allocating on C heap right now?


inline char* AllocateHeap(int32 size, char* name, bool mustAllocate= true) {
  char* b = (char *) selfs_malloc(size);
  if (mustAllocate && b == NULL) OS::allocate_failed(name);
# ifdef GENERATE_ASSERTIONS
  if (CheckAssertions  &&  b && (char*)catchThisOne == b) warning("AllocateHeap caught one");
# endif
  return b;
}

inline void FreeHeap(void* p) {
# ifdef GENERATE_ASSERTIONS
  if (CheckAssertions  &&  (void*)catchThisOne == p) warning("FreeHeap caught one");
# endif
 selfs_free((char*) p);
}



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