[Tizen] Unify dnetmemoryenumlib terms to match the codebase (#291)
[platform/upstream/coreclr.git] / src / utilcode / sbuffer.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 // 
7 // Buffer.cpp
8 // ---------------------------------------------------------------------------
9
10 #include "stdafx.h"
11 #include "sbuffer.h"
12 #include "ex.h"
13 #include "holder.h"
14 #include "stdmacros.h"
15
16 // Try to minimize the performance impact of contracts on CHK build.
17 #if defined(_MSC_VER)
18 #pragma inline_depth (20)
19 #endif
20
21 const DWORD g_garbageFillBuffer[GARBAGE_FILL_BUFFER_ITEMS] = 
22 {
23         GARBAGE_FILL_DWORD, GARBAGE_FILL_DWORD, GARBAGE_FILL_DWORD, GARBAGE_FILL_DWORD,
24         GARBAGE_FILL_DWORD, GARBAGE_FILL_DWORD, GARBAGE_FILL_DWORD, GARBAGE_FILL_DWORD,
25         GARBAGE_FILL_DWORD, GARBAGE_FILL_DWORD, GARBAGE_FILL_DWORD, GARBAGE_FILL_DWORD,
26         GARBAGE_FILL_DWORD, GARBAGE_FILL_DWORD, GARBAGE_FILL_DWORD, GARBAGE_FILL_DWORD,
27 };
28
29 //----------------------------------------------------------------------------
30 // ReallocateBuffer
31 // Low level buffer reallocate routine
32 //----------------------------------------------------------------------------
33 void SBuffer::ReallocateBuffer(COUNT_T allocation, Preserve preserve)
34 {
35     CONTRACT_VOID
36     {
37         PRECONDITION(CheckPointer(this));
38         PRECONDITION(CheckBufferClosed());
39         PRECONDITION(CheckAllocation(allocation));
40         PRECONDITION(allocation >= m_size);
41         POSTCONDITION(m_allocation == allocation);
42         if (allocation > 0) THROWS; else NOTHROW;
43         GC_NOTRIGGER;
44         SUPPORTS_DAC_HOST_ONLY;
45     } 
46     CONTRACT_END;
47
48     BYTE *newBuffer = NULL;
49     if (allocation > 0)
50     {
51         newBuffer = NewBuffer(allocation);
52
53         if (preserve == PRESERVE)
54         {
55             // Copy the relevant contents of the old buffer over
56             DebugMoveBuffer(newBuffer, m_buffer, m_size);
57         }
58     }
59
60     if (IsAllocated())
61         DeleteBuffer(m_buffer, m_allocation);
62
63     m_buffer = newBuffer;
64     m_allocation = allocation;
65
66     if (allocation > 0)
67         SetAllocated();
68     else
69         ClearAllocated();
70
71     ClearImmutable();
72
73     RETURN;
74 }
75
76 void SBuffer::Replace(const Iterator &i, COUNT_T deleteSize, COUNT_T insertSize)
77 {
78     CONTRACT_VOID 
79     {
80         THROWS;
81         GC_NOTRIGGER;
82         PRECONDITION(CheckPointer(this));
83         PRECONDITION(CheckIteratorRange(i, deleteSize));
84         SUPPORTS_DAC_HOST_ONLY;
85     } 
86     CONTRACT_END;
87
88     COUNT_T startRange = (COUNT_T) (i.m_ptr - m_buffer);
89     // The PRECONDITION(CheckIterationRange(i, deleteSize)) should check this in
90     // contract-checking builds, but this ensures we don't integer overflow if someone
91     // passes in an egregious deleteSize by capping it to the remaining length in the
92     // buffer.
93     if ((COUNT_T)(m_buffer + m_size - i.m_ptr) < deleteSize)
94     {
95         _ASSERTE(!"Trying to replace more bytes than are remaining in the buffer.");
96         deleteSize = (COUNT_T)(m_buffer + m_size - i.m_ptr);
97     }
98     COUNT_T endRange = startRange + deleteSize;
99     COUNT_T end = m_size;
100
101     SCOUNT_T delta = insertSize - deleteSize;
102
103     if (delta < 0)
104     {
105         // Buffer is shrinking
106
107         DebugDestructBuffer(i.m_ptr, deleteSize);
108
109         DebugMoveBuffer(m_buffer + endRange + delta,
110                         m_buffer + endRange, 
111                         end - endRange);
112
113         Resize(m_size+delta, PRESERVE);
114
115         i.Resync(this, m_buffer + startRange);
116
117     }
118     else if (delta > 0)
119     {
120         // Buffer is growing
121
122         ResizePadded(m_size+delta);
123
124         i.Resync(this, m_buffer + startRange);
125
126         DebugDestructBuffer(i.m_ptr, deleteSize);
127
128         DebugMoveBuffer(m_buffer + endRange + delta, 
129                         m_buffer + endRange, 
130                         end - endRange);
131
132     }
133     else
134     {
135         // Buffer stays the same size.  We need to DebugDestruct it first to keep
136         // the invariant that the new space is clean.
137
138         DebugDestructBuffer(i.m_ptr, insertSize);
139     }
140
141     DebugConstructBuffer(i.m_ptr, insertSize);
142
143     RETURN;
144 }
145
146