hotspot/src/share/vm/libadt/set.cpp
author ysr
Mon, 16 Aug 2010 15:58:42 -0700
changeset 6258 68f252c6e825
parent 5547 f4b087cbb361
child 7397 5b173b4ca846
permissions -rw-r--r--
6948538: CMS: BOT walkers can fall into object allocation and initialization cracks Summary: GC workers now recognize an intermediate transient state of blocks which are allocated but have not yet completed initialization. blk_start() calls do not attempt to determine the size of a block in the transient state, rather waiting for the block to become initialized so that it is safe to query its size. Audited and ensured the order of initialization of object fields (klass, free bit and size) to respect block state transition protocol. Also included some new assertion checking code enabled in debug mode. Reviewed-by: chrisphi, johnc, poonam
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
5547
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1
diff changeset
     2
 * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     4
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
489c9b5090e2 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
489c9b5090e2 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     8
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
489c9b5090e2 Initial load
duke
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
489c9b5090e2 Initial load
duke
parents:
diff changeset
    13
 * accompanied this code).
489c9b5090e2 Initial load
duke
parents:
diff changeset
    14
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
489c9b5090e2 Initial load
duke
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    18
 *
5547
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1
diff changeset
    21
 * questions.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    22
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    23
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    24
489c9b5090e2 Initial load
duke
parents:
diff changeset
    25
// Sets - An Abstract Data Type
489c9b5090e2 Initial load
duke
parents:
diff changeset
    26
489c9b5090e2 Initial load
duke
parents:
diff changeset
    27
#include "incls/_precompiled.incl"
489c9b5090e2 Initial load
duke
parents:
diff changeset
    28
#include "incls/_set.cpp.incl"
489c9b5090e2 Initial load
duke
parents:
diff changeset
    29
489c9b5090e2 Initial load
duke
parents:
diff changeset
    30
// %%%%% includes not needed with AVM framework - Ungar
489c9b5090e2 Initial load
duke
parents:
diff changeset
    31
// #include "port.hpp"
489c9b5090e2 Initial load
duke
parents:
diff changeset
    32
//IMPLEMENTATION
489c9b5090e2 Initial load
duke
parents:
diff changeset
    33
// #include "set.hpp"
489c9b5090e2 Initial load
duke
parents:
diff changeset
    34
489c9b5090e2 Initial load
duke
parents:
diff changeset
    35
#include <stdio.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    36
#include <assert.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    37
#include <string.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    38
#include <stdlib.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    39
489c9b5090e2 Initial load
duke
parents:
diff changeset
    40
// Not needed and it causes terouble for gcc.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    41
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
// #include <iostream.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
//-------------------------Virtual Functions-----------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
// These functions MUST be implemented by the inheriting class.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
class SparseSet;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
/* Removed for MCC BUG
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
   Set::operator const SparseSet*() const { assert(0); return NULL; } */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
const SparseSet *Set::asSparseSet() const { assert(0); return NULL; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
class VectorSet;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
/* Removed for MCC BUG
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
   Set::operator const VectorSet*() const { assert(0); return NULL; } */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
const VectorSet *Set::asVectorSet() const { assert(0); return NULL; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
class ListSet;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
/* Removed for MCC BUG
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
   Set::operator const ListSet*() const { assert(0); return NULL; } */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
const ListSet *Set::asListSet() const { assert(0); return NULL; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
class CoSet;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
/* Removed for MCC BUG
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
   Set::operator const CoSet*() const { assert(0); return NULL; } */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
const CoSet *Set::asCoSet() const { assert(0); return NULL; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
//------------------------------setstr-----------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
// Create a string with a printable representation of a set.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
// The caller must deallocate the string.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
char *Set::setstr() const
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
  if( !this ) return os::strdup("{no set}");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
  Set &set = clone();           // Virtually copy the basic set.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
  set.Sort();                   // Sort elements for in-order retrieval
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
  uint len = 128;               // Total string space
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
  char *buf = NEW_C_HEAP_ARRAY(char,len);// Some initial string space
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
  register char *s = buf;       // Current working string pointer
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
  *s++ = '{';
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
  *s = '\0';
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
  // For all elements of the Set
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
  uint hi = (uint)-2, lo = (uint)-2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
  for( SetI i(&set); i.test(); ++i ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
    if( hi+1 == i.elem ) {        // Moving sequentially thru range?
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
      hi = i.elem;                // Yes, just update hi end of range
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
    } else {                      // Else range ended
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
      if( buf+len-s < 25 ) {      // Generous trailing space for upcoming numbers
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
        int offset = (int)(s-buf);// Not enuf space; compute offset into buffer
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
        len <<= 1;                // Double string size
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
        buf = REALLOC_C_HEAP_ARRAY(char,buf,len); // Reallocate doubled size
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
        s = buf+offset;         // Get working pointer into new bigger buffer
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
      if( lo != (uint)-2 ) {    // Startup?  No!  Then print previous range.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
        if( lo != hi ) sprintf(s,"%d-%d,",lo,hi);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
        else sprintf(s,"%d,",lo);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
        s += strlen(s);         // Advance working string
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
      hi = lo = i.elem;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
  if( lo != (uint)-2 ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
    if( buf+len-s < 25 ) {      // Generous trailing space for upcoming numbers
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
      int offset = (int)(s-buf);// Not enuf space; compute offset into buffer
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
      len <<= 1;                // Double string size
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
      buf = (char*)ReallocateHeap(buf,len); // Reallocate doubled size
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
      s = buf+offset;           // Get working pointer into new bigger buffer
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
    if( lo != hi ) sprintf(s,"%d-%d}",lo,hi);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
    else sprintf(s,"%d}",lo);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
  } else strcat(s,"}");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
  // Don't delete the clone 'set' since it is allocated on Arena.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
  return buf;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
//------------------------------print------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
// Handier print routine
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
void Set::print() const
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
  char *printable_set = setstr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
  tty->print_cr(printable_set);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
  FreeHeap(printable_set);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
//------------------------------parse------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
// Convert a textual representation of a Set, to a Set and union into "this"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
// Set.  Return the amount of text parsed in "len", or zero in "len".
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
int Set::parse(const char *s)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
  register char c;              // Parse character
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
  register const char *t = s;   // Save the starting position of s.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
  do c = *s++;                  // Skip characters
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
  while( c && (c <= ' ') );     // Till no more whitespace or EOS
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
  if( c != '{' ) return 0;      // Oops, not a Set openner
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
  if( *s == '}' ) return 2;     // The empty Set
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
  // Sets are filled with values of the form "xx," or "xx-yy," with the comma
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
  // a "}" at the very end.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
  while( 1 ) {                  // While have elements in the Set
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
    char *u;                    // Pointer to character ending parse
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
    uint hi, i;                 // Needed for range handling below
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
    uint elem = (uint)strtoul(s,&u,10);// Get element
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
    if( u == s ) return 0;      // Bogus crude
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
    s = u;                      // Skip over the number
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
    c = *s++;                   // Get the number seperator
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
    switch ( c ) {              // Different seperators
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
    case '}':                   // Last simple element
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
    case ',':                   // Simple element
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
      (*this) <<= elem;         // Insert the simple element into the Set
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
      break;                    // Go get next element
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
    case '-':                   // Range
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
      hi = (uint)strtoul(s,&u,10); // Get element
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
      if( u == s ) return 0;    // Bogus crude
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
      for( i=elem; i<=hi; i++ )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
        (*this) <<= i;          // Insert the entire range into the Set
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
      s = u;                    // Skip over the number
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
      c = *s++;                 // Get the number seperator
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
    if( c == '}' ) break;       // End of the Set
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
    if( c != ',' ) return 0;    // Bogus garbage
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
  return (int)(s-t);            // Return length parsed
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
//------------------------------Iterator---------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
SetI_::~SetI_()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
}