merge from argo
[tamarin-stm.git] / MMgc / ZCT.cpp
blob52206561c924627548dfa96c05a99faf0ec9d454
1 /* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 4 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
15 * The Original Code is [Open Source Virtual Machine.].
17 * The Initial Developer of the Original Code is
18 * Adobe System Incorporated.
19 * Portions created by the Initial Developer are Copyright (C) 2004-2006
20 * the Initial Developer. All Rights Reserved.
22 * Contributor(s):
23 * Adobe AS3 Team
24 * leon.sha@sun.com
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 #include "MMgc.h"
41 #include "StaticAssert.h"
43 #ifdef AVMPLUS_SAMPLER
44 //sampling support
45 #include "avmplus.h"
46 #else
47 #define SAMPLE_FRAME(_x, _s)
48 #define SAMPLE_CHECK()
49 #endif
51 //#define ZCT_TESTING // Test the handling of a failure to extend the ZCT
53 namespace MMgc
55 /* The ZCT is implemented as a two-level table. Given a ZCT index, the
56 * first-level table (indexed by the high bits of the index) yields a
57 * second-level table (indexed by the low bits) that contains a pointer to the
58 * entry. The entry is an RCObject*. The RCObject has a header field,
59 * ZCT_INDEX, which is the index at which the pointer is found, and a flag
60 * stating whether that index is valid (ie whether the object is in the ZCT).
62 * The ZCT_INDEX field is 20 bits wide; thus it may be possible that some
63 * objects cannot be entered into the ZCT. This is OK, as the garbage
64 * collector will reclaim any unreachable objects eventually anyway. (Some
65 * test programs in the acceptance tests actually run into this problem.)
67 * RCObjects whose reference counts are zero are added to the ZCT by being
68 * passed to ZCT::Add(); they are removed by being passed to ZCT::Remove() if
69 * their reference counts transition from 0 to 1, and when the object
70 * is destroyed. This is all taken care of in RCObject's constructor,
71 * destructor, and reference counting operations. See GCObject.h.
73 * Every RCObject is added to the ZCT on creation; 10%-25% are subsequently
74 * removed as their reference counts transition from 0 to 1. Very few are
75 * removed as objects are destroyed; the bulk are removed by the reaper because
76 * the objects are not pinned. (Based on profiling some Flash apps, July 2009.)
78 * ZCT::Add() has a fast path that can be in-lined: it checks a pointer against
79 * a limit, stores the object in the table, bumps the pointer, stores the
80 * index in the object and sets the object's ZCT flag.
82 * ZCT::Remove() only has a fast path: it clears the table entry and clears the
83 * ZCT flag in the object. NULL entries in the table are recovered during
84 * reaping.
87 * Useful invariants:
89 * - gc->collecting and zct.reaping are never both true at the same time. This
90 * is ensured by GC::FinishIncrementalMark returning immediately if zct.reaping
91 * is true, and by ZCT::Reap returning immediately if gc->collecting is true.
93 * - There are never any free blocks beyond the 'current' block (the one pointed
94 * into by top or slowTop) in the ZCT. During reaping, once the ZCT is popped
95 * below a block the block is removed from the ZCT and added to an empty blocks
96 * pool.
98 * - The ZCT will honor calls to Pin() from prereap() but not necessarily any
99 * calls to Pin() earlier than that. When an object is added to the ZCT its
100 * pinned flag is cleared. (This is consistent with the old ZCT code.)
103 #ifdef ZCT_TESTING
104 // Max number less 1 of blocks the ZCT may use for the second level of the block table
105 // as well as the pinned table during reaping.
106 static uint32_t zct_allowance = 0;
107 #endif
109 ZCT::ZCT()
110 : gc(NULL)
111 , blocktable(NULL)
112 , blocktop(NULL)
113 , reaping(false)
114 , budget(0)
115 , bottom(NULL)
116 , top(NULL)
117 , limit(NULL)
118 , topIndex(0)
119 , slowState(false)
120 , slowBottom(NULL)
121 , slowTop(NULL)
122 , slowLimit(NULL)
123 , slowTopIndex(0)
124 , pinTop(NULL)
125 , pinLimit(NULL)
126 , pinIndex(0)
127 , pinList(0)
128 , pinLast(0)
129 , freeList(0)
133 void ZCT::SetGC(GC *gc)
135 this->gc = gc;
137 // The size of the block table is limited by the field in the RCObject header
138 // that accomodates the ZCT index. This field is currently 20 bits, so
139 // the max number of entries in the ZCT is 1M. On a 64-bit system each block
140 // holds 512 elements so the block table needs 2K entries, occupying
141 // four blocks. On a 32-bit system each block holds 1K elements so the block
142 // table needs 1K entries, occupying a single block. Instead of messing with
143 // growing the block table later, just allocate full tables here. The
144 // pointed-to blocks are still allocated on demand.
146 // This invariant is stronger than we need; we only need for the ZCT capacity
147 // to divide evenly into blocks on both 32-bit and 64-bit systems.
148 GCAssert(RCObject::ZCT_CAPACITY == 0x100000U);
150 const uint32_t numblocks = RCObject::ZCT_CAPACITY / CAPACITY(RCObject**) / CAPACITY(RCObject***);
152 blocktable = (RCObject***) GCHeap::GetGCHeap()->Alloc(numblocks); // must succeed, so use default flags
153 for ( uint32_t i=0 ; i < CAPACITY(RCObject**)*numblocks ; i++ )
154 blocktable[i] = NULL;
155 blocktable[0] = (RCObject**) GCHeap::GetGCHeap()->Alloc(1); // must succeed, so use default flags
156 blocktop = blocktable + 1;
158 budget = 0;
159 bottom = blocktable[0];
160 top = blocktable[0];
161 limit = blocktable[0] + CAPACITY(RCObject*);
162 topIndex = 0;
165 void ZCT::Destroy()
167 ClearBlockTable();
168 ClearFreeList();
169 GCHeap::GetGCHeap()->Free(blocktable);
172 void ZCT::StartCollecting()
174 GCAssert(!slowState);
176 // Transfer state to slow-path variables
177 slowState = true;
178 slowBottom = bottom;
179 slowTop = top;
180 slowLimit = limit;
181 slowTopIndex = topIndex;
183 // Create a state that triggers the slow path
184 top = limit;
187 void ZCT::EndCollecting()
189 GCAssert(slowState);
191 // Transfer the state from the slow-path variables
192 bottom = slowBottom;
193 top = slowTop;
194 limit = slowLimit;
195 topIndex = slowTopIndex;
196 slowState = false;
199 // The problem here is when a prereap(), prereap(obj), or postreap()
200 // call gets into a situation where a longjmp is made across the GC,
201 // or if the GC aborts while slowState is true (because this leaves us
202 // with broken invariants when the heap is later swept).
204 void ZCT::SignalImminentAbort()
206 // It's not necessary to unpin objects; pinned garbage will be
207 // reclaimed by the garbage collector eventually.
209 // No particular reason to clear the ZCT, the objects in it are
210 // valid.
212 if (slowState) {
213 EndCollecting();
214 ClearPinningMemory();
217 if (reaping)
218 reaping = false;
221 void ZCT::AddSlow(RCObject *obj)
223 GCAssert(top == limit);
224 GCAssert(gc->collecting + reaping < 2);
226 if(gc->collecting)
228 // This is a vestige from FP8 to fix bug 165100, it has the effect of delaying
229 // the deletion of some objects; this causes the site to work.
230 if(gc->dontAddToZCTDuringCollection)
231 return;
233 // Unmarked objects are gonna get swept anyways.
234 if(!GC::GetMark(obj))
235 return;
238 if (slowState && slowTop < slowLimit) {
239 *slowTop++ = obj;
240 obj->setZCTIndexAndMaybeUnpin(slowTopIndex++, uint32_t(reaping));
241 return;
244 // Overflow.
245 // Expand or reap? Sometimes we must grow even if the budget has been exhausted.
247 bool shouldGrow = false;
248 if (reaping)
249 shouldGrow = true;
250 else if (budget > 0 && CanGrow())
251 shouldGrow = true;
252 else {
253 // 'obj' will not be reaped as it's on the stack; we'll add it to the ZCT below.
254 Reap();
255 uint32_t avail = AvailableInCurrentSegment();
256 budget = gc->policy.queryZCTBudget(uint32_t(blocktop - blocktable));
257 if (avail == 0)
258 shouldGrow = true;
261 if (shouldGrow) {
262 GCAssert(AvailableInCurrentSegment() == 0);
263 if (!CanGrow() || !Grow())
264 return; // c'est la vie
265 if (budget > 0)
266 budget--;
267 // Grow() does not set up the state for Add(), so do that.
268 if (slowState) {
269 slowBottom = blocktop[-1];
270 slowTop = slowBottom;
271 slowLimit = slowBottom + CAPACITY(RCObject*);
272 GCAssert(slowTopIndex % CAPACITY(RCObject*) == 0);
274 else {
275 bottom = blocktop[-1];
276 limit = bottom + CAPACITY(RCObject*);
277 top = bottom;
278 GCAssert(topIndex % CAPACITY(RCObject*) == 0);
282 GCAssert(AvailableInCurrentSegment() > 0);
284 Add(obj); // won't fail
287 uint32_t ZCT::AvailableInCurrentSegment()
289 return slowState ? uint32_t(slowLimit - slowTop) : uint32_t(limit - top);
292 bool ZCT::CanGrow()
294 return (slowState ? slowTopIndex : topIndex) + CAPACITY(RCObject*) <= RCObject::ZCT_CAPACITY;
297 void ZCT::Reap(bool scanStack)
299 if(gc->collecting)
300 return;
302 GCAssert(!slowState);
304 // Do not reap if already reaping or if the ZCT is empty (waste of time).
305 if (reaping || topIndex == 0)
306 return;
308 reaping = true;
309 gc->policy.signal(GCPolicyManager::START_ReapZCT);
310 SAMPLE_FRAME("[reap]", gc->core());
312 uint64_t start = VMPI_getPerformanceCounter();
313 #ifdef MMGC_POLICY_PROFILING
314 uint32_t objects_pinned = 0;
315 #endif
316 uint32_t objects_reaped = 0;
317 size_t bytes_reaped = 0;
318 size_t blocks_before = gc->GetNumBlocks();
320 // Note that we must pin from root segments even if scanStack is false, because the
321 // MMGC_GC_ROOT_THREAD creates one AutoRCRootSegment that is not managed by VMPI_alloca.
322 // The root segment list should be very short if scanStack==false so performance-wise
323 // this is not a big deal.
325 // It is not necessary to pin from the mark and barrier stacks because there is a
326 // test in GC::Free that prevents queued objects from being deleted; we have to pay
327 // for that check in any case and can depend on it here.
329 // For some generally difficult problems around pinning see bugzilla #506644.
331 if (scanStack)
332 VMPI_callWithRegistersSaved(ZCT::DoPinProgramStack, this);
333 PinRootSegments();
335 // Invoke prereap on all callbacks
336 for ( GCCallback *cb = gc->m_callbacks; cb ; cb = cb->nextCB )
337 cb->prereap();
339 #ifdef _DEBUG
340 if (gc->validateDefRef)
341 VMPI_callWithRegistersSaved(ZCT::DoSetupDefRefValidation, this);
342 #endif
344 // We perform depth-first reaping using the ZCT as a stack.
346 // Popping an element off the end of the ZCT, it is either NULL, pinned, or unpinned.
347 // - If it's NULL it's ignored.
348 // - If it's pinned, it's shifted into a list of new blocks that will replace
349 // the blocks in the ZCT. The index of the object is updated.
350 // - If it's not pinned, it's reaped (which runs its finalizer, which may add
351 // more elements ot the end of the ZCT).
353 // Depth-first processing is desirable because object graphs will tend to be wider
354 // than they are deep; going depth-first reduces ZCT growth during reaping.
356 // Memory use is optimal to within a constant: space occupied by a pointer to a
357 // reaped object is released immediately, and empty segments popped off the ZCT
358 // are used for the list of replacement blocks.
360 SetupPinningMemory();
361 for (;;) {
362 SAMPLE_CHECK();
364 // Pop an element off the ZCT
365 GCAssert(bottom <= top);
366 GCAssert(top <= limit);
368 if (top == bottom) {
369 if (topIndex == 0)
370 break;
371 PopFastSegment();
373 RCObject *rcobj = *--top;
374 --topIndex;
376 // Process the element
377 if (rcobj == NULL)
379 else if (rcobj->IsPinned()) {
380 #ifdef MMGC_POLICY_PROFILING
381 objects_pinned++;
382 #endif
383 PinObject(rcobj);
385 else {
386 objects_reaped++;
387 bytes_reaped += GC::Size(rcobj);
388 ReapObject(rcobj);
391 UsePinningMemory();
393 // Invoke postreap on all callbacks
394 for ( GCCallback *cb = gc->m_callbacks; cb ; cb = cb->nextCB )
395 cb->postreap();
397 if(gc->heap->Config().gcstats && objects_reaped > 0) {
398 size_t blocks_after = gc->GetNumBlocks();
399 gc->gclog("[mem] DRC reaped %u objects (%u kb) freeing %u pages (%u kb) in %.2f millis (%.4f s)\n",
400 objects_reaped,
401 unsigned(bytes_reaped/1024),
402 unsigned(blocks_before - blocks_after),
403 unsigned(blocks_after * GCHeap::kBlockSize / 1024),
404 GC::duration(start),
405 GC::duration(gc->t0)/1000);
408 reaping = false;
410 #ifdef _DEBUG
411 for ( uint32_t i=0 ; i < topIndex ; i++ ) {
412 // The first element of each block is usually NULL because it has
413 // been used as a link for pinList.
414 if (Get(i) != NULL) {
415 GCAssert(Get(i)->getZCTIndex() == i);
416 GCAssert(!Get(i)->IsPinned());
419 if (gc->validateDefRef)
420 FinishDefRefValidation();
421 #endif
423 #ifdef MMGC_POLICY_PROFILING
424 gc->policy.signalReapWork(objects_reaped, uint32_t(bytes_reaped), objects_pinned);
425 #endif
426 gc->policy.signal(GCPolicyManager::END_ReapZCT);
429 void ZCT::PopFastSegment()
431 GCAssert(!slowState);
432 GCAssert(blocktop-1 > blocktable); // Can't pop the first segment
433 blocktop--;
434 FreeBlock(*blocktop);
435 *blocktop = NULL;
436 RCObject** block = blocktop[-1];
437 bottom = block;
438 top = block + CAPACITY(RCObject**);
439 limit = top;
442 void ZCT::SetupPinningMemory()
444 GCAssert(pinList == NULL);
445 GCAssert(pinLast == NULL);
446 pinTop = NULL;
447 pinLimit = NULL;
448 pinIndex = 0;
451 bool ZCT::GrowPinningMemory()
453 GCAssert(pinTop == pinLimit);
454 GCAssert(pinIndex % CAPACITY(RCObject*) == 0);
456 RCObject** block = PleaseAllocBlock();
457 if (block == NULL)
458 return false;
459 // Use the first element of the block as a 'next' pointer, we don't
460 // want to use an auxiliary dynamic data structure that might fail
461 // here.
462 if (pinLast == NULL)
463 pinList = block;
464 else
465 pinLast[0] = (RCObject*)block;
466 pinLast = block;
467 block[0] = NULL;
468 pinTop = block + 1;
469 pinIndex++;
470 pinLimit = block + CAPACITY(RCObject*);
471 return true;
474 // Transfer blocks from pinList into the ZCT, replacing the ZCT blocks.
476 void ZCT::UsePinningMemory()
478 // ZCT must be empty when we do this
479 GCAssert(!slowState);
480 GCAssert(top == bottom);
481 GCAssert(topIndex == 0);
483 if (pinTop != NULL) {
484 // Nuke the ZCT contents (there should only be one block in it)
485 ClearBlockTable();
486 GCAssert(blocktop == blocktable);
487 GCAssert(*blocktop == NULL);
489 // Copy block pointers into the ZCT (typically very few)
490 while (pinList != NULL) {
491 RCObject** block = pinList;
492 pinList = (RCObject**)block[0];
493 block[0] = NULL;
494 *blocktop++ = block;
497 pinLast = NULL;
499 bottom = blocktop[-1];
500 top = pinTop;
501 limit = pinLimit;
502 topIndex = pinIndex;
506 void ZCT::ClearPinningMemory()
508 while (pinList != NULL)
510 RCObject** block = pinList;
511 pinList = (RCObject**)block[0];
512 FreeBlock(block);
514 pinLast = NULL;
517 REALLY_INLINE void ZCT::PinObject(RCObject* obj)
519 if (pinTop == pinLimit) {
520 if (!GrowPinningMemory()) {
521 obj->ClearZCTFlag();
522 return;
525 *pinTop++ = obj;
526 obj->setZCTIndexAndUnpin(pinIndex++);
529 REALLY_INLINE void ZCT::ReapObject(RCObject* obj)
531 obj->ClearZCTFlag();
532 #ifdef _DEBUG
533 if (gc->validateDefRef)
534 DefRefValidate(obj);
535 #endif
536 // Invoke prereap on all callbacks.
537 // FIXME: This is fairly wasteful and it would be good to be rid of it.
538 for ( GCCallback *cb = gc->m_callbacks; cb ; cb = cb->nextCB )
539 cb->prereap(obj);
541 GCAssert(*(intptr_t*)obj != 0); // That's the vtable normally
542 GCAssert(gc->IsFinalized(obj));
543 ((GCFinalizedObject*)obj)->~GCFinalizedObject();
544 gc->FreeNotNull(obj);
546 GCAssert(gc->weakRefs.get(obj) == NULL);
549 #ifdef _DEBUG
550 // FIXME: document the purpose & mechanisms of DefRef validation
552 /*static*/
553 void ZCT::DoSetupDefRefValidation(void* stackPointer, void* arg)
555 ZCT* zct = (ZCT*)arg;
556 GC* gc = zct->gc;
557 char* stackBase = (char*)gc->GetStackTop();
558 gc->Trace(stackPointer, uint32_t(stackBase - (char*)stackPointer));
561 void ZCT::FinishDefRefValidation()
563 gc->Sweep();
566 void ZCT::DefRefValidate(RCObject* obj)
568 if(!gc->GetMark(obj))
569 return;
570 #ifdef MMGC_RC_HISTORY
571 obj->DumpHistory();
572 #endif
573 GCAssertMsg(false, "Zero count object reachable, ref counts not correct!");
575 #endif // _DEBUG
577 /*static*/
578 void ZCT::DoPinProgramStack(void* stackPointer, void* arg)
580 ZCT* zct = (ZCT*)arg;
581 GC* gc = zct->gc;
582 char* stackBase = (char*)gc->GetStackTop();
583 zct->PinStackObjects(stackPointer, stackBase - (char*)stackPointer);
586 void ZCT::PinRootSegments()
588 GC::RCRootSegment* segment = gc->rcRootSegments;
589 while(segment)
591 PinStackObjects(segment->mem, segment->size);
592 segment = segment->next;
596 void ZCT::PinStackObjects(const void *start, size_t len)
598 RCObject **p = (RCObject**)start;
599 RCObject **end = p + len/sizeof(RCObject*);
601 const void *_memStart = (const void*)gc->memStart;
602 const void *_memEnd = (const void*)gc->memEnd;
604 while(p < end) {
605 const void *val = GC::Pointer(*p++);
607 if(val < _memStart || val >= _memEnd)
608 continue;
610 // Any pointer into the object pins the object.
612 switch (gc->GetPageMapValue((uintptr_t)val)) {
613 case GC::kGCAllocPage:
614 val = GCAlloc::IsRCObject(val) ? GetUserPointer(GCAlloc::FindBeginning(val)) : NULL;
615 break;
616 case GC::kGCLargeAllocPageRest:
617 do {
618 val = (const void*) ((uintptr_t)val - GCHeap::kBlockSize);
619 } while (gc->GetPageMapValue((uintptr_t)val) == GC::kGCLargeAllocPageRest);
620 /*FALLTHROUGH*/
621 case GC::kGCLargeAllocPageFirst:
622 val = GCLargeAlloc::IsRCObject(val) ? GetUserPointer(GCLargeAlloc::FindBeginning(val)) : NULL;
623 break;
624 default:
625 val = NULL;
626 break;
629 if(val) {
630 // We must pin all objects that are reachable from the stack whether they're in
631 // the ZCT or not, because destroying an object not in the ZCT may push additional
632 // references onto the ZCT, and if those are reachable from the stack they must
633 // be pinned. (Ergo adding objects during reaping must not clear the ZCT flag.)
635 RCObject *obj = (RCObject*)val;
636 obj->Pin();
641 bool ZCT::Grow()
643 GCAssert(CanGrow());
644 GCAssert(*blocktop == NULL);
646 // Allocate one more block
647 *blocktop = PleaseAllocBlock();
648 if (*blocktop == NULL)
649 return false;
650 blocktop++;
652 return true;
655 void ZCT::Prune()
657 ClearFreeList();
660 void ZCT::ClearBlockTable()
662 while (blocktop > blocktable) {
663 blocktop--;
664 FreeBlock(*blocktop);
665 *blocktop = NULL;
669 void ZCT::ClearFreeList()
671 while (freeList != NULL) {
672 void* item = (void*)freeList;
673 freeList = (void**)*freeList;
674 GCHeap::GetGCHeap()->FreeNoOOM(item);
678 RCObject** ZCT::PleaseAllocBlock()
680 #ifdef ZCT_TESTING
681 if (zct_allowance == 0)
682 return false;
683 #endif
684 RCObject** block = NULL;
685 if (freeList != NULL) {
686 block = (RCObject**)freeList;
687 freeList = (void**)*freeList;
689 else
690 block = (RCObject**)GCHeap::GetGCHeap()->AllocNoOOM(1, GCHeap::flags_Alloc|GCHeap::kCanFail);
691 #ifdef ZCT_TESTING
692 if (block != NULL)
693 --zct_allowance;
694 #endif
695 return block;
698 void ZCT::FreeBlock(RCObject** block)
700 #ifdef ZCT_TESTING
701 zct_allowance++;
702 #endif
703 *(void**)block = (void*)freeList;
704 freeList = (void**)block;