src/share/vm/opto/indexSet.hpp

Sat, 16 Mar 2013 07:39:14 -0700

author
morris
date
Sat, 16 Mar 2013 07:39:14 -0700
changeset 4760
96ef09c26978
parent 2557
f7de3327c683
child 6876
710a3c8b516e
permissions
-rw-r--r--

8009166: [parfait] Null pointer deference in hotspot/src/share/vm/opto/type.cpp
Summary: add guarantee() to as_instance_type()
Reviewed-by: kvn, twisti

     1 /*
     2  * Copyright (c) 1998, 2011, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    20  * or visit www.oracle.com if you need additional information or have any
    21  * questions.
    22  *
    23  */
    25 #ifndef SHARE_VM_OPTO_INDEXSET_HPP
    26 #define SHARE_VM_OPTO_INDEXSET_HPP
    28 #include "memory/allocation.hpp"
    29 #include "memory/resourceArea.hpp"
    30 #include "opto/compile.hpp"
    31 #include "opto/regmask.hpp"
    33 // This file defines the IndexSet class, a set of sparse integer indices.
    34 // This data structure is used by the compiler in its liveness analysis and
    35 // during register allocation.
    37 //-------------------------------- class IndexSet ----------------------------
    38 // An IndexSet is a piece-wise bitvector.  At the top level, we have an array
    39 // of pointers to bitvector chunks called BitBlocks.  Each BitBlock has a fixed
    40 // size and is allocated from a shared free list.  The bits which are set in
    41 // each BitBlock correspond to the elements of the set.
    43 class IndexSet : public ResourceObj {
    44  friend class IndexSetIterator;
    46  public:
    47   // When we allocate an IndexSet, it starts off with an array of top level block
    48   // pointers of a set length.  This size is intended to be large enough for the
    49   // majority of IndexSets.  In the cases when this size is not large enough,
    50   // a separately allocated array is used.
    52   // The length of the preallocated top level block array
    53   enum { preallocated_block_list_size = 16 };
    55   // Elements of a IndexSet get decomposed into three fields.  The highest order
    56   // bits are the block index, which tell which high level block holds the element.
    57   // Within that block, the word index indicates which word holds the element.
    58   // Finally, the bit index determines which single bit within that word indicates
    59   // membership of the element in the set.
    61   // The lengths of the index bitfields
    62   enum { bit_index_length = 5,
    63          word_index_length = 3,
    64          block_index_length = 8 // not used
    65   };
    67   // Derived constants used for manipulating the index bitfields
    68   enum {
    69          bit_index_offset = 0, // not used
    70          word_index_offset = bit_index_length,
    71          block_index_offset = bit_index_length + word_index_length,
    73          bits_per_word = 1 << bit_index_length,
    74          words_per_block = 1 << word_index_length,
    75          bits_per_block = bits_per_word * words_per_block,
    77          bit_index_mask = right_n_bits(bit_index_length),
    78          word_index_mask = right_n_bits(word_index_length)
    79   };
    81   // These routines are used for extracting the block, word, and bit index
    82   // from an element.
    83   static uint get_block_index(uint element) {
    84     return element >> block_index_offset;
    85   }
    86   static uint get_word_index(uint element) {
    87     return mask_bits(element >> word_index_offset,word_index_mask);
    88   }
    89   static uint get_bit_index(uint element) {
    90     return mask_bits(element,bit_index_mask);
    91   }
    93   //------------------------------ class BitBlock ----------------------------
    94   // The BitBlock class is a segment of a bitvector set.
    96   class BitBlock : public ResourceObj {
    97    friend class IndexSetIterator;
    98    friend class IndexSet;
   100    private:
   101     // All of BitBlocks fields and methods are declared private.  We limit
   102     // access to IndexSet and IndexSetIterator.
   104     // A BitBlock is composed of some number of 32 bit words.  When a BitBlock
   105     // is not in use by any IndexSet, it is stored on a free list.  The next field
   106     // is used by IndexSet to mainting this free list.
   108     union {
   109       uint32 _words[words_per_block];
   110       BitBlock *_next;
   111     } _data;
   113     // accessors
   114     uint32 *words() { return _data._words; }
   115     void set_next(BitBlock *next) { _data._next = next; }
   116     BitBlock *next() { return _data._next; }
   118     // Operations.  A BitBlock supports four simple operations,
   119     // clear(), member(), insert(), and remove().  These methods do
   120     // not assume that the block index has been masked out.
   122     void clear() {
   123       memset(words(), 0, sizeof(uint32) * words_per_block);
   124     }
   126     bool member(uint element) {
   127       uint word_index = IndexSet::get_word_index(element);
   128       uint bit_index = IndexSet::get_bit_index(element);
   130       return ((words()[word_index] & (uint32)(0x1 << bit_index)) != 0);
   131     }
   133     bool insert(uint element) {
   134       uint word_index = IndexSet::get_word_index(element);
   135       uint bit_index = IndexSet::get_bit_index(element);
   137       uint32 bit = (0x1 << bit_index);
   138       uint32 before = words()[word_index];
   139       words()[word_index] = before | bit;
   140       return ((before & bit) != 0);
   141     }
   143     bool remove(uint element) {
   144       uint word_index = IndexSet::get_word_index(element);
   145       uint bit_index = IndexSet::get_bit_index(element);
   147       uint32 bit = (0x1 << bit_index);
   148       uint32 before = words()[word_index];
   149       words()[word_index] = before & ~bit;
   150       return ((before & bit) != 0);
   151     }
   152   };
   154   //-------------------------- BitBlock allocation ---------------------------
   155  private:
   157   // All IndexSets share an arena from which they allocate BitBlocks.  Unused
   158   // BitBlocks are placed on a free list.
   160   // The number of BitBlocks to allocate at a time
   161   enum { bitblock_alloc_chunk_size = 50 };
   163   static Arena *arena() { return Compile::current()->indexSet_arena(); }
   165   static void populate_free_list();
   167  public:
   169   // Invalidate the current free BitBlock list and begin allocation
   170   // from a new arena.  It is essential that this method is called whenever
   171   // the Arena being used for BitBlock allocation is reset.
   172   static void reset_memory(Compile* compile, Arena *arena) {
   173     compile->set_indexSet_free_block_list(NULL);
   174     compile->set_indexSet_arena(arena);
   176    // This should probably be done in a static initializer
   177    _empty_block.clear();
   178   }
   180  private:
   181   friend class BitBlock;
   182   // A distinguished BitBlock which always remains empty.  When a new IndexSet is
   183   // created, all of its top level BitBlock pointers are initialized to point to
   184   // this.
   185   static BitBlock _empty_block;
   187   //-------------------------- Members ------------------------------------------
   189   // The number of elements in the set
   190   uint      _count;
   192   // Our top level array of bitvector segments
   193   BitBlock **_blocks;
   195   BitBlock  *_preallocated_block_list[preallocated_block_list_size];
   197   // The number of top level array entries in use
   198   uint       _max_blocks;
   200   // Our assertions need to know the maximum number allowed in the set
   201 #ifdef ASSERT
   202   uint       _max_elements;
   203 #endif
   205   // The next IndexSet on the free list (not used at same time as count)
   206   IndexSet *_next;
   208  public:
   209   //-------------------------- Free list operations ------------------------------
   210   // Individual IndexSets can be placed on a free list.  This is done in PhaseLive.
   212   IndexSet *next() {
   213 #ifdef ASSERT
   214     if( VerifyOpto ) {
   215       check_watch("removed from free list?", ((_next == NULL) ? 0 : _next->_serial_number));
   216     }
   217 #endif
   218     return _next;
   219   }
   221   void set_next(IndexSet *next) {
   222 #ifdef ASSERT
   223     if( VerifyOpto ) {
   224       check_watch("put on free list?", ((next == NULL) ? 0 : next->_serial_number));
   225     }
   226 #endif
   227     _next = next;
   228   }
   230  private:
   231   //-------------------------- Utility methods -----------------------------------
   233   // Get the block which holds element
   234   BitBlock *get_block_containing(uint element) const {
   235     assert(element < _max_elements, "element out of bounds");
   236     return _blocks[get_block_index(element)];
   237   }
   239   // Set a block in the top level array
   240   void set_block(uint index, BitBlock *block) {
   241 #ifdef ASSERT
   242     if( VerifyOpto )
   243       check_watch("set block", index);
   244 #endif
   245     _blocks[index] = block;
   246   }
   248   // Get a BitBlock from the free list
   249   BitBlock *alloc_block();
   251   // Get a BitBlock from the free list and place it in the top level array
   252   BitBlock *alloc_block_containing(uint element);
   254   // Free a block from the top level array, placing it on the free BitBlock list
   255   void free_block(uint i);
   257  public:
   258   //-------------------------- Primitive set operations --------------------------
   260   void clear() {
   261 #ifdef ASSERT
   262     if( VerifyOpto )
   263       check_watch("clear");
   264 #endif
   265     _count = 0;
   266     for (uint i = 0; i < _max_blocks; i++) {
   267       BitBlock *block = _blocks[i];
   268       if (block != &_empty_block) {
   269         free_block(i);
   270       }
   271     }
   272   }
   274   uint count() const { return _count; }
   276   bool is_empty() const { return _count == 0; }
   278   bool member(uint element) const {
   279     return get_block_containing(element)->member(element);
   280   }
   282   bool insert(uint element) {
   283 #ifdef ASSERT
   284     if( VerifyOpto )
   285       check_watch("insert", element);
   286 #endif
   287     if (element == 0) {
   288       return 0;
   289     }
   290     BitBlock *block = get_block_containing(element);
   291     if (block == &_empty_block) {
   292       block = alloc_block_containing(element);
   293     }
   294     bool present = block->insert(element);
   295     if (!present) {
   296       _count++;
   297     }
   298     return !present;
   299   }
   301   bool remove(uint element) {
   302 #ifdef ASSERT
   303     if( VerifyOpto )
   304       check_watch("remove", element);
   305 #endif
   307     BitBlock *block = get_block_containing(element);
   308     bool present = block->remove(element);
   309     if (present) {
   310       _count--;
   311     }
   312     return present;
   313   }
   315   //-------------------------- Compound set operations ------------------------
   316   // Compute the union of all elements of one and two which interfere
   317   // with the RegMask mask.  If the degree of the union becomes
   318   // exceeds fail_degree, the union bails out.  The underlying set is
   319   // cleared before the union is performed.
   320   uint lrg_union(uint lr1, uint lr2,
   321                  const uint fail_degree,
   322                  const class PhaseIFG *ifg,
   323                  const RegMask &mask);
   326   //------------------------- Construction, initialization -----------------------
   328   IndexSet() {}
   330   // This constructor is used for making a deep copy of a IndexSet.
   331   IndexSet(IndexSet *set);
   333   // Perform initialization on a IndexSet
   334   void initialize(uint max_element);
   336   // Initialize a IndexSet.  If the top level BitBlock array needs to be
   337   // allocated, do it from the proffered arena.  BitBlocks are still allocated
   338   // from the static Arena member.
   339   void initialize(uint max_element, Arena *arena);
   341   // Exchange two sets
   342   void swap(IndexSet *set);
   344   //-------------------------- Debugging and statistics --------------------------
   346 #ifndef PRODUCT
   347   // Output a IndexSet for debugging
   348   void dump() const;
   349 #endif
   351 #ifdef ASSERT
   352   void tally_iteration_statistics() const;
   354   // BitBlock allocation statistics
   355   static julong _alloc_new;
   356   static julong _alloc_total;
   358   // Block density statistics
   359   static julong _total_bits;
   360   static julong _total_used_blocks;
   361   static julong _total_unused_blocks;
   363   // Sanity tests
   364   void verify() const;
   366   static int _serial_count;
   367   int        _serial_number;
   369   // Check to see if the serial number of the current set is the one we're tracing.
   370   // If it is, print a message.
   371   void check_watch(const char *operation, uint operand) const {
   372     if (IndexSetWatch != 0) {
   373       if (IndexSetWatch == -1 || _serial_number == IndexSetWatch) {
   374         tty->print_cr("IndexSet %d : %s ( %d )", _serial_number, operation, operand);
   375       }
   376     }
   377   }
   378   void check_watch(const char *operation) const {
   379     if (IndexSetWatch != 0) {
   380       if (IndexSetWatch == -1 || _serial_number == IndexSetWatch) {
   381         tty->print_cr("IndexSet %d : %s", _serial_number, operation);
   382       }
   383     }
   384   }
   386  public:
   387   static void print_statistics();
   389 #endif
   390 };
   393 //-------------------------------- class IndexSetIterator --------------------
   394 // An iterator for IndexSets.
   396 class IndexSetIterator VALUE_OBJ_CLASS_SPEC {
   397  friend class IndexSet;
   399  public:
   401   // We walk over the bits in a word in chunks of size window_size.
   402   enum { window_size = 5,
   403          window_mask = right_n_bits(window_size),
   404          table_size  = (1 << window_size) };
   406   // For an integer of length window_size, what is the first set bit?
   407   static const byte _first_bit[table_size];
   409   // For an integer of length window_size, what is the second set bit?
   410   static const byte _second_bit[table_size];
   412  private:
   413   // The current word we are inspecting
   414   uint32                _current;
   416   // What element number are we currently on?
   417   uint                  _value;
   419   // The index of the next word we will inspect
   420   uint                  _next_word;
   422   // A pointer to the contents of the current block
   423   uint32               *_words;
   425   // The index of the next block we will inspect
   426   uint                  _next_block;
   428   // A pointer to the blocks in our set
   429   IndexSet::BitBlock **_blocks;
   431   // The number of blocks in the set
   432   uint                  _max_blocks;
   434   // If the iterator was created from a non-const set, we replace
   435   // non-canonical empty blocks with the _empty_block pointer.  If
   436   // _set is NULL, we do no replacement.
   437   IndexSet            *_set;
   439   // Advance to the next non-empty word and return the next
   440   // element in the set.
   441   uint advance_and_next();
   444  public:
   446   // If an iterator is built from a constant set then empty blocks
   447   // are not canonicalized.
   448   IndexSetIterator(IndexSet *set);
   449   IndexSetIterator(const IndexSet *set);
   451   // Return the next element of the set.  Return 0 when done.
   452   uint next() {
   453     uint current = _current;
   454     if (current != 0) {
   455       uint value = _value;
   456       while (mask_bits(current,window_mask) == 0) {
   457         current >>= window_size;
   458         value += window_size;
   459       }
   461       uint advance = _second_bit[mask_bits(current,window_mask)];
   462       _current = current >> advance;
   463       _value = value + advance;
   464       return value + _first_bit[mask_bits(current,window_mask)];
   465     } else {
   466       return advance_and_next();
   467     }
   468   }
   469 };
   471 #endif // SHARE_VM_OPTO_INDEXSET_HPP

mercurial