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
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.
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 __avmplus_List_inlines__
41 #define __avmplus_List_inlines__
46 REALLY_INLINE
bool TracedListData
<Atom
>::gcTrace(MMgc::GC
* gc
, size_t cursor
)
48 const size_t work_increment
= 2000/sizeof(void*);
49 const size_t work_count
= len
;
50 if (cursor
* work_increment
>= work_count
)
53 size_t work
= work_increment
;
55 if ((cursor
+ 1) * work_increment
>= work_count
)
57 work
= work_count
- (cursor
* work_increment
);
61 gc
->TraceAtoms(entries
+ (cursor
*work_increment
), work
);
66 inline bool TracedListData
<T
>::gcTrace(MMgc::GC
* gc
, size_t cursor
)
68 const size_t work_increment
= 2000/sizeof(void*);
69 const size_t work_count
= len
;
70 if (cursor
* work_increment
>= work_count
)
73 size_t work
= work_increment
;
75 if ((cursor
+ 1) * work_increment
>= work_count
)
77 work
= work_count
- (cursor
* work_increment
);
81 gc
->TraceLocations(entries
+ (cursor
*work_increment
), work
);
85 // ----------------------------
88 REALLY_INLINE
/*static*/ void DataListHelper
<T
>::wbData(const void* /*container*/, LISTDATA
** address
, LISTDATA
* data
)
94 REALLY_INLINE
/*static*/ typename DataListHelper
<T
>::TYPE DataListHelper
<T
>::load(LISTDATA
* data
, uint32_t index
)
96 AvmAssert(data
!= NULL
);
97 return data
->entries
[index
];
101 REALLY_INLINE
/*static*/ void DataListHelper
<T
>::store(LISTDATA
* data
, uint32_t index
, TYPE value
)
103 AvmAssert(data
!= NULL
);
104 data
->entries
[index
] = value
;
108 REALLY_INLINE
/*static*/ void DataListHelper
<T
>::storeInEmpty(LISTDATA
* data
, uint32_t index
, TYPE value
)
110 AvmAssert(data
!= NULL
);
111 // This is commented out because it's not necessary for safety of a DataList,
112 // and it can generate an assert in List::insert(), which uses storeInEmpty() for efficiency;
113 // since DataListHelper::moveRange doesn't zero out the cleared space we could get this
114 // assertion firing. Better to neuter this assertion than add a unnecessary zeroing-out
115 // to moveRange() just to pacify it.
116 // AvmAssert(data->entries[index] == 0);
117 data
->entries
[index
] = value
;
121 REALLY_INLINE
/*static*/ void DataListHelper
<T
>::clearRange(LISTDATA
* data
, uint32_t start
, uint32_t count
)
123 AvmAssert(count
> 0);
124 VMPI_memset(&data
->entries
[start
], 0, count
*sizeof(T
));
128 REALLY_INLINE
/*static*/ void DataListHelper
<T
>::moveRange(LISTDATA
* data
, uint32_t srcStart
, uint32_t dstStart
, uint32_t count
)
130 VMPI_memmove(&data
->entries
[dstStart
], &data
->entries
[srcStart
], count
* sizeof(T
));
134 REALLY_INLINE
/*static*/ void DataListHelper
<T
>::gcTrace(MMgc::GC
* gc
, LISTDATA
** loc
)
136 AvmAssert(!gc
->IsPointerToGCPage(*loc
));
140 // ----------------------------
142 REALLY_INLINE
/*static*/ void GCListHelper::wbData(const void* container
, LISTDATA
** address
, LISTDATA
* data
)
144 MMgc::GC
* const gc
= data
->gc();
145 if (gc
->IsPointerToGCPage(container
))
147 WB(gc
, gc
->FindBeginningFast(container
), address
, data
);
155 REALLY_INLINE
/*static*/ GCListHelper::TYPE
GCListHelper::load(LISTDATA
* data
, uint32_t index
)
157 AvmAssert(data
!= NULL
);
158 return data
->entries
[index
];
161 REALLY_INLINE
/*static*/ void GCListHelper::store(LISTDATA
* data
, uint32_t index
, TYPE value
)
163 AvmAssert(data
!= NULL
);
164 WB(data
->gc(), data
, &data
->entries
[index
], value
);
167 REALLY_INLINE
/*static*/ void GCListHelper::storeInEmpty(LISTDATA
* data
, uint32_t index
, TYPE value
)
169 AvmAssert(data
!= NULL
);
170 AvmAssert(data
->entries
[index
] == 0);
171 WB(data
->gc(), data
, &data
->entries
[index
], value
);
174 REALLY_INLINE
/*static*/ void GCListHelper::clearRange(LISTDATA
* data
, uint32_t start
, uint32_t count
)
176 AvmAssert(count
> 0);
177 VMPI_memset(&data
->entries
[start
], 0, count
*sizeof(MMgc::GCObject
*));
180 REALLY_INLINE
/*static*/ void GCListHelper::moveRange(LISTDATA
* data
, uint32_t srcStart
, uint32_t dstStart
, uint32_t count
)
182 AvmAssert(data
!= NULL
);
183 data
->gc()->movePointersWithinBlock((void**)data
,
184 uint32_t((char*)(&data
->entries
[dstStart
]) - (char*)data
),
185 uint32_t((char*)(&data
->entries
[srcStart
]) - (char*)data
),
187 /*zeroEmptied*/ true);
190 REALLY_INLINE
/*static*/ void GCListHelper::gcTrace(MMgc::GC
* gc
, LISTDATA
** loc
)
192 gc
->TraceLocation(loc
);
195 // ----------------------------
197 REALLY_INLINE
/*static*/ void RCListHelper::wbData(const void* container
, LISTDATA
** address
, LISTDATA
* data
)
199 MMgc::GC
* const gc
= data
->gc();
200 if (gc
->IsPointerToGCPage(container
))
202 WB(gc
, gc
->FindBeginningFast(container
), address
, data
);
210 REALLY_INLINE
/*static*/ RCListHelper::TYPE
RCListHelper::load(LISTDATA
* data
, uint32_t index
)
212 AvmAssert(data
!= NULL
);
213 return data
->entries
[index
];
216 REALLY_INLINE
/*static*/ void RCListHelper::store(LISTDATA
* data
, uint32_t index
, TYPE value
)
218 AvmAssert(data
!= NULL
);
219 WBRC(data
->gc(), data
, &data
->entries
[index
], value
);
222 REALLY_INLINE
/*static*/ void RCListHelper::storeInEmpty(LISTDATA
* data
, uint32_t index
, TYPE value
)
224 AvmAssert(data
!= NULL
);
225 AvmAssert(data
->entries
[index
] == 0);
226 // We can't use WriteBarrierRC_ctor here, as it will call GetGC() on the address, which might be
227 // wrong if the allocation is large. Instead, replicate the necessary code inline (ugh) in
228 // the tradition of AvmCore::atomWriteBarrier_ctor...
231 if (data
->gc()->BarrierActive())
232 data
->gc()->InlineWriteBarrierTrap(data
);
233 value
->IncrementRef();
234 data
->entries
[index
] = value
;
238 REALLY_INLINE
/*static*/ void RCListHelper::clearRange(LISTDATA
* data
, uint32_t start
, uint32_t count
)
240 AvmAssert(count
> 0);
241 for (uint32_t i
= start
, n
= start
+ count
; i
< n
; i
++)
243 if (data
->entries
[i
])
245 data
->entries
[i
]->DecrementRef();
246 data
->entries
[i
] = 0;
251 REALLY_INLINE
/*static*/ void RCListHelper::moveRange(LISTDATA
* data
, uint32_t srcStart
, uint32_t dstStart
, uint32_t count
)
253 AvmAssert(data
!= NULL
);
254 data
->gc()->movePointersWithinBlock((void**)data
,
255 uint32_t((char*)(&data
->entries
[dstStart
]) - (char*)data
),
256 uint32_t((char*)(&data
->entries
[srcStart
]) - (char*)data
),
258 /*zeroEmptied*/ true);
261 REALLY_INLINE
/*static*/ void RCListHelper::gcTrace(MMgc::GC
* gc
, LISTDATA
** loc
)
263 gc
->TraceLocation(loc
);
266 // ----------------------------
268 REALLY_INLINE
/*static*/ void AtomListHelper::wbData(const void* container
, LISTDATA
** address
, LISTDATA
* data
)
270 MMgc::GC
* const gc
= data
->gc();
271 if (gc
->IsPointerToGCPage(container
))
273 WB(gc
, gc
->FindBeginningFast(container
), address
, data
);
281 REALLY_INLINE
/*static*/ AtomListHelper::TYPE
AtomListHelper::load(LISTDATA
* data
, uint32_t index
)
283 AvmAssert(data
!= NULL
);
284 return data
->entries
[index
];
287 REALLY_INLINE
/*static*/ void AtomListHelper::store(LISTDATA
* data
, uint32_t index
, TYPE value
)
289 AvmAssert(data
!= NULL
);
290 AvmCore::atomWriteBarrier(data
->gc(), data
, &data
->entries
[index
], value
);
293 REALLY_INLINE
/*static*/ void AtomListHelper::storeInEmpty(LISTDATA
* data
, uint32_t index
, TYPE value
)
295 AvmAssert(data
!= NULL
);
296 // newly-allocated space clears to 0; clearRange() clears to nullObjectAtom.
297 // Both are "empty" as far as AtomList is concerned.
298 AvmAssert(data
->entries
[index
] == 0 || data
->entries
[index
] == nullObjectAtom
);
299 AvmCore::atomWriteBarrier_ctor(data
->gc(), data
, &data
->entries
[index
], value
);
302 REALLY_INLINE
/*static*/ void AtomListHelper::clearRange(LISTDATA
* data
, uint32_t start
, uint32_t count
)
304 AvmAssert(count
> 0);
305 AvmCore::decrementAtomRegion_null(&data
->entries
[start
], count
);
308 REALLY_INLINE
/*static*/ void AtomListHelper::moveRange(LISTDATA
* data
, uint32_t srcStart
, uint32_t dstStart
, uint32_t count
)
310 AvmAssert(data
!= NULL
);
311 data
->gc()->movePointersWithinBlock((void**)data
,
312 uint32_t((char*)(&data
->entries
[dstStart
]) - (char*)data
),
313 uint32_t((char*)(&data
->entries
[srcStart
]) - (char*)data
),
315 /*zeroEmptied*/ true);
318 REALLY_INLINE
/*static*/ void AtomListHelper::gcTrace(MMgc::GC
* gc
, LISTDATA
** loc
)
320 gc
->TraceLocation(loc
);
323 // ----------------------------
325 REALLY_INLINE
/*static*/ void WeakRefListHelper::wbData(const void* container
, LISTDATA
** address
, LISTDATA
* data
)
327 MMgc::GC
* const gc
= data
->gc();
328 if (gc
->IsPointerToGCPage(container
))
330 WB(gc
, gc
->FindBeginningFast(container
), address
, data
);
338 REALLY_INLINE
/*static*/ WeakRefListHelper::TYPE
WeakRefListHelper::load(LISTDATA
* data
, uint32_t index
)
340 AvmAssert(data
!= NULL
);
341 MMgc::GCWeakRef
* weak
= data
->entries
[index
];
342 return weak
? (TYPE
)weak
->get() : NULL
;
345 REALLY_INLINE
/*static*/ void WeakRefListHelper::store(LISTDATA
* data
, uint32_t index
, TYPE value
)
347 AvmAssert(data
!= NULL
);
348 MMgc::GCWeakRef
* weak
= value
? value
->GetWeakRef() : NULL
;
349 WB(data
->gc(), data
, &data
->entries
[index
], weak
);
352 REALLY_INLINE
/*static*/ void WeakRefListHelper::storeInEmpty(LISTDATA
* data
, uint32_t index
, TYPE value
)
354 AvmAssert(data
!= NULL
);
355 AvmAssert(data
->entries
[index
] == 0);
356 store(data
, index
, value
);
359 REALLY_INLINE
/*static*/ void WeakRefListHelper::clearRange(LISTDATA
* data
, uint32_t start
, uint32_t count
)
361 AvmAssert(count
> 0);
362 VMPI_memset(&data
->entries
[start
], 0, count
*sizeof(STORAGE
));
365 REALLY_INLINE
/*static*/ void WeakRefListHelper::moveRange(LISTDATA
* data
, uint32_t srcStart
, uint32_t dstStart
, uint32_t count
)
367 AvmAssert(data
!= NULL
);
368 data
->gc()->movePointersWithinBlock((void**)data
,
369 uint32_t((char*)(&data
->entries
[dstStart
]) - (char*)data
),
370 uint32_t((char*)(&data
->entries
[srcStart
]) - (char*)data
),
372 /*zeroEmptied*/ true);
375 REALLY_INLINE
/*static*/ void WeakRefListHelper::gcTrace(MMgc::GC
* gc
, LISTDATA
** loc
)
377 gc
->TraceLocation(loc
);
380 // ----------------------------
382 template<class T
, class ListHelper
>
383 REALLY_INLINE
bool ListImpl
<T
,ListHelper
>::isEmpty() const
385 return m_data
->len
== 0;
388 template<class T
, class ListHelper
>
389 REALLY_INLINE
uint32_t ListImpl
<T
,ListHelper
>::length() const
394 template<class T
, class ListHelper
>
395 REALLY_INLINE
uint32_t ListImpl
<T
,ListHelper
>::capacity() const
397 return uint32_t((ListHelper::LISTDATA::getSize(m_data
) - offsetof(typename
ListHelper::LISTDATA
, entries
)) /
398 sizeof(typename
ListHelper::STORAGE
));
401 template<class T
, class ListHelper
>
402 REALLY_INLINE T ListImpl
<T
,ListHelper
>::get(uint32_t index
) const
404 AvmAssert(index
< m_data
->len
);
405 return ListHelper::load(m_data
, index
);
408 template<class T
, class ListHelper
>
409 REALLY_INLINE
void ListImpl
<T
,ListHelper
>::replace(uint32_t index
, T value
)
411 AvmAssert(index
< m_data
->len
);
412 ListHelper::store(m_data
, index
, value
);
415 template<class T
, class ListHelper
>
416 REALLY_INLINE
void ListImpl
<T
,ListHelper
>::set(uint32_t index
, T value
)
418 // Yes, this is worth inlining, according to performance testing.
419 if (index
>= m_data
->len
)
421 ensureCapacityExtra(index
, 1);
422 m_data
->len
= index
+1;
424 ListHelper::store(m_data
, index
, value
);
427 template<class T
, class ListHelper
>
428 REALLY_INLINE T ListImpl
<T
,ListHelper
>::first() const
430 AvmAssert(m_data
->len
> 0);
431 return ListHelper::load(m_data
, 0);
434 template<class T
, class ListHelper
>
435 REALLY_INLINE T ListImpl
<T
,ListHelper
>::last() const
437 AvmAssert(m_data
->len
> 0);
438 return ListHelper::load(m_data
, m_data
->len
-1);
441 template<class T
, class ListHelper
>
442 REALLY_INLINE T ListImpl
<T
,ListHelper
>::removeFirst()
444 AvmAssert(!isEmpty());
448 template<class T
, class ListHelper
>
449 REALLY_INLINE T ListImpl
<T
,ListHelper
>::operator[](uint32_t index
) const
451 AvmAssert(index
< m_data
->len
);
452 return ListHelper::load(m_data
, index
);
455 template<class T
, class ListHelper
>
456 REALLY_INLINE
void ListImpl
<T
,ListHelper
>::ensureCapacityExtra(uint32_t cap
, uint32_t extra
)
458 MMGC_STATIC_ASSERT(0xFFFFFFFF > kListMaxLength
);
459 uint32_t const ncap
= (cap
> 0xFFFFFFFF - extra
) ? // if true, cap + extra will overflow a uint32_t...
460 0xFFFFFFFF : // ...in that case, choose a size that will definitely fail in ensureCapacityImpl.
463 if (ncap
> capacity())
465 ensureCapacityImpl(ncap
);
469 template<class T
, class ListHelper
>
470 REALLY_INLINE
void ListImpl
<T
,ListHelper
>::ensureCapacity(uint32_t cap
)
472 AvmAssert(m_data
!= NULL
);
473 if (cap
> capacity())
475 ensureCapacityImpl(cap
);
479 template<class T
, class ListHelper
>
480 REALLY_INLINE
uint64_t ListImpl
<T
,ListHelper
>::bytesUsed() const
482 AvmAssert(m_data
!= NULL
);
483 return ListHelper::LISTDATA::getSize(m_data
);
486 template<class T
, class ListHelper
>
487 REALLY_INLINE
/*static*/ typename
ListHelper::LISTDATA
* ListImpl
<T
,ListHelper
>::allocData(MMgc::GC
* gc
, uint32_t cap
)
489 AvmAssert(cap
<= kListMaxLength
);
490 typename
ListHelper::LISTDATA
* newData
= ListHelper::LISTDATA::create(gc
, cap
);
496 template<class T
, class ListHelper
>
497 REALLY_INLINE
void ListImpl
<T
,ListHelper
>::skipDestructor()
499 // Note that we explicitly do not attempt to free the data here;
500 // this method should only be called in situations where we
501 // know that MMGC has already been torn down, thus an attempt
502 // to free the data would be unsafe.
506 // ----------------------------
510 REALLY_INLINE GCList
<T
>::GCList(MMgc::GC
* gc
, uint32_t capacity
, const TYPE
* args
)
511 : m_list(gc
, capacity
, (MMgc::GCObject
* const*)args
)
513 MMGC_STATIC_ASSERT((TypeSniffer
<T
>::isGCObject::value
== true ||
514 TypeSniffer
<T
>::isGCFinalizedObject::value
== true ||
515 TypeSniffer
<T
>::isGCTraceableObject::value
== true) &&
516 TypeSniffer
<T
>::isRCObject::value
== false);
517 MMGC_STATIC_ASSERT(TypeSniffer
<T
>::isNonPointer::value
== true);
521 REALLY_INLINE
bool GCList
<T
>::isEmpty() const
523 return m_list
.isEmpty();
527 REALLY_INLINE
uint32_t GCList
<T
>::length() const
529 return m_list
.length();
533 REALLY_INLINE
uint32_t GCList
<T
>::capacity() const
535 return m_list
.capacity();
539 REALLY_INLINE typename GCList
<T
>::TYPE GCList
<T
>::get(uint32_t index
) const
541 return reinterpret_cast<TYPE
>(m_list
.get(index
));
545 REALLY_INLINE typename GCList
<T
>::TYPE GCList
<T
>::first() const
547 return reinterpret_cast<TYPE
>(m_list
.first());
551 REALLY_INLINE typename GCList
<T
>::TYPE GCList
<T
>::last() const
553 return reinterpret_cast<TYPE
>(m_list
.last());
557 REALLY_INLINE
void GCList
<T
>::replace(uint32_t index
, TYPE value
)
559 m_list
.replace(index
, reinterpret_cast<MMgc::GCObject
*>(value
));
563 REALLY_INLINE
void GCList
<T
>::set(uint32_t index
, TYPE value
)
565 m_list
.set(index
, reinterpret_cast<MMgc::GCObject
*>(value
));
569 REALLY_INLINE
void GCList
<T
>::add(TYPE value
)
571 m_list
.add(reinterpret_cast<MMgc::GCObject
*>(value
));
575 REALLY_INLINE
void GCList
<T
>::add(const GCList
<T
>& that
)
577 m_list
.add(*(const LIST
*)&that
);
581 REALLY_INLINE
void GCList
<T
>::insert(uint32_t index
, TYPE value
, uint32_t count
)
583 m_list
.insert(index
, reinterpret_cast<MMgc::GCObject
*>(value
), count
);
587 REALLY_INLINE
void GCList
<T
>::insert(uint32_t index
, const TYPE
* args
, uint32_t argc
)
589 m_list
.insert(index
, args
, argc
);
593 REALLY_INLINE
void GCList
<T
>::splice(uint32_t insertPoint
, uint32_t insertCount
, uint32_t deleteCount
, const TYPE
* args
)
595 m_list
.splice(insertPoint
, insertCount
, deleteCount
, args
);
599 REALLY_INLINE
void GCList
<T
>::splice(uint32_t insertPoint
, uint32_t insertCount
, uint32_t deleteCount
, const GCList
<T
>& args
, uint32_t argsOffset
)
601 m_list
.splice(insertPoint
, insertCount
, deleteCount
, args
, argsOffset
);
605 REALLY_INLINE
void GCList
<T
>::reverse()
611 REALLY_INLINE
void GCList
<T
>::clear()
617 REALLY_INLINE
int32_t GCList
<T
>::indexOf(TYPE value
) const
619 return m_list
.indexOf(reinterpret_cast<MMgc::GCObject
*>(value
));
623 REALLY_INLINE
int32_t GCList
<T
>::lastIndexOf(TYPE value
) const
625 return m_list
.lastIndexOf(reinterpret_cast<MMgc::GCObject
*>(value
));
629 REALLY_INLINE typename GCList
<T
>::TYPE GCList
<T
>::removeAt(uint32_t index
)
631 return reinterpret_cast<TYPE
>(m_list
.removeAt(index
));
635 REALLY_INLINE typename GCList
<T
>::TYPE GCList
<T
>::removeFirst()
637 return reinterpret_cast<TYPE
>(m_list
.removeFirst());
641 REALLY_INLINE typename GCList
<T
>::TYPE GCList
<T
>::removeLast()
643 return reinterpret_cast<TYPE
>(m_list
.removeLast());
647 REALLY_INLINE typename GCList
<T
>::TYPE GCList
<T
>::operator[](uint32_t index
) const
649 return reinterpret_cast<TYPE
>(m_list
[index
]);
653 REALLY_INLINE
void GCList
<T
>::ensureCapacity(uint32_t cap
)
655 m_list
.ensureCapacity(cap
);
659 REALLY_INLINE
uint64_t GCList
<T
>::bytesUsed() const
661 return m_list
.bytesUsed();
665 REALLY_INLINE
void GCList
<T
>::skipDestructor()
667 m_list
.skipDestructor();
671 REALLY_INLINE
void GCList
<T
>::gcTrace(MMgc::GC
* gc
)
676 // ----------------------------
679 REALLY_INLINE RCList
<T
>::RCList(MMgc::GC
* gc
, uint32_t capacity
, const TYPE
* args
)
680 : m_list(gc
, capacity
, (MMgc::RCObject
* const*)args
)
682 MMGC_STATIC_ASSERT(TypeSniffer
<T
>::isRCObject::value
== true);
683 MMGC_STATIC_ASSERT(TypeSniffer
<T
>::isNonPointer::value
== true);
687 REALLY_INLINE
bool RCList
<T
>::isEmpty() const
689 return m_list
.isEmpty();
693 REALLY_INLINE
uint32_t RCList
<T
>::length() const
695 return m_list
.length();
699 REALLY_INLINE
uint32_t RCList
<T
>::capacity() const
701 return m_list
.capacity();
705 REALLY_INLINE typename RCList
<T
>::TYPE RCList
<T
>::get(uint32_t index
) const
707 return reinterpret_cast<TYPE
>(m_list
.get(index
));
711 REALLY_INLINE typename RCList
<T
>::TYPE RCList
<T
>::first() const
713 return reinterpret_cast<TYPE
>(m_list
.first());
717 REALLY_INLINE typename RCList
<T
>::TYPE RCList
<T
>::last() const
719 return reinterpret_cast<TYPE
>(m_list
.last());
723 REALLY_INLINE
void RCList
<T
>::replace(uint32_t index
, TYPE value
)
725 m_list
.replace(index
, value
);
729 REALLY_INLINE
void RCList
<T
>::set(uint32_t index
, TYPE value
)
731 m_list
.set(index
, value
);
735 REALLY_INLINE
void RCList
<T
>::add(TYPE value
)
741 REALLY_INLINE
void RCList
<T
>::add(const RCList
<T
>& that
)
743 m_list
.add(*(const LIST
*)&that
);
747 REALLY_INLINE
void RCList
<T
>::insert(uint32_t index
, TYPE value
, uint32_t count
)
749 m_list
.insert(index
, value
, count
);
753 REALLY_INLINE
void RCList
<T
>::insert(uint32_t index
, const TYPE
* args
, uint32_t argc
)
755 m_list
.insert(index
, args
, argc
);
759 REALLY_INLINE
void RCList
<T
>::splice(uint32_t insertPoint
, uint32_t insertCount
, uint32_t deleteCount
, const TYPE
* args
)
761 m_list
.splice(insertPoint
, insertCount
, deleteCount
, args
);
765 REALLY_INLINE
void RCList
<T
>::splice(uint32_t insertPoint
, uint32_t insertCount
, uint32_t deleteCount
, const RCList
<T
>& args
, uint32_t argsOffset
)
767 m_list
.splice(insertPoint
, insertCount
, deleteCount
, args
, argsOffset
);
771 REALLY_INLINE
void RCList
<T
>::reverse()
777 REALLY_INLINE
void RCList
<T
>::clear()
783 REALLY_INLINE
int32_t RCList
<T
>::indexOf(TYPE value
) const
785 return m_list
.indexOf(value
);
789 REALLY_INLINE
int32_t RCList
<T
>::lastIndexOf(TYPE value
) const
791 return m_list
.lastIndexOf(value
);
795 REALLY_INLINE typename RCList
<T
>::TYPE RCList
<T
>::removeAt(uint32_t index
)
797 return reinterpret_cast<TYPE
>(m_list
.removeAt(index
));
801 REALLY_INLINE typename RCList
<T
>::TYPE RCList
<T
>::removeFirst()
803 return reinterpret_cast<TYPE
>(m_list
.removeFirst());
807 REALLY_INLINE typename RCList
<T
>::TYPE RCList
<T
>::removeLast()
809 return reinterpret_cast<TYPE
>(m_list
.removeLast());
813 REALLY_INLINE typename RCList
<T
>::TYPE RCList
<T
>::operator[](uint32_t index
) const
815 return reinterpret_cast<TYPE
>(m_list
[index
]);
819 REALLY_INLINE
void RCList
<T
>::ensureCapacity(uint32_t cap
)
821 m_list
.ensureCapacity(cap
);
825 REALLY_INLINE
uint64_t RCList
<T
>::bytesUsed() const
827 return m_list
.bytesUsed();
831 REALLY_INLINE
void RCList
<T
>::skipDestructor()
833 m_list
.skipDestructor();
837 REALLY_INLINE
void RCList
<T
>::gcTrace(MMgc::GC
* gc
)
843 // ----------------------------
846 REALLY_INLINE UnmanagedPointerList
<T
>::UnmanagedPointerList(MMgc::GC
* gc
, uint32_t capacity
, const T
* args
)
847 : m_list(gc
, capacity
, (const UnmanagedPointer
*)args
)
849 // We must not be a GC/RCObject.
850 MMGC_STATIC_ASSERT(TypeSniffer
<T
>::isGCObject::value
== false &&
851 TypeSniffer
<T
>::isGCFinalizedObject::value
== false &&
852 TypeSniffer
<T
>::isRCObject::value
== false &&
853 TypeSniffer
<T
>::isGCTraceableObject::value
== false);
855 // BUT we MUST be a pointer type.
856 MMGC_STATIC_ASSERT(TypeSniffer
<T
>::isNonPointer::value
== false);
860 REALLY_INLINE
bool UnmanagedPointerList
<T
>::isEmpty() const
862 return m_list
.isEmpty();
866 REALLY_INLINE
uint32_t UnmanagedPointerList
<T
>::length() const
868 return m_list
.length();
872 REALLY_INLINE
uint32_t UnmanagedPointerList
<T
>::capacity() const
874 return m_list
.capacity();
878 REALLY_INLINE T UnmanagedPointerList
<T
>::get(uint32_t index
) const
880 return (T
)m_list
.get(index
);
884 REALLY_INLINE T UnmanagedPointerList
<T
>::first() const
886 return (T
)m_list
.first();
890 REALLY_INLINE T UnmanagedPointerList
<T
>::last() const
892 return (T
)m_list
.last();
896 REALLY_INLINE
void UnmanagedPointerList
<T
>::replace(uint32_t index
, T value
)
898 m_list
.replace(index
, (UnmanagedPointer
)value
);
902 REALLY_INLINE
void UnmanagedPointerList
<T
>::set(uint32_t index
, T value
)
904 m_list
.set(index
, (UnmanagedPointer
)value
);
908 REALLY_INLINE
void UnmanagedPointerList
<T
>::add(T value
)
910 m_list
.add((UnmanagedPointer
)value
);
914 REALLY_INLINE
void UnmanagedPointerList
<T
>::add(const UnmanagedPointerList
<T
>& that
)
916 m_list
.add(*(const LIST
*)&that
);
920 REALLY_INLINE
void UnmanagedPointerList
<T
>::insert(uint32_t index
, T value
, uint32_t count
)
922 m_list
.insert(index
, (UnmanagedPointer
)value
, count
);
926 REALLY_INLINE
void UnmanagedPointerList
<T
>::insert(uint32_t index
, const T
* args
, uint32_t argc
)
928 m_list
.insert(index
, args
, argc
);
932 REALLY_INLINE
void UnmanagedPointerList
<T
>::splice(uint32_t insertPoint
, uint32_t insertCount
, uint32_t deleteCount
, const T
* args
)
934 m_list
.splice(insertPoint
, insertCount
, deleteCount
, args
);
938 REALLY_INLINE
void UnmanagedPointerList
<T
>::splice(uint32_t insertPoint
, uint32_t insertCount
, uint32_t deleteCount
, const UnmanagedPointerList
<T
>& args
, uint32_t argsOffset
)
940 m_list
.splice(insertPoint
, insertCount
, deleteCount
, args
, argsOffset
);
944 REALLY_INLINE
void UnmanagedPointerList
<T
>::reverse()
950 REALLY_INLINE
void UnmanagedPointerList
<T
>::clear()
956 REALLY_INLINE
int32_t UnmanagedPointerList
<T
>::indexOf(T value
) const
958 return m_list
.indexOf((UnmanagedPointer
)value
);
962 REALLY_INLINE
int32_t UnmanagedPointerList
<T
>::lastIndexOf(T value
) const
964 return m_list
.lastIndexOf((UnmanagedPointer
)value
);
968 REALLY_INLINE T UnmanagedPointerList
<T
>::removeAt(uint32_t index
)
970 return (T
)m_list
.removeAt(index
);
974 REALLY_INLINE T UnmanagedPointerList
<T
>::removeFirst()
976 return (T
)m_list
.removeFirst();
980 REALLY_INLINE T UnmanagedPointerList
<T
>::removeLast()
982 return (T
)m_list
.removeLast();
986 REALLY_INLINE T UnmanagedPointerList
<T
>::operator[](uint32_t index
) const
988 return (T
)m_list
[index
];
992 REALLY_INLINE
void UnmanagedPointerList
<T
>::ensureCapacity(uint32_t cap
)
994 m_list
.ensureCapacity(cap
);
998 REALLY_INLINE
uint64_t UnmanagedPointerList
<T
>::bytesUsed() const
1000 return m_list
.bytesUsed();
1004 REALLY_INLINE
void UnmanagedPointerList
<T
>::skipDestructor()
1006 m_list
.skipDestructor();
1010 REALLY_INLINE
void UnmanagedPointerList
<T
>::gcTrace(MMgc::GC
* gc
)
1015 // ----------------------------
1018 REALLY_INLINE WeakRefList
<T
>::WeakRefList(MMgc::GC
* gc
, uint32_t capacity
, const TYPE
* args
)
1019 : m_list(gc
, capacity
, (MMgc::GCObject
* const*)args
)
1021 MMGC_STATIC_ASSERT(TypeSniffer
<T
>::isGCObject::value
||
1022 TypeSniffer
<T
>::isGCFinalizedObject::value
||
1023 TypeSniffer
<T
>::isRCObject::value
||
1024 TypeSniffer
<T
>::isGCTraceableObject::value
);
1025 MMGC_STATIC_ASSERT(TypeSniffer
<T
>::isNonPointer::value
== true);
1029 REALLY_INLINE
bool WeakRefList
<T
>::isEmpty() const
1031 return m_list
.isEmpty();
1035 REALLY_INLINE
uint32_t WeakRefList
<T
>::length() const
1037 return m_list
.length();
1041 REALLY_INLINE
uint32_t WeakRefList
<T
>::capacity() const
1043 return m_list
.capacity();
1047 REALLY_INLINE typename WeakRefList
<T
>::TYPE WeakRefList
<T
>::get(uint32_t index
) const
1049 return reinterpret_cast<TYPE
>(m_list
.get(index
));
1053 REALLY_INLINE typename WeakRefList
<T
>::TYPE WeakRefList
<T
>::first() const
1055 return reinterpret_cast<TYPE
>(m_list
.first());
1059 REALLY_INLINE typename WeakRefList
<T
>::TYPE WeakRefList
<T
>::last() const
1061 return reinterpret_cast<TYPE
>(m_list
.last());
1065 REALLY_INLINE
void WeakRefList
<T
>::replace(uint32_t index
, TYPE value
)
1067 m_list
.replace(index
, to_gc(value
));
1071 REALLY_INLINE
void WeakRefList
<T
>::set(uint32_t index
, TYPE value
)
1073 m_list
.set(index
, reinterpret_cast<MMgc::GCObject
*>(value
));
1077 REALLY_INLINE
void WeakRefList
<T
>::add(TYPE value
)
1079 m_list
.add(reinterpret_cast<MMgc::GCObject
*>(value
));
1083 REALLY_INLINE
void WeakRefList
<T
>::add(const WeakRefList
<T
>& that
)
1085 m_list
.add(*(const LIST
*)&that
);
1089 REALLY_INLINE
void WeakRefList
<T
>::insert(uint32_t index
, TYPE value
, uint32_t count
)
1091 m_list
.insert(index
, reinterpret_cast<MMgc::GCObject
*>(value
), count
);
1095 REALLY_INLINE
void WeakRefList
<T
>::insert(uint32_t index
, const TYPE
* args
, uint32_t argc
)
1097 m_list
.insert(index
, args
, argc
);
1101 REALLY_INLINE
void WeakRefList
<T
>::splice(uint32_t insertPoint
, uint32_t insertCount
, uint32_t deleteCount
, const TYPE
* args
)
1103 m_list
.splice(insertPoint
, insertCount
, deleteCount
, args
);
1107 REALLY_INLINE
void WeakRefList
<T
>::splice(uint32_t insertPoint
, uint32_t insertCount
, uint32_t deleteCount
, const WeakRefList
<T
>& args
, uint32_t argsOffset
)
1109 m_list
.splice(insertPoint
, insertCount
, deleteCount
, args
, argsOffset
);
1113 REALLY_INLINE
void WeakRefList
<T
>::reverse()
1119 REALLY_INLINE
void WeakRefList
<T
>::clear()
1125 REALLY_INLINE
int32_t WeakRefList
<T
>::indexOf(TYPE value
) const
1127 return m_list
.indexOf(reinterpret_cast<MMgc::GCObject
*>(value
));
1131 REALLY_INLINE
int32_t WeakRefList
<T
>::lastIndexOf(TYPE value
) const
1133 return m_list
.lastIndexOf(reinterpret_cast<MMgc::GCObject
*>(value
));
1137 REALLY_INLINE typename WeakRefList
<T
>::TYPE WeakRefList
<T
>::removeAt(uint32_t index
)
1139 return reinterpret_cast<TYPE
>(m_list
.removeAt(index
));
1143 REALLY_INLINE typename WeakRefList
<T
>::TYPE WeakRefList
<T
>::removeFirst()
1145 return reinterpret_cast<TYPE
>(m_list
.removeFirst());
1149 REALLY_INLINE typename WeakRefList
<T
>::TYPE WeakRefList
<T
>::removeLast()
1151 return reinterpret_cast<TYPE
>(m_list
.removeLast());
1155 REALLY_INLINE typename WeakRefList
<T
>::TYPE WeakRefList
<T
>::operator[](uint32_t index
) const
1157 return reinterpret_cast<TYPE
>(m_list
[index
]);
1161 REALLY_INLINE
void WeakRefList
<T
>::ensureCapacity(uint32_t cap
)
1163 m_list
.ensureCapacity(cap
);
1167 REALLY_INLINE
uint64_t WeakRefList
<T
>::bytesUsed() const
1169 return m_list
.bytesUsed();
1173 REALLY_INLINE
void WeakRefList
<T
>::skipDestructor()
1175 m_list
.skipDestructor();
1179 REALLY_INLINE
uint32_t WeakRefList
<T
>::removeCollectedItems()
1181 return m_list
.removeNullItems();
1185 REALLY_INLINE
void WeakRefList
<T
>::gcTrace(MMgc::GC
* gc
)
1190 // ----------------------------
1193 REALLY_INLINE DataList
<T
>::DataList(MMgc::GC
* gc
, uint32_t capacity
, const T
* args
)
1194 : ListImpl
< T
, DataListHelper
<T
> >(gc
, capacity
, args
)
1196 // We must not be a pointer type.
1197 MMGC_STATIC_ASSERT(TypeSniffer
<T
>::isNonPointer::value
== true);
1199 // If you make a NonGCObject list that holds GC/RCObjects, you are almost
1200 // certainly making a mistake. (Redundant to the above check, but left in
1202 MMGC_STATIC_ASSERT(TypeSniffer
<T
>::isGCObject::value
== false &&
1203 TypeSniffer
<T
>::isGCFinalizedObject::value
== false &&
1204 TypeSniffer
<T
>::isRCObject::value
== false &&
1205 TypeSniffer
<T
>::isGCTraceableObject::value
== false);
1208 // ----------------------------
1211 REALLY_INLINE DataListAccessor
<T
>::DataListAccessor(DataList
<T
>* v
) : m_list(v
)
1216 REALLY_INLINE T
* DataListAccessor
<T
>::addr()
1218 return (m_list
!= NULL
) ? m_list
->m_data
->entries
: (T
*)NULL
;
1222 REALLY_INLINE
uint32_t DataListAccessor
<T
>::length()
1224 return (m_list
!= NULL
) ? m_list
->length() : 0;
1227 // ----------------------------
1230 REALLY_INLINE HeapList
<T
>::HeapList(MMgc::GC
* gc
, uint32_t capacity
, const typename
T::TYPE
* args
)
1231 : list(gc
, capacity
, args
)
1236 #endif /* __avmplus_List_inlines__ */