[Tizen] Unify dnetmemoryenumlib terms to match the codebase (#291)
[platform/upstream/coreclr.git] / src / vm / objectlist.cpp
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.
4
5
6 #include "common.h"
7 #include "objectlist.h"
8
9 #ifndef DACCESS_COMPILE
10
11 ObjectList::ObjectList( void )
12 : freeIndexHead_( INVALID_COMPRESSEDSTACK_INDEX ),
13   listLock_( CrstObjectList, CrstFlags(CRST_UNSAFE_SAMELEVEL | CRST_UNSAFE_ANYMODE) )
14 {
15     CONTRACTL {
16         THROWS;
17         GC_NOTRIGGER;
18         MODE_ANY;
19     } CONTRACTL_END;
20 }
21
22 #endif
23
24 #define MAX_LOOP 2
25
26 DWORD
27 ObjectList::AddToList( PVOID ptr )
28 {
29     CONTRACTL {
30         THROWS;
31         GC_NOTRIGGER;
32         MODE_ANY;
33         PRECONDITION(CheckPointer(ptr));
34     } CONTRACTL_END;
35     
36
37         //  sanity check that the pointer low bit is not set
38          _ASSERTE(  (((DWORD)(size_t)ptr & 0x1) == 0) && "Invalid pointer" );
39         
40     DWORD retval = INVALID_COMPRESSEDSTACK_INDEX;
41
42     CrstHolder ch( &listLock_ );
43
44     // If there is an entry in the free list, simply use it.
45
46     if (this->freeIndexHead_ != INVALID_COMPRESSEDSTACK_INDEX)
47     {
48         _ASSERTE( this->listLock_.OwnedByCurrentThread() );
49
50         // grab the head of the list
51         retval = (this->freeIndexHead_ >> 1);
52         
53         DWORD nextFreeIndex = (DWORD)(size_t)this->allEntries_.Get( retval );
54         
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;            
59          
60         // store the pointer
61         this->allEntries_.Set( retval, ptr);       
62     }
63     // Otherwise we place this new entry at that end of the list.
64     else
65     {
66         _ASSERTE( this->listLock_.OwnedByCurrentThread() );
67         retval = this->allEntries_.GetCount();
68         IfFailThrow(this->allEntries_.Append(ptr));
69     }
70
71     _ASSERTE( retval != INVALID_COMPRESSEDSTACK_INDEX );
72
73     return retval;
74 }
75
76 void
77 ObjectList::RemoveFromList( PVOID ptr )
78 {
79     CONTRACTL {
80         THROWS;
81         GC_TRIGGERS;
82         MODE_ANY;
83         PRECONDITION(CheckPointer(ptr));
84     } CONTRACTL_END;
85     
86         //  sanity check that the pointer low bit is not set
87          _ASSERTE(  (((DWORD)(size_t)ptr & 0x1) == 0) && "Invalid pointer" );
88         
89     DWORD index = INVALID_COMPRESSEDSTACK_INDEX;
90
91     CrstHolder ch( &listLock_ );
92
93     ObjectList::Iterator iter = Iterate();
94
95     while (iter.Next())
96     {
97         if (iter.GetElement() == ptr)
98         {
99             index = iter.GetIndex();
100             break;
101         }
102     }
103
104     if (index == INVALID_COMPRESSEDSTACK_INDEX)
105     {
106         _ASSERTE( FALSE && "Unable to find object" );
107     }
108     else
109     {
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);
113     }
114 }
115
116
117
118 void
119 ObjectList::RemoveFromList( DWORD index, PVOID ptr )
120 {
121     CONTRACTL {
122         NOTHROW;
123         GC_NOTRIGGER;
124         MODE_ANY;
125         PRECONDITION(CheckPointer(ptr));
126     } CONTRACTL_END;
127
128     CrstHolder ch( &listLock_ );
129
130         //  sanity check that the pointer low bit is not set
131          _ASSERTE(  (((DWORD)(size_t)ptr & 0x1) == 0) && "Invalid pointer" );
132         
133     _ASSERTE( index < this->allEntries_.GetCount() );
134     _ASSERTE( this->allEntries_.Get( index ) == ptr && "Index tracking failed for this object" );
135
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);
139     
140 }
141
142 PVOID
143 ObjectList::Get( DWORD index )
144 {
145     LIMITED_METHOD_CONTRACT;
146     return this->allEntries_.Get( index );
147 }
148
149
150 UnsynchronizedBlockAllocator::UnsynchronizedBlockAllocator( size_t blockSize )
151 : blockSize_( blockSize ),
152   offset_( blockSize ),
153   index_( INVALID_COMPRESSEDSTACK_INDEX )
154 {
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
158 }
159
160 UnsynchronizedBlockAllocator::~UnsynchronizedBlockAllocator( void )
161 {
162     LIMITED_METHOD_CONTRACT;
163     ArrayList::Iterator iter = this->blockList_.Iterate();
164
165     while (iter.Next())
166     {
167         delete [] (BYTE *) iter.GetElement();
168     }
169 }
170
171
172 PVOID
173 UnsynchronizedBlockAllocator::Allocate( size_t size )
174 {
175     CONTRACTL {
176         THROWS;
177         GC_NOTRIGGER;
178         MODE_ANY;
179     } CONTRACTL_END;
180
181     _ASSERTE( size <= this->blockSize_ );
182
183     NewHolder<BYTE> buffer;
184
185     S_SIZE_T sizecheck = S_SIZE_T(this->offset_) + S_SIZE_T(size) ;
186     if( sizecheck.IsOverflow() )
187     {
188         ThrowOutOfMemory();
189     }
190
191     if (sizecheck.Value() > this->blockSize_)
192     {
193         buffer.Assign( new BYTE[this->blockSize_] );
194         IfFailThrow(this->blockList_.Append( buffer ));
195         buffer.SuppressRelease();
196         ++this->index_;
197         this->offset_ = 0;
198     }
199     else
200     {
201         buffer.Assign( (BYTE*)this->blockList_.Get( index_ ) );
202         buffer.SuppressRelease();
203     }
204
205     void* retval = buffer.GetValue() + this->offset_;
206     this->offset_ += size;
207
208     return retval;
209 }