Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/libadt/vectset.cpp
32285 views
/*1* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#include "precompiled.hpp"25#include "libadt/vectset.hpp"26#include "memory/allocation.inline.hpp"2728// Vector Sets - An Abstract Data Type2930// %%%%% includes not needed with AVM framework - Ungar31// #include "port.hpp"32//IMPLEMENTATION33// #include "vectset.hpp"3435// BitsInByte is a lookup table which tells the number of bits that36// are in the looked-up number. It is very useful in VectorSet_Size.3738uint8 bitsInByte[256] = {390, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,401, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,411, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,422, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,431, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,442, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,452, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,463, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,471, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,482, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,492, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,503, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,512, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,523, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,533, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,544, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 855};5657//------------------------------VectorSet--------------------------------------58// Create a new, empty Set.59VectorSet::VectorSet(Arena *arena) : Set(arena) {60size = 2; // Small initial size61data = (uint32 *)_set_arena->Amalloc(size*sizeof(uint32));62data[0] = 0; // No elements63data[1] = 0;64}6566//------------------------------Construct--------------------------------------67Set &VectorSet_Construct(Arena *arena)68{69return *(new VectorSet(arena));70}7172//------------------------------operator=--------------------------------------73Set &VectorSet::operator = (const Set &set)74{75if( &set == this ) return *this;76FREE_FAST(data);77// The cast is a virtual function that checks that "set" is a VectorSet.78slamin(*(set.asVectorSet()));79return *this;80}8182//------------------------------slamin-----------------------------------------83// Initialize one set with another. No regard is made to the existing Set.84void VectorSet::slamin(const VectorSet& s)85{86size = s.size; // Use new size87data = (uint32*)s._set_arena->Amalloc(size*sizeof(uint32)); // Make array of required size88memcpy( data, s.data, size*sizeof(uint32) ); // Fill the array89}9091//------------------------------grow-------------------------------------------92// Expand the existing set to a bigger size93void VectorSet::grow( uint newsize )94{95newsize = (newsize+31) >> 5; // Convert to longwords96uint x = size;97while( x < newsize ) x <<= 1;98data = (uint32 *)_set_arena->Arealloc(data, size*sizeof(uint32), x*sizeof(uint32));99memset((char *)(data + size), 0, (x - size)*sizeof(uint32));100size = x;101}102103//------------------------------operator<<=------------------------------------104// Insert a member into an existing Set.105Set &VectorSet::operator <<= (uint elem)106{107register uint word = elem >> 5; // Get the longword offset108register uint32 mask = 1L << (elem & 31); // Get bit mask109110if( word >= size ) // Need to grow set?111grow(elem+1); // Then grow it112data[word] |= mask; // Set new bit113return *this;114}115116//------------------------------operator>>=------------------------------------117// Delete a member from an existing Set.118Set &VectorSet::operator >>= (uint elem)119{120register uint word = elem >> 5; // Get the longword offset121if( word >= size ) // Beyond the last?122return *this; // Then it's clear & return clear123register uint32 mask = 1L << (elem & 31); // Get bit mask124data[word] &= ~mask; // Clear bit125return *this;126}127128//------------------------------operator&=-------------------------------------129// Intersect one set into another.130VectorSet &VectorSet::operator &= (const VectorSet &s)131{132// NOTE: The intersection is never any larger than the smallest set.133if( s.size < size ) size = s.size; // Get smaller size134register uint32 *u1 = data; // Pointer to the destination data135register uint32 *u2 = s.data; // Pointer to the source data136for( uint i=0; i<size; i++) // For data in set137*u1++ &= *u2++; // Copy and AND longwords138return *this; // Return set139}140141//------------------------------operator&=-------------------------------------142Set &VectorSet::operator &= (const Set &set)143{144// The cast is a virtual function that checks that "set" is a VectorSet.145return (*this) &= *(set.asVectorSet());146}147148//------------------------------operator|=-------------------------------------149// Union one set into another.150VectorSet &VectorSet::operator |= (const VectorSet &s)151{152// This many words must be unioned153register uint cnt = ((size<s.size)?size:s.size);154register uint32 *u1 = data; // Pointer to the destination data155register uint32 *u2 = s.data; // Pointer to the source data156for( uint i=0; i<cnt; i++) // Copy and OR the two sets157*u1++ |= *u2++;158if( size < s.size ) { // Is set 2 larger than set 1?159// Extend result by larger set160grow(s.size*sizeof(uint32)*8);161memcpy(&data[cnt], u2, (s.size - cnt)*sizeof(uint32));162}163return *this; // Return result set164}165166//------------------------------operator|=-------------------------------------167Set &VectorSet::operator |= (const Set &set)168{169// The cast is a virtual function that checks that "set" is a VectorSet.170return (*this) |= *(set.asVectorSet());171}172173//------------------------------operator-=-------------------------------------174// Difference one set from another.175VectorSet &VectorSet::operator -= (const VectorSet &s)176{177// This many words must be unioned178register uint cnt = ((size<s.size)?size:s.size);179register uint32 *u1 = data; // Pointer to the destination data180register uint32 *u2 = s.data; // Pointer to the source data181for( uint i=0; i<cnt; i++ ) // For data in set182*u1++ &= ~(*u2++); // A <-- A & ~B with longwords183return *this; // Return new set184}185186//------------------------------operator-=-------------------------------------187Set &VectorSet::operator -= (const Set &set)188{189// The cast is a virtual function that checks that "set" is a VectorSet.190return (*this) -= *(set.asVectorSet());191}192193//------------------------------compare----------------------------------------194// Compute 2 booleans: bits in A not B, bits in B not A.195// Return X0 -- A is not a subset of B196// X1 -- A is a subset of B197// 0X -- B is not a subset of A198// 1X -- B is a subset of A199int VectorSet::compare (const VectorSet &s) const200{201register uint32 *u1 = data; // Pointer to the destination data202register uint32 *u2 = s.data; // Pointer to the source data203register uint32 AnotB = 0, BnotA = 0;204// This many words must be unioned205register uint cnt = ((size<s.size)?size:s.size);206207// Get bits for both sets208uint i; // Exit value of loop209for( i=0; i<cnt; i++ ) { // For data in BOTH sets210register uint32 A = *u1++; // Data from one guy211register uint32 B = *u2++; // Data from other guy212AnotB |= (A & ~B); // Compute bits in A not B213BnotA |= (B & ~A); // Compute bits in B not A214}215216// Get bits from bigger set217if( size < s.size ) {218for( ; i<s.size; i++ ) // For data in larger set219BnotA |= *u2++; // These bits are in B not A220} else {221for( ; i<size; i++ ) // For data in larger set222AnotB |= *u1++; // These bits are in A not B223}224225// Set & return boolean flags226return ((!BnotA)<<1) + (!AnotB);227}228229//------------------------------operator==-------------------------------------230// Test for set equality231int VectorSet::operator == (const VectorSet &s) const232{233return compare(s) == 3; // TRUE if A and B are mutual subsets234}235236//------------------------------operator==-------------------------------------237int VectorSet::operator == (const Set &set) const238{239// The cast is a virtual function that checks that "set" is a VectorSet.240return (*this) == *(set.asVectorSet());241}242243//------------------------------disjoint---------------------------------------244// Check for sets being disjoint.245int VectorSet::disjoint(const Set &set) const246{247// The cast is a virtual function that checks that "set" is a VectorSet.248const VectorSet &s = *(set.asVectorSet());249250// NOTE: The intersection is never any larger than the smallest set.251register uint small_size = ((size<s.size)?size:s.size);252register uint32 *u1 = data; // Pointer to the destination data253register uint32 *u2 = s.data; // Pointer to the source data254for( uint i=0; i<small_size; i++) // For data in set255if( *u1++ & *u2++ ) // If any elements in common256return 0; // Then not disjoint257return 1; // Else disjoint258}259260//------------------------------operator<--------------------------------------261// Test for strict subset262int VectorSet::operator < (const VectorSet &s) const263{264return compare(s) == 1; // A subset B, B not subset A265}266267//------------------------------operator<--------------------------------------268int VectorSet::operator < (const Set &set) const269{270// The cast is a virtual function that checks that "set" is a VectorSet.271return (*this) < *(set.asVectorSet());272}273274//------------------------------operator<=-------------------------------------275// Test for subset276int VectorSet::operator <= (const VectorSet &s) const277{278return compare(s) & 1; // A subset B279}280281//------------------------------operator<=-------------------------------------282int VectorSet::operator <= (const Set &set) const283{284// The cast is a virtual function that checks that "set" is a VectorSet.285return (*this) <= *(set.asVectorSet());286}287288//------------------------------operator[]-------------------------------------289// Test for membership. A Zero/Non-Zero value is returned!290int VectorSet::operator[](uint elem) const291{292register uint word = elem >> 5; // Get the longword offset293if( word >= size ) // Beyond the last?294return 0; // Then it's clear295register uint32 mask = 1L << (elem & 31); // Get bit mask296return ((data[word] & mask))!=0; // Return the sense of the bit297}298299//------------------------------getelem----------------------------------------300// Get any element from the set.301uint VectorSet::getelem(void) const302{303uint i; // Exit value of loop304for( i=0; i<size; i++ )305if( data[i] )306break;307uint32 word = data[i];308int j; // Exit value of loop309for( j= -1; word; j++, word>>=1 );310return (i<<5)+j;311}312313//------------------------------Clear------------------------------------------314// Clear a set315void VectorSet::Clear(void)316{317if( size > 100 ) { // Reclaim storage only if huge318FREE_RESOURCE_ARRAY(uint32,data,size);319size = 2; // Small initial size320data = NEW_RESOURCE_ARRAY(uint32,size);321}322memset( data, 0, size*sizeof(uint32) );323}324325//------------------------------Size-------------------------------------------326// Return number of elements in a Set327uint VectorSet::Size(void) const328{329uint sum = 0; // Cumulative size so far.330uint8 *currByte = (uint8*)data;331for( uint32 i = 0; i < (size<<2); i++) // While have bytes to process332sum += bitsInByte[*currByte++]; // Add bits in current byte to size.333return sum;334}335336//------------------------------Sort-------------------------------------------337// Sort the elements for the next forall statement338void VectorSet::Sort(void)339{340}341342//------------------------------hash-------------------------------------------343int VectorSet::hash() const344{345uint32 _xor = 0;346uint lim = ((size<4)?size:4);347for( uint i = 0; i < lim; i++ )348_xor ^= data[i];349return (int)_xor;350}351352//------------------------------iterate----------------------------------------353// Used by Set::print().354class VSetI_ : public SetI_ {355VectorSetI vsi;356public:357VSetI_( const VectorSet *vset, uint &elem ) : vsi(vset) { elem = vsi.elem; }358359uint next(void) { ++vsi; return vsi.elem; }360int test(void) { return vsi.test(); }361};362363SetI_ *VectorSet::iterate(uint &elem) const {364return new(ResourceObj::C_HEAP, mtInternal) VSetI_(this, elem);365}366367//=============================================================================368//------------------------------next-------------------------------------------369// Find and return the next element of a vector set, or return garbage and370// make "VectorSetI::test()" fail.371uint VectorSetI::next(void)372{373j++; // Next element in word374mask = (mask & max_jint) << 1;// Next bit in word375do { // Do While still have words376while( mask ) { // While have bits in word377if( s->data[i] & mask ) { // If found a bit378return (i<<5)+j; // Return the bit address379}380j++; // Skip to next bit381mask = (mask & max_jint) << 1;382}383j = 0; // No more bits in word; setup for next word384mask = 1;385for( i++; (i<s->size) && (!s->data[i]); i++ ); // Skip to non-zero word386} while( i<s->size );387return max_juint; // No element, iterated them all388}389390391