allocation.hpp 15.2 KB
Newer Older
D
duke 已提交
1
/*
2
 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
D
duke 已提交
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
19 20 21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
D
duke 已提交
22 23 24
 *
 */

25 26 27 28 29 30 31 32 33 34 35 36
#ifndef SHARE_VM_MEMORY_ALLOCATION_HPP
#define SHARE_VM_MEMORY_ALLOCATION_HPP

#include "runtime/globals.hpp"
#include "utilities/globalDefinitions.hpp"
#ifdef COMPILER1
#include "c1/c1_globals.hpp"
#endif
#ifdef COMPILER2
#include "opto/c2_globals.hpp"
#endif

D
duke 已提交
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
#define ARENA_ALIGN_M1 (((size_t)(ARENA_AMALLOC_ALIGNMENT)) - 1)
#define ARENA_ALIGN_MASK (~((size_t)ARENA_ALIGN_M1))
#define ARENA_ALIGN(x) ((((size_t)(x)) + ARENA_ALIGN_M1) & ARENA_ALIGN_MASK)

// All classes in the virtual machine must be subclassed
// by one of the following allocation classes:
//
// For objects allocated in the resource area (see resourceArea.hpp).
// - ResourceObj
//
// For objects allocated in the C-heap (managed by: free & malloc).
// - CHeapObj
//
// For objects allocated on the stack.
// - StackObj
//
// For embedded objects.
// - ValueObj
//
// For classes used as name spaces.
// - AllStatic
//
// The printable subclasses are used for debugging and define virtual
// member functions for printing. Classes that avoid allocating the
// vtbl entries in the objects should therefore not be the printable
// subclasses.
//
// The following macros and function should be used to allocate memory
// directly in the resource area or in the C-heap:
//
//   NEW_RESOURCE_ARRAY(type,size)
//   NEW_RESOURCE_OBJ(type)
//   NEW_C_HEAP_ARRAY(type,size)
//   NEW_C_HEAP_OBJ(type)
//   char* AllocateHeap(size_t size, const char* name);
//   void  FreeHeap(void* p);
//
// C-heap allocation can be traced using +PrintHeapAllocation.
// malloc and free should therefore never called directly.

// Base class for objects allocated in the C-heap.

// In non product mode we introduce a super class for all allocation classes
// that supports printing.
// We avoid the superclass in product mode since some C++ compilers add
// a word overhead for empty super classes.

#ifdef PRODUCT
#define ALLOCATION_SUPER_CLASS_SPEC
#else
#define ALLOCATION_SUPER_CLASS_SPEC : public AllocatedObj
class AllocatedObj {
 public:
  // Printing support
  void print() const;
  void print_value() const;

  virtual void print_on(outputStream* st) const;
  virtual void print_value_on(outputStream* st) const;
};
#endif

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

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

class StackObj ALLOCATION_SUPER_CLASS_SPEC {
 public:
  void* operator new(size_t size);
  void  operator delete(void* p);
};

// Base class for objects used as value objects.
// Calling new or delete will result in fatal error.
//
// Portability note: Certain compilers (e.g. gcc) will
// always make classes bigger if it has a superclass, even
// if the superclass does not have any virtual methods or
// instance fields. The HotSpot implementation relies on this
// not to happen. So never make a ValueObj class a direct subclass
// of this object, but use the VALUE_OBJ_CLASS_SPEC class instead, e.g.,
// like this:
//
//   class A VALUE_OBJ_CLASS_SPEC {
//     ...
//   }
//
// With gcc and possible other compilers the VALUE_OBJ_CLASS_SPEC can
// be defined as a an empty string "".
//
class _ValueObj {
 public:
  void* operator new(size_t size);
  void operator delete(void* p);
};

// Base class for classes that constitute name spaces.

class AllStatic {
 public:
  AllStatic()  { ShouldNotCallThis(); }
  ~AllStatic() { ShouldNotCallThis(); }
};


//------------------------------Chunk------------------------------------------
// Linked list of raw memory chunks
class Chunk: public CHeapObj {
 protected:
  Chunk*       _next;     // Next Chunk in list
  const size_t _len;      // Size of this Chunk
 public:
  void* operator new(size_t size, size_t length);
  void  operator delete(void* p);
  Chunk(size_t length);

  enum {
    // default sizes; make them slightly smaller than 2**k to guard against
    // buddy-system style malloc implementations
#ifdef _LP64
    slack      = 40,            // [RGV] Not sure if this is right, but make it
                                //       a multiple of 8.
#else
    slack      = 20,            // suspected sizeof(Chunk) + internal malloc headers
#endif

    init_size  =  1*K  - slack, // Size of first chunk
    medium_size= 10*K  - slack, // Size of medium-sized chunk
    size       = 32*K  - slack, // Default size of an Arena chunk (following the first)
    non_pool_size = init_size + 32 // An initial size which is not one of above
  };

  void chop();                  // Chop this chunk
  void next_chop();             // Chop next chunk
  static size_t aligned_overhead_size(void) { return ARENA_ALIGN(sizeof(Chunk)); }

  size_t length() const         { return _len;  }
  Chunk* next() const           { return _next;  }
  void set_next(Chunk* n)       { _next = n;  }
  // Boundaries of data area (possibly unused)
  char* bottom() const          { return ((char*) this) + aligned_overhead_size();  }
  char* top()    const          { return bottom() + _len; }
  bool contains(char* p) const  { return bottom() <= p && p <= top(); }

  // Start the chunk_pool cleaner task
  static void start_chunk_pool_cleaner_task();

190 191
  static void clean_chunk_pool();
};
D
duke 已提交
192 193 194 195 196 197 198 199 200 201 202 203 204

//------------------------------Arena------------------------------------------
// Fast allocation of memory
class Arena: public CHeapObj {
protected:
  friend class ResourceMark;
  friend class HandleMark;
  friend class NoHandleMark;
  Chunk *_first;                // First chunk
  Chunk *_chunk;                // current chunk
  char *_hwm, *_max;            // High water mark and max in current chunk
  void* grow(size_t x);         // Get a new Chunk of at least size x
  NOT_PRODUCT(size_t _size_in_bytes;) // Size of arena (used for memory usage tracing)
205
  NOT_PRODUCT(static julong _bytes_allocated;) // total #bytes allocated since start
D
duke 已提交
206 207 208
  friend class AllocStats;
  debug_only(void* malloc(size_t size);)
  debug_only(void* internal_malloc_4(size_t x);)
209
  NOT_PRODUCT(void inc_bytes_allocated(size_t x);)
210 211 212 213 214 215 216 217 218

  void signal_out_of_memory(size_t request, const char* whence) const;

  void check_for_overflow(size_t request, const char* whence) const {
    if (UINTPTR_MAX - request < (uintptr_t)_hwm) {
      signal_out_of_memory(request, whence);
    }
 }

D
duke 已提交
219 220 221 222 223 224 225 226 227 228 229 230 231
 public:
  Arena();
  Arena(size_t init_size);
  Arena(Arena *old);
  ~Arena();
  void  destruct_contents();
  char* hwm() const             { return _hwm; }

  // Fast allocate in the arena.  Common case is: pointer test + increment.
  void* Amalloc(size_t x) {
    assert(is_power_of_2(ARENA_AMALLOC_ALIGNMENT) , "should be a power of 2");
    x = ARENA_ALIGN(x);
    debug_only(if (UseMallocOnly) return malloc(x);)
232
    check_for_overflow(x, "Arena::Amalloc");
233
    NOT_PRODUCT(inc_bytes_allocated(x);)
D
duke 已提交
234 235 236 237 238 239 240 241 242 243 244 245
    if (_hwm + x > _max) {
      return grow(x);
    } else {
      char *old = _hwm;
      _hwm += x;
      return old;
    }
  }
  // Further assume size is padded out to words
  void *Amalloc_4(size_t x) {
    assert( (x&(sizeof(char*)-1)) == 0, "misaligned size" );
    debug_only(if (UseMallocOnly) return malloc(x);)
246
    check_for_overflow(x, "Arena::Amalloc_4");
247
    NOT_PRODUCT(inc_bytes_allocated(x);)
D
duke 已提交
248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266
    if (_hwm + x > _max) {
      return grow(x);
    } else {
      char *old = _hwm;
      _hwm += x;
      return old;
    }
  }

  // Allocate with 'double' alignment. It is 8 bytes on sparc.
  // In other cases Amalloc_D() should be the same as Amalloc_4().
  void* Amalloc_D(size_t x) {
    assert( (x&(sizeof(char*)-1)) == 0, "misaligned size" );
    debug_only(if (UseMallocOnly) return malloc(x);)
#if defined(SPARC) && !defined(_LP64)
#define DALIGN_M1 7
    size_t delta = (((size_t)_hwm + DALIGN_M1) & ~DALIGN_M1) - (size_t)_hwm;
    x += delta;
#endif
267
    check_for_overflow(x, "Arena::Amalloc_D");
268
    NOT_PRODUCT(inc_bytes_allocated(x);)
D
duke 已提交
269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316
    if (_hwm + x > _max) {
      return grow(x); // grow() returns a result aligned >= 8 bytes.
    } else {
      char *old = _hwm;
      _hwm += x;
#if defined(SPARC) && !defined(_LP64)
      old += delta; // align to 8-bytes
#endif
      return old;
    }
  }

  // Fast delete in area.  Common case is: NOP (except for storage reclaimed)
  void Afree(void *ptr, size_t size) {
#ifdef ASSERT
    if (ZapResourceArea) memset(ptr, badResourceValue, size); // zap freed memory
    if (UseMallocOnly) return;
#endif
    if (((char*)ptr) + size == _hwm) _hwm = (char*)ptr;
  }

  void *Arealloc( void *old_ptr, size_t old_size, size_t new_size );

  // Move contents of this arena into an empty arena
  Arena *move_contents(Arena *empty_arena);

  // Determine if pointer belongs to this Arena or not.
  bool contains( const void *ptr ) const;

  // Total of all chunks in use (not thread-safe)
  size_t used() const;

  // Total # of bytes used
  size_t size_in_bytes() const         NOT_PRODUCT({  return _size_in_bytes; }) PRODUCT_RETURN0;
  void set_size_in_bytes(size_t size)  NOT_PRODUCT({ _size_in_bytes = size;  }) PRODUCT_RETURN;
  static void free_malloced_objects(Chunk* chunk, char* hwm, char* max, char* hwm2)  PRODUCT_RETURN;
  static void free_all(char** start, char** end)                                     PRODUCT_RETURN;

private:
  // Reset this Arena to empty, access will trigger grow if necessary
  void   reset(void) {
    _first = _chunk = NULL;
    _hwm = _max = NULL;
  }
};

// One of the following macros must be used when allocating
// an array or object from an arena
317 318
#define NEW_ARENA_ARRAY(arena, type, size) \
  (type*) (arena)->Amalloc((size) * sizeof(type))
D
duke 已提交
319

320 321 322
#define REALLOC_ARENA_ARRAY(arena, type, old, old_size, new_size)    \
  (type*) (arena)->Arealloc((char*)(old), (old_size) * sizeof(type), \
                            (new_size) * sizeof(type) )
D
duke 已提交
323

324 325
#define FREE_ARENA_ARRAY(arena, type, old, size) \
  (arena)->Afree((char*)(old), (size) * sizeof(type))
D
duke 已提交
326

327
#define NEW_ARENA_OBJ(arena, type) \
D
duke 已提交
328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345
  NEW_ARENA_ARRAY(arena, type, 1)


//%note allocation_1
extern char* resource_allocate_bytes(size_t size);
extern char* resource_allocate_bytes(Thread* thread, size_t size);
extern char* resource_reallocate_bytes( char *old, size_t old_size, size_t new_size);
extern void resource_free_bytes( char *old, size_t size );

//----------------------------------------------------------------------
// Base class for objects allocated in the resource area per default.
// Optionally, objects may be allocated on the C heap with
// new(ResourceObj::C_HEAP) Foo(...) or in an Arena with new (&arena)
// ResourceObj's can be allocated within other objects, but don't use
// new or delete (allocation_type is unknown).  If new is used to allocate,
// use delete to deallocate.
class ResourceObj ALLOCATION_SUPER_CLASS_SPEC {
 public:
346
  enum allocation_type { STACK_OR_EMBEDDED = 0, RESOURCE_AREA, C_HEAP, ARENA, allocation_mask = 0x3 };
347
  static void set_allocation_type(address res, allocation_type type) NOT_DEBUG_RETURN;
D
duke 已提交
348 349
#ifdef ASSERT
 private:
350 351 352
  // When this object is allocated on stack the new() operator is not
  // called but garbage on stack may look like a valid allocation_type.
  // Store negated 'this' pointer when new() is called to distinguish cases.
353 354 355
  // Use second array's element for verification value to distinguish garbage.
  uintptr_t _allocation_t[2];
  bool is_type_set() const;
D
duke 已提交
356
 public:
357 358 359 360 361
  allocation_type get_allocation_type() const;
  bool allocated_on_stack()    const { return get_allocation_type() == STACK_OR_EMBEDDED; }
  bool allocated_on_res_area() const { return get_allocation_type() == RESOURCE_AREA; }
  bool allocated_on_C_heap()   const { return get_allocation_type() == C_HEAP; }
  bool allocated_on_arena()    const { return get_allocation_type() == ARENA; }
362 363 364 365
  ResourceObj(); // default construtor
  ResourceObj(const ResourceObj& r); // default copy construtor
  ResourceObj& operator=(const ResourceObj& r); // default copy assignment
  ~ResourceObj();
D
duke 已提交
366 367 368 369 370 371
#endif // ASSERT

 public:
  void* operator new(size_t size, allocation_type type);
  void* operator new(size_t size, Arena *arena) {
      address res = (address)arena->Amalloc(size);
372
      DEBUG_ONLY(set_allocation_type(res, ARENA);)
D
duke 已提交
373 374 375 376
      return res;
  }
  void* operator new(size_t size) {
      address res = (address)resource_allocate_bytes(size);
377
      DEBUG_ONLY(set_allocation_type(res, RESOURCE_AREA);)
D
duke 已提交
378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421
      return res;
  }
  void  operator delete(void* p);
};

// One of the following macros must be used when allocating an array
// or object to determine whether it should reside in the C heap on in
// the resource area.

#define NEW_RESOURCE_ARRAY(type, size)\
  (type*) resource_allocate_bytes((size) * sizeof(type))

#define NEW_RESOURCE_ARRAY_IN_THREAD(thread, type, size)\
  (type*) resource_allocate_bytes(thread, (size) * sizeof(type))

#define REALLOC_RESOURCE_ARRAY(type, old, old_size, new_size)\
  (type*) resource_reallocate_bytes((char*)(old), (old_size) * sizeof(type), (new_size) * sizeof(type) )

#define FREE_RESOURCE_ARRAY(type, old, size)\
  resource_free_bytes((char*)(old), (size) * sizeof(type))

#define FREE_FAST(old)\
    /* nop */

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

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

#define REALLOC_C_HEAP_ARRAY(type, old, size)\
  (type*) (ReallocateHeap((char*)old, (size) * sizeof(type), XSTR(type) " in " __FILE__))

#define FREE_C_HEAP_ARRAY(type,old) \
  FreeHeap((char*)(old))

#define NEW_C_HEAP_OBJ(type)\
  NEW_C_HEAP_ARRAY(type, 1)

extern bool warn_new_operator;

// for statistics
#ifndef PRODUCT
class AllocStats : StackObj {
422 423
  julong start_mallocs, start_frees;
  julong start_malloc_bytes, start_mfree_bytes, start_res_bytes;
D
duke 已提交
424 425 426
 public:
  AllocStats();

427 428 429 430 431
  julong num_mallocs();    // since creation of receiver
  julong alloc_bytes();
  julong num_frees();
  julong free_bytes();
  julong resource_bytes();
D
duke 已提交
432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449
  void   print();
};
#endif


//------------------------------ReallocMark---------------------------------
// Code which uses REALLOC_RESOURCE_ARRAY should check an associated
// ReallocMark, which is declared in the same scope as the reallocated
// pointer.  Any operation that could __potentially__ cause a reallocation
// should check the ReallocMark.
class ReallocMark: public StackObj {
protected:
  NOT_PRODUCT(int _nesting;)

public:
  ReallocMark()   PRODUCT_RETURN;
  void check()    PRODUCT_RETURN;
};
450 451

#endif // SHARE_VM_MEMORY_ALLOCATION_HPP