1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
7 #include "objectlist.h"
9 #ifndef DACCESS_COMPILE
11 ObjectList::ObjectList( void )
12 : freeIndexHead_( INVALID_COMPRESSEDSTACK_INDEX ),
13 listLock_( CrstObjectList, CrstFlags(CRST_UNSAFE_SAMELEVEL | CRST_UNSAFE_ANYMODE) )
27 ObjectList::AddToList( PVOID ptr )
33 PRECONDITION(CheckPointer(ptr));
37 // sanity check that the pointer low bit is not set
38 _ASSERTE( (((DWORD)(size_t)ptr & 0x1) == 0) && "Invalid pointer" );
40 DWORD retval = INVALID_COMPRESSEDSTACK_INDEX;
42 CrstHolder ch( &listLock_ );
44 // If there is an entry in the free list, simply use it.
46 if (this->freeIndexHead_ != INVALID_COMPRESSEDSTACK_INDEX)
48 _ASSERTE( this->listLock_.OwnedByCurrentThread() );
50 // grab the head of the list
51 retval = (this->freeIndexHead_ >> 1);
53 DWORD nextFreeIndex = (DWORD)(size_t)this->allEntries_.Get( retval );
55 // index in use, pointer values have low bit as 0
56 _ASSERTE( ((nextFreeIndex & 0x01) == 1) && "The free list points to an index that is in use" );
57 // update the head of the list with the next free index stored in the array list
58 this->freeIndexHead_ = nextFreeIndex;
61 this->allEntries_.Set( retval, ptr);
63 // Otherwise we place this new entry at that end of the list.
66 _ASSERTE( this->listLock_.OwnedByCurrentThread() );
67 retval = this->allEntries_.GetCount();
68 IfFailThrow(this->allEntries_.Append(ptr));
71 _ASSERTE( retval != INVALID_COMPRESSEDSTACK_INDEX );
77 ObjectList::RemoveFromList( PVOID ptr )
83 PRECONDITION(CheckPointer(ptr));
86 // sanity check that the pointer low bit is not set
87 _ASSERTE( (((DWORD)(size_t)ptr & 0x1) == 0) && "Invalid pointer" );
89 DWORD index = INVALID_COMPRESSEDSTACK_INDEX;
91 CrstHolder ch( &listLock_ );
93 ObjectList::Iterator iter = Iterate();
97 if (iter.GetElement() == ptr)
99 index = iter.GetIndex();
104 if (index == INVALID_COMPRESSEDSTACK_INDEX)
106 _ASSERTE( FALSE && "Unable to find object" );
110 // add the index to the free list ( shift the freeIndex left and set the low bit)
111 this->allEntries_.Set( index, (PVOID)(size_t)(this->freeIndexHead_));
112 this-> freeIndexHead_ = ((index<<1) | 0x1);
119 ObjectList::RemoveFromList( DWORD index, PVOID ptr )
125 PRECONDITION(CheckPointer(ptr));
128 CrstHolder ch( &listLock_ );
130 // sanity check that the pointer low bit is not set
131 _ASSERTE( (((DWORD)(size_t)ptr & 0x1) == 0) && "Invalid pointer" );
133 _ASSERTE( index < this->allEntries_.GetCount() );
134 _ASSERTE( this->allEntries_.Get( index ) == ptr && "Index tracking failed for this object" );
136 // add the index to the free list ( shift the freeIndex left and set the low bit)
137 this->allEntries_.Set( index, (PVOID)(size_t)(this->freeIndexHead_));
138 this-> freeIndexHead_ = ((index<<1) | 0x1);
143 ObjectList::Get( DWORD index )
145 LIMITED_METHOD_CONTRACT;
146 return this->allEntries_.Get( index );
150 UnsynchronizedBlockAllocator::UnsynchronizedBlockAllocator( size_t blockSize )
151 : blockSize_( blockSize ),
152 offset_( blockSize ),
153 index_( INVALID_COMPRESSEDSTACK_INDEX )
155 LIMITED_METHOD_CONTRACT;
156 // We start off the offset at the block size to force the first
157 // allocation to create a new (first) block
160 UnsynchronizedBlockAllocator::~UnsynchronizedBlockAllocator( void )
162 LIMITED_METHOD_CONTRACT;
163 ArrayList::Iterator iter = this->blockList_.Iterate();
167 delete [] (BYTE *) iter.GetElement();
173 UnsynchronizedBlockAllocator::Allocate( size_t size )
181 _ASSERTE( size <= this->blockSize_ );
183 NewHolder<BYTE> buffer;
185 S_SIZE_T sizecheck = S_SIZE_T(this->offset_) + S_SIZE_T(size) ;
186 if( sizecheck.IsOverflow() )
191 if (sizecheck.Value() > this->blockSize_)
193 buffer.Assign( new BYTE[this->blockSize_] );
194 IfFailThrow(this->blockList_.Append( buffer ));
195 buffer.SuppressRelease();
201 buffer.Assign( (BYTE*)this->blockList_.Get( index_ ) );
202 buffer.SuppressRelease();
205 void* retval = buffer.GetValue() + this->offset_;
206 this->offset_ += size;