src/share/vm/utilities/array.hpp

Thu, 20 Nov 2008 16:56:09 -0800

author
ysr
date
Thu, 20 Nov 2008 16:56:09 -0800
changeset 888
c96030fff130
parent 867
275a3b7ff0d6
child 905
ad8c8ca4ab0f
permissions
-rw-r--r--

6684579: SoftReference processing can be made more efficient
Summary: For current soft-ref clearing policies, we can decide at marking time if a soft-reference will definitely not be cleared, postponing the decision of whether it will definitely be cleared to the final reference processing phase. This can be especially beneficial in the case of concurrent collectors where the marking is usually concurrent but reference processing is usually not.
Reviewed-by: jmasa

     1 /*
     2  * Copyright 2000-2005 Sun Microsystems, Inc.  All Rights Reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     8  *
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    12  * version 2 for more details (a copy is included in the LICENSE file that
    13  * accompanied this code).
    14  *
    15  * You should have received a copy of the GNU General Public License version
    16  * 2 along with this work; if not, write to the Free Software Foundation,
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    18  *
    19  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    20  * CA 95054 USA or visit www.sun.com if you need additional information or
    21  * have any questions.
    22  *
    23  */
    25 // correct linkage required to compile w/o warnings
    26 // (must be on file level - cannot be local)
    27 extern "C" { typedef int (*ftype)(const void*, const void*); }
    30 class ResourceArray: public ResourceObj {
    31  protected:
    32   int   _length;                                 // the number of array elements
    33   void* _data;                                   // the array memory
    34 #ifdef ASSERT
    35   int   _nesting;                                // the resource area nesting level
    36 #endif
    38   // creation
    39   ResourceArray() {
    40     _length  = 0;
    41     _data    = NULL;
    42     DEBUG_ONLY(init_nesting();)
    43     // client may call initialize, at most once
    44   }
    47   ResourceArray(size_t esize, int length) {
    48     DEBUG_ONLY(_data = NULL);
    49     initialize(esize, length);
    50   }
    52   void initialize(size_t esize, int length) {
    53     assert(length >= 0, "illegal length");
    54     assert(_data == NULL, "must be new object");
    55     _length  = length;
    56     _data    = resource_allocate_bytes(esize * length);
    57     DEBUG_ONLY(init_nesting();)
    58   }
    60 #ifdef ASSERT
    61   void init_nesting();
    62 #endif
    64   // helper functions
    65   void sort     (size_t esize, ftype f);         // sort the array
    66   void expand   (size_t esize, int i, int& size);// expand the array to include slot i
    67   void remove_at(size_t esize, int i);           // remove the element in slot i
    69  public:
    70   // standard operations
    71   int  length() const                            { return _length; }
    72   bool is_empty() const                          { return length() == 0; }
    73 };
    76 class CHeapArray: public CHeapObj {
    77  protected:
    78   int   _length;                                 // the number of array elements
    79   void* _data;                                   // the array memory
    81   // creation
    82   CHeapArray() {
    83     _length  = 0;
    84     _data    = NULL;
    85   }
    88   CHeapArray(size_t esize, int length) {
    89     assert(length >= 0, "illegal length");
    90     _length  = length;
    91     _data    = (void*) NEW_C_HEAP_ARRAY(char *, esize * length);
    92   }
    94 #ifdef ASSERT
    95   void init_nesting();
    96 #endif
    98   // helper functions
    99   void sort     (size_t esize, ftype f);         // sort the array
   100   void expand   (size_t esize, int i, int& size);// expand the array to include slot i
   101   void remove_at(size_t esize, int i);           // remove the element in slot i
   103  public:
   104   // standard operations
   105   int  length() const                            { return _length; }
   106   bool is_empty() const                          { return length() == 0; }
   107 };
   109 #define define_generic_array(array_name,element_type, base_class)                        \
   110   class array_name: public base_class {                                                  \
   111    protected:                                                                            \
   112     typedef element_type etype;                                                          \
   113     enum { esize = sizeof(etype) };                                                      \
   114                                                                                          \
   115     void base_remove_at(size_t size, int i) { base_class::remove_at(size, i); }          \
   116                                                                                          \
   117    public:                                                                               \
   118     /* creation */                                                                       \
   119     array_name() : base_class()                       {}                                 \
   120     array_name(const int length) : base_class(esize, length) {}                          \
   121     array_name(const int length, const etype fx)      { initialize(length, fx); }        \
   122     void initialize(const int length)     { base_class::initialize(esize, length); }     \
   123     void initialize(const int length, const etype fx) {                                  \
   124       initialize(length);                                                                \
   125       for (int i = 0; i < length; i++) ((etype*)_data)[i] = fx;                          \
   126     }                                                                                    \
   127                                                                                          \
   128     /* standard operations */                                                            \
   129     etype& operator [] (const int i) const {                                             \
   130       assert(0 <= i && i < length(), "index out of bounds");                             \
   131       return ((etype*)_data)[i];                                                         \
   132     }                                                                                    \
   133                                                                                          \
   134     int index_of(const etype x) const {                                                  \
   135       int i = length();                                                                  \
   136       while (i-- > 0 && ((etype*)_data)[i] != x) ;                                       \
   137       /* i < 0 || ((etype*)_data)_data[i] == x */                                        \
   138       return i;                                                                          \
   139     }                                                                                    \
   140                                                                                          \
   141     void sort(int f(etype*, etype*))             { base_class::sort(esize, (ftype)f); }  \
   142     bool contains(const etype x) const           { return index_of(x) >= 0; }            \
   143                                                                                          \
   144     /* deprecated operations - for compatibility with GrowableArray only */              \
   145     etype  at(const int i) const                 { return (*this)[i]; }                  \
   146     void   at_put(const int i, const etype x)    { (*this)[i] = x; }                     \
   147     etype* adr_at(const int i)                   { return &(*this)[i]; }                 \
   148     int    find(const etype x)                   { return index_of(x); }                 \
   149   };                                                                                     \
   152 #define define_array(array_name,element_type)                                            \
   153   define_generic_array(array_name, element_type, ResourceArray)
   156 #define define_stack(stack_name,array_name)                                              \
   157   class stack_name: public array_name {                                                  \
   158    protected:                                                                            \
   159     int _size;                                                                           \
   160                                                                                          \
   161     void grow(const int i, const etype fx) {                                             \
   162       assert(i >= length(), "index too small");                                          \
   163       if (i >= size()) expand(esize, i, _size);                                          \
   164       for (int j = length(); j <= i; j++) ((etype*)_data)[j] = fx;                       \
   165       _length = i+1;                                                                     \
   166     }                                                                                    \
   167                                                                                          \
   168    public:                                                                               \
   169     /* creation */                                                                       \
   170     stack_name() : array_name()                     { _size = 0; }                       \
   171     stack_name(const int size)                      { initialize(size); }                \
   172     stack_name(const int size, const etype fx)      { initialize(size, fx); }            \
   173     void initialize(const int size, const etype fx) {                                    \
   174       _size = size;                                                                      \
   175       array_name::initialize(size, fx);                                                  \
   176       /* _length == size, allocation and size are the same */                            \
   177     }                                                                                    \
   178     void initialize(const int size) {                                                    \
   179       _size = size;                                                                      \
   180       array_name::initialize(size);                                                      \
   181       _length = 0;          /* reset length to zero; _size records the allocation */     \
   182     }                                                                                    \
   183                                                                                          \
   184     /* standard operations */                                                            \
   185     int size() const                             { return _size; }                       \
   186                                                                                          \
   187     int push(const etype x) {                                                            \
   188       int len = length();                                                                \
   189       if (len >= size()) expand(esize, len, _size);                                      \
   190       ((etype*)_data)[len] = x;                                                          \
   191       _length = len+1;                                                                   \
   192       return len;                                                                        \
   193     }                                                                                    \
   194                                                                                          \
   195     etype pop() {                                                                        \
   196       assert(!is_empty(), "stack is empty");                                             \
   197       return ((etype*)_data)[--_length];                                                 \
   198     }                                                                                    \
   199                                                                                          \
   200     etype top() const {                                                                  \
   201       assert(!is_empty(), "stack is empty");                                             \
   202       return ((etype*)_data)[length() - 1];                                              \
   203     }                                                                                    \
   204                                                                                          \
   205     void push_all(const stack_name* stack) {                                             \
   206       const int l = stack->length();                                                     \
   207       for (int i = 0; i < l; i++) push(((etype*)(stack->_data))[i]);                     \
   208     }                                                                                    \
   209                                                                                          \
   210     etype at_grow(const int i, const etype fx) {                                         \
   211       if (i >= length()) grow(i, fx);                                                    \
   212       return ((etype*)_data)[i];                                                         \
   213     }                                                                                    \
   214                                                                                          \
   215     void at_put_grow(const int i, const etype x, const etype fx) {                       \
   216       if (i >= length()) grow(i, fx);                                                    \
   217       ((etype*)_data)[i] = x;                                                            \
   218     }                                                                                    \
   219                                                                                          \
   220     void truncate(const int length) {                                                    \
   221       assert(0 <= length && length <= this->length(), "illegal length");                 \
   222       _length = length;                                                                  \
   223     }                                                                                    \
   224                                                                                          \
   225     void remove_at(int i)                        { base_remove_at(esize, i); }           \
   226     void remove(etype x)                         { remove_at(index_of(x)); }             \
   227                                                                                          \
   228     /* inserts the given element before the element at index i */                        \
   229     void insert_before(const int i, const etype el)  {                                   \
   230       int len = length();                                                                \
   231       int new_length = len + 1;                                                          \
   232       if (new_length >= size()) expand(esize, new_length, _size);                        \
   233       for (int j = len - 1; j >= i; j--) {                                               \
   234         ((etype*)_data)[j + 1] = ((etype*)_data)[j];                                     \
   235       }                                                                                  \
   236       _length = new_length;                                                              \
   237       at_put(i, el);                                                                     \
   238     }                                                                                    \
   239                                                                                          \
   240     /* inserts contents of the given stack before the element at index i */              \
   241     void insert_before(const int i, const stack_name *st) {                              \
   242       if (st->length() == 0) return;                                                     \
   243       int len = length();                                                                \
   244       int st_len = st->length();                                                         \
   245       int new_length = len + st_len;                                                     \
   246       if (new_length >= size()) expand(esize, new_length, _size);                        \
   247       int j;                                                                             \
   248       for (j = len - 1; j >= i; j--) {                                                   \
   249         ((etype*)_data)[j + st_len] = ((etype*)_data)[j];                                \
   250       }                                                                                  \
   251       for (j = 0; j < st_len; j++) {                                                     \
   252         ((etype*)_data)[i + j] = ((etype*)st->_data)[j];                                 \
   253       }                                                                                  \
   254       _length = new_length;                                                              \
   255     }                                                                                    \
   256                                                                                          \
   257     /* deprecated operations - for compatibility with GrowableArray only */              \
   258     int  capacity() const                        { return size(); }                      \
   259     void clear()                                 { truncate(0); }                        \
   260     void trunc_to(const int length)              { truncate(length); }                   \
   261     int  append(const etype x)                   { return push(x); }                     \
   262     void appendAll(const stack_name* stack)      { push_all(stack); }                    \
   263     etype last() const                           { return top(); }                       \
   264   };                                                                                     \
   267 #define define_resource_list(element_type)                                               \
   268   define_generic_array(element_type##Array, element_type, ResourceArray)                 \
   269   define_stack(element_type##List, element_type##Array)
   271 #define define_resource_pointer_list(element_type)                                       \
   272   define_generic_array(element_type##Array, element_type *, ResourceArray)               \
   273   define_stack(element_type##List, element_type##Array)
   275 #define define_c_heap_list(element_type)                                                 \
   276   define_generic_array(element_type##Array, element_type, CHeapArray)                    \
   277   define_stack(element_type##List, element_type##Array)
   279 #define define_c_heap_pointer_list(element_type)                                         \
   280   define_generic_array(element_type##Array, element_type *, CHeapArray)                  \
   281   define_stack(element_type##List, element_type##Array)
   284 // Arrays for basic types
   286 define_array(boolArray, bool)          define_stack(boolStack, boolArray)
   287 define_array(intArray , int )          define_stack(intStack , intArray )

mercurial