Bug 611140: add support to only run files when in certain timezones (r=jsudduth)
[tamarin-stm.git] / MMgc / GCAlloc-inlines.h
blobd2c364eca546a893df908d93c2208f8b7356a884
1 /* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */
2 /* vi: set ts=4 sw=4 expandtab: (add to ~/.vimrc: set modeline modelines=5) */
3 /* ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
14 * License.
16 * The Original Code is [Open Source Virtual Machine.].
18 * The Initial Developer of the Original Code is
19 * Adobe System Incorporated.
20 * Portions created by the Initial Developer are Copyright (C) 2004-2006
21 * the Initial Developer. All Rights Reserved.
23 * Contributor(s):
24 * Adobe AS3 Team
26 * Alternatively, the contents of this file may be used under the terms of
27 * either the GNU General Public License Version 2 or later (the "GPL"), or
28 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
38 * ***** END LICENSE BLOCK ***** */
40 #ifndef __GCAlloc_inlines__
41 #define __GCAlloc_inlines__
43 // Inline functions for GCAlloc, GCAlloc::GCBlock, and GCAllocIterator
45 namespace MMgc
47 REALLY_INLINE GCBlockHeader* GetBlockHeader(const void* item)
49 return (GCBlockHeader*)(uintptr_t(item) & GCHeap::kBlockMask);
52 /*static*/
53 REALLY_INLINE GCAlloc::GCBlock *GCAlloc::GetBlock(const void *item)
55 return (GCBlock*)GetBlockHeader(item);
58 /*static*/
59 REALLY_INLINE GCAlloc::GCBlock* GCAlloc::Next(GCAlloc::GCBlock* b)
61 return (GCBlock*)b->next;
64 #ifndef MMGC_FASTBITS
65 /*static*/
66 REALLY_INLINE gcbits_t& GCAlloc::GetGCBits(const void* realptr)
68 GCBlock *block = GetBlock(realptr);
69 return block->bits[GetBitsIndex(block, realptr)];
71 #endif
73 /*static*/
74 REALLY_INLINE void *GCAlloc::FindBeginning(const void *item)
76 GCBlock *block = GetBlock(item);
77 GCAssertMsg(item >= block->items, "Can't call FindBeginning on something pointing to GC header");
78 return block->items + block->size * GetObjectIndex(block, item);
81 REALLY_INLINE void GCAlloc::SetBlockHasWeakRef(const void *userptr)
83 GetBlock(userptr)->slowFlags |= kFlagWeakRefs;
86 REALLY_INLINE void GCAlloc::AddToFreeList(GCBlock *b)
88 GCAssert(!IsOnEitherList(b) && !b->needsSweeping());
89 b->prevFree = NULL;
90 b->nextFree = m_firstFree;
91 if (m_firstFree) {
92 GCAssert(m_firstFree->prevFree == 0 && m_firstFree != b);
93 m_firstFree->prevFree = b;
95 m_firstFree = b;
98 REALLY_INLINE void GCAlloc::RemoveFromFreeList(GCBlock *b)
100 GCAssert(m_firstFree == b || b->prevFree != NULL);
101 if ( m_firstFree == b )
102 m_firstFree = b->nextFree;
103 else
104 b->prevFree->nextFree = b->nextFree;
106 if (b->nextFree)
107 b->nextFree->prevFree = b->prevFree;
108 b->nextFree = b->prevFree = NULL;
111 REALLY_INLINE void GCAlloc::AddToSweepList(GCBlock *b)
113 GCAssert(!IsOnEitherList(b) && !b->needsSweeping());
114 b->prevFree = NULL;
115 b->nextFree = m_needsSweeping;
116 if (m_needsSweeping) {
117 GCAssert(m_needsSweeping->prevFree == 0);
118 m_needsSweeping->prevFree = b;
120 m_needsSweeping = b;
121 b->setNeedsSweeping(kFlagNeedsSweeping);
124 REALLY_INLINE void GCAlloc::RemoveFromSweepList(GCBlock *b)
126 GCAssert(m_needsSweeping == b || b->prevFree != NULL);
127 if ( m_needsSweeping == b )
128 m_needsSweeping = b->nextFree;
129 else
130 b->prevFree->nextFree = b->nextFree;
132 if (b->nextFree)
133 b->nextFree->prevFree = b->prevFree;
134 b->setNeedsSweeping(0);
135 b->nextFree = b->prevFree = NULL;
138 REALLY_INLINE uint32_t GCAlloc::GetObjectIndex(const GCBlock *block, const void *item)
140 GCAlloc* alloc = (GCAlloc*)block->alloc;
141 uint32_t index = (uint32_t)((((char*) item - block->items) * alloc->multiple) >> alloc->shift);
142 #ifdef _DEBUG
143 GCAssert(((char*) item - block->items) / block->size == index);
144 #endif
145 return index;
148 #ifdef MMGC_FASTBITS
150 /*static*/
151 REALLY_INLINE uint32_t GCAlloc::GetBitsIndex(const GCBlock *block, const void *item)
153 uint32_t index = (uintptr_t(item) & 0xFFF) >> block->bitsShift;
154 #ifdef _DEBUG
155 GCAssert(index < uint32_t(((GCAlloc*)block->alloc)->m_numBitmapBytes));
156 #endif
157 return index;
160 #else // MMGC_FASTBITS
162 /*static*/
163 REALLY_INLINE uint32_t GCAlloc::GetBitsIndex(const GCBlock *block, const void *item)
165 return GetObjectIndex(block, item);
168 #endif // MMGC_FASTBITS
170 REALLY_INLINE int GCAlloc::GCBlock::GetCount() const
172 return ((GCAlloc*)alloc)->m_itemsPerBlock;
175 REALLY_INLINE int GCAlloc::GCBlock::needsSweeping()
177 return slowFlags & kFlagNeedsSweeping;
180 REALLY_INLINE void GCAlloc::GCBlock::setNeedsSweeping(int v)
182 GCAssert(v == 0 || v == kFlagNeedsSweeping);
183 slowFlags = (uint8_t)((slowFlags & ~kFlagNeedsSweeping) | v);
186 REALLY_INLINE GCAllocIterator::GCAllocIterator(MMgc::GCAlloc* alloc)
187 : alloc(alloc)
188 , block(alloc->m_firstBlock)
189 , idx(0)
190 , limit(alloc->m_itemsPerBlock)
191 , size(alloc->m_itemSize)
195 REALLY_INLINE bool GCAllocIterator::GetNextMarkedObject(void*& out_ptr, uint32_t& out_size)
197 for (;;) {
198 if (idx == limit) {
199 idx = 0;
200 block = GCAlloc::Next(block);
202 if (block == NULL)
203 return false;
204 uint32_t i = idx++;
205 if ((GC::GetGCBits(block->items + i*size) & (kMark|kQueued)) == kMark) {
206 out_ptr = GetUserPointer(block->items + i*size);
207 out_size = size - (uint32_t)DebugSize();
208 return true;
214 #endif /* __GCAlloc_inlines__ */