src/hotspot/share/adlc/arena.cpp
changeset 47216 71c04702a3d5
parent 19696 bd5a0131bde1
child 51050 96ea37459ca7
child 51078 fc6cfe40e32a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/adlc/arena.cpp	Tue Sep 12 19:03:39 2017 +0200
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#include "adlc.hpp"
+
+void* Chunk::operator new(size_t requested_size, size_t length) throw() {
+  return CHeapObj::operator new(requested_size + length);
+}
+
+void  Chunk::operator delete(void* p, size_t length) {
+  CHeapObj::operator delete(p);
+}
+
+Chunk::Chunk(size_t length) {
+  _next = NULL;         // Chain on the linked list
+  _len  = length;       // Save actual size
+}
+
+//------------------------------chop-------------------------------------------
+void Chunk::chop() {
+  Chunk *k = this;
+  while( k ) {
+    Chunk *tmp = k->_next;
+    // clear out this chunk (to detect allocation bugs)
+    memset(k, 0xBAADBABE, k->_len);
+    free(k);                    // Free chunk (was malloc'd)
+    k = tmp;
+  }
+}
+
+void Chunk::next_chop() {
+  _next->chop();
+  _next = NULL;
+}
+
+//------------------------------Arena------------------------------------------
+Arena::Arena( size_t init_size ) {
+  init_size = (init_size+3) & ~3;
+  _first = _chunk = new (init_size) Chunk(init_size);
+  _hwm = _chunk->bottom();      // Save the cached hwm, max
+  _max = _chunk->top();
+  set_size_in_bytes(init_size);
+}
+
+Arena::Arena() {
+  _first = _chunk = new (Chunk::init_size) Chunk(Chunk::init_size);
+  _hwm = _chunk->bottom();      // Save the cached hwm, max
+  _max = _chunk->top();
+  set_size_in_bytes(Chunk::init_size);
+}
+
+Arena::Arena( Arena *a )
+: _chunk(a->_chunk), _hwm(a->_hwm), _max(a->_max), _first(a->_first) {
+  set_size_in_bytes(a->size_in_bytes());
+}
+
+//------------------------------used-------------------------------------------
+// Total of all Chunks in arena
+size_t Arena::used() const {
+  size_t sum = _chunk->_len - (_max-_hwm); // Size leftover in this Chunk
+  register Chunk *k = _first;
+  while( k != _chunk) {         // Whilst have Chunks in a row
+    sum += k->_len;             // Total size of this Chunk
+    k = k->_next;               // Bump along to next Chunk
+  }
+  return sum;                   // Return total consumed space.
+}
+
+//------------------------------grow-------------------------------------------
+// Grow a new Chunk
+void* Arena::grow( size_t x ) {
+  // Get minimal required size.  Either real big, or even bigger for giant objs
+  size_t len = max(x, Chunk::size);
+
+  register Chunk *k = _chunk;   // Get filled-up chunk address
+  _chunk = new (len) Chunk(len);
+
+  if( k ) k->_next = _chunk;    // Append new chunk to end of linked list
+  else _first = _chunk;
+  _hwm  = _chunk->bottom();     // Save the cached hwm, max
+  _max =  _chunk->top();
+  set_size_in_bytes(size_in_bytes() + len);
+  void* result = _hwm;
+  _hwm += x;
+  return result;
+}
+
+//------------------------------calloc-----------------------------------------
+// Allocate zeroed storage in Arena
+void *Arena::Acalloc( size_t items, size_t x ) {
+  size_t z = items*x;   // Total size needed
+  void *ptr = Amalloc(z);       // Get space
+  memset( ptr, 0, z );          // Zap space
+  return ptr;                   // Return space
+}
+
+//------------------------------realloc----------------------------------------
+// Reallocate storage in Arena.
+void *Arena::Arealloc( void *old_ptr, size_t old_size, size_t new_size ) {
+  char *c_old = (char*)old_ptr; // Handy name
+  // Stupid fast special case
+  if( new_size <= old_size ) {  // Shrink in-place
+    if( c_old+old_size == _hwm) // Attempt to free the excess bytes
+      _hwm = c_old+new_size;    // Adjust hwm
+    return c_old;
+  }
+
+  // See if we can resize in-place
+  if( (c_old+old_size == _hwm) &&       // Adjusting recent thing
+      (c_old+new_size <= _max) ) {      // Still fits where it sits
+    _hwm = c_old+new_size;      // Adjust hwm
+    return c_old;               // Return old pointer
+  }
+
+  // Oops, got to relocate guts
+  void *new_ptr = Amalloc(new_size);
+  memcpy( new_ptr, c_old, old_size );
+  Afree(c_old,old_size);        // Mostly done to keep stats accurate
+  return new_ptr;
+}
+
+//------------------------------reset------------------------------------------
+// Reset this Arena to empty, and return this Arenas guts in a new Arena.
+Arena *Arena::reset(void) {
+  Arena *a = new Arena(this);   // New empty arena
+  _first = _chunk = NULL;       // Normal, new-arena initialization
+  _hwm = _max = NULL;
+  return a;                     // Return Arena with guts
+}
+
+//------------------------------contains---------------------------------------
+// Determine if pointer belongs to this Arena or not.
+bool Arena::contains( const void *ptr ) const {
+  if( (void*)_chunk->bottom() <= ptr && ptr < (void*)_hwm )
+    return true;                // Check for in this chunk
+  for( Chunk *c = _first; c; c = c->_next )
+    if( (void*)c->bottom() <= ptr && ptr < (void*)c->top())
+      return true;              // Check for every chunk in Arena
+  return false;                 // Not in any Chunk, so not in Arena
+}
+
+//-----------------------------------------------------------------------------
+// CHeapObj
+
+void* CHeapObj::operator new(size_t size) throw() {
+  return (void *) malloc(size);
+}
+
+void CHeapObj::operator delete(void* p){
+ free(p);
+}