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
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.
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 ***** */
41 #include "StaticAssert.h"
43 #ifdef AVMPLUS_SAMPLER
47 #define SAMPLE_FRAME(_x, _s)
48 #define SAMPLE_CHECK()
51 //#define ZCT_TESTING // Test the handling of a failure to extend the ZCT
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
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
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.)
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;
133 void ZCT::SetGC(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;
159 bottom
= blocktable
[0];
161 limit
= blocktable
[0] + CAPACITY(RCObject
*);
169 GCHeap::GetGCHeap()->Free(blocktable
);
172 void ZCT::StartCollecting()
174 GCAssert(!slowState
);
176 // Transfer state to slow-path variables
181 slowTopIndex
= topIndex
;
183 // Create a state that triggers the slow path
187 void ZCT::EndCollecting()
191 // Transfer the state from the slow-path variables
195 topIndex
= slowTopIndex
;
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
214 ClearPinningMemory();
221 void ZCT::AddSlow(RCObject
*obj
)
223 GCAssert(top
== limit
);
224 GCAssert(gc
->collecting
+ reaping
< 2);
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
)
233 // Unmarked objects are gonna get swept anyways.
234 if(!GC::GetMark(obj
))
238 if (slowState
&& slowTop
< slowLimit
) {
240 obj
->setZCTIndexAndMaybeUnpin(slowTopIndex
++, uint32_t(reaping
));
245 // Expand or reap? Sometimes we must grow even if the budget has been exhausted.
247 bool shouldGrow
= false;
250 else if (budget
> 0 && CanGrow())
253 // 'obj' will not be reaped as it's on the stack; we'll add it to the ZCT below.
255 uint32_t avail
= AvailableInCurrentSegment();
256 budget
= gc
->policy
.queryZCTBudget(uint32_t(blocktop
- blocktable
));
262 GCAssert(AvailableInCurrentSegment() == 0);
263 if (!CanGrow() || !Grow())
264 return; // c'est la vie
267 // Grow() does not set up the state for Add(), so do that.
269 slowBottom
= blocktop
[-1];
270 slowTop
= slowBottom
;
271 slowLimit
= slowBottom
+ CAPACITY(RCObject
*);
272 GCAssert(slowTopIndex
% CAPACITY(RCObject
*) == 0);
275 bottom
= blocktop
[-1];
276 limit
= bottom
+ CAPACITY(RCObject
*);
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
);
294 return (slowState
? slowTopIndex
: topIndex
) + CAPACITY(RCObject
*) <= RCObject::ZCT_CAPACITY
;
297 void ZCT::Reap(bool scanStack
)
302 GCAssert(!slowState
);
304 // Do not reap if already reaping or if the ZCT is empty (waste of time).
305 if (reaping
|| topIndex
== 0)
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;
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.
332 VMPI_callWithRegistersSaved(ZCT::DoPinProgramStack
, this);
335 // Invoke prereap on all callbacks
336 for ( GCCallback
*cb
= gc
->m_callbacks
; cb
; cb
= cb
->nextCB
)
340 if (gc
->validateDefRef
)
341 VMPI_callWithRegistersSaved(ZCT::DoSetupDefRefValidation
, this);
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();
364 // Pop an element off the ZCT
365 GCAssert(bottom
<= top
);
366 GCAssert(top
<= limit
);
373 RCObject
*rcobj
= *--top
;
376 // Process the element
379 else if (rcobj
->IsPinned()) {
380 #ifdef MMGC_POLICY_PROFILING
387 bytes_reaped
+= GC::Size(rcobj
);
393 // Invoke postreap on all callbacks
394 for ( GCCallback
*cb
= gc
->m_callbacks
; cb
; cb
= cb
->nextCB
)
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",
401 unsigned(bytes_reaped
/1024),
402 unsigned(blocks_before
- blocks_after
),
403 unsigned(blocks_after
* GCHeap::kBlockSize
/ 1024),
405 GC::duration(gc
->t0
)/1000);
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();
423 #ifdef MMGC_POLICY_PROFILING
424 gc
->policy
.signalReapWork(objects_reaped
, uint32_t(bytes_reaped
), objects_pinned
);
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
434 FreeBlock(*blocktop
);
436 RCObject
** block
= blocktop
[-1];
438 top
= block
+ CAPACITY(RCObject
**);
442 void ZCT::SetupPinningMemory()
444 GCAssert(pinList
== NULL
);
445 GCAssert(pinLast
== NULL
);
451 bool ZCT::GrowPinningMemory()
453 GCAssert(pinTop
== pinLimit
);
454 GCAssert(pinIndex
% CAPACITY(RCObject
*) == 0);
456 RCObject
** block
= PleaseAllocBlock();
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
465 pinLast
[0] = (RCObject
*)block
;
470 pinLimit
= block
+ CAPACITY(RCObject
*);
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)
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];
499 bottom
= blocktop
[-1];
506 void ZCT::ClearPinningMemory()
508 while (pinList
!= NULL
)
510 RCObject
** block
= pinList
;
511 pinList
= (RCObject
**)block
[0];
517 REALLY_INLINE
void ZCT::PinObject(RCObject
* obj
)
519 if (pinTop
== pinLimit
) {
520 if (!GrowPinningMemory()) {
526 obj
->setZCTIndexAndUnpin(pinIndex
++);
529 REALLY_INLINE
void ZCT::ReapObject(RCObject
* obj
)
533 if (gc
->validateDefRef
)
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
)
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
);
550 // FIXME: document the purpose & mechanisms of DefRef validation
553 void ZCT::DoSetupDefRefValidation(void* stackPointer
, void* arg
)
555 ZCT
* zct
= (ZCT
*)arg
;
557 char* stackBase
= (char*)gc
->GetStackTop();
558 gc
->Trace(stackPointer
, uint32_t(stackBase
- (char*)stackPointer
));
561 void ZCT::FinishDefRefValidation()
566 void ZCT::DefRefValidate(RCObject
* obj
)
568 if(!gc
->GetMark(obj
))
570 #ifdef MMGC_RC_HISTORY
573 GCAssertMsg(false, "Zero count object reachable, ref counts not correct!");
578 void ZCT::DoPinProgramStack(void* stackPointer
, void* arg
)
580 ZCT
* zct
= (ZCT
*)arg
;
582 char* stackBase
= (char*)gc
->GetStackTop();
583 zct
->PinStackObjects(stackPointer
, stackBase
- (char*)stackPointer
);
586 void ZCT::PinRootSegments()
588 GC::RCRootSegment
* segment
= gc
->rcRootSegments
;
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
;
605 const void *val
= GC::Pointer(*p
++);
607 if(val
< _memStart
|| val
>= _memEnd
)
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
;
616 case GC::kGCLargeAllocPageRest
:
618 val
= (const void*) ((uintptr_t)val
- GCHeap::kBlockSize
);
619 } while (gc
->GetPageMapValue((uintptr_t)val
) == GC::kGCLargeAllocPageRest
);
621 case GC::kGCLargeAllocPageFirst
:
622 val
= GCLargeAlloc::IsRCObject(val
) ? GetUserPointer(GCLargeAlloc::FindBeginning(val
)) : NULL
;
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
;
644 GCAssert(*blocktop
== NULL
);
646 // Allocate one more block
647 *blocktop
= PleaseAllocBlock();
648 if (*blocktop
== NULL
)
660 void ZCT::ClearBlockTable()
662 while (blocktop
> blocktable
) {
664 FreeBlock(*blocktop
);
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()
681 if (zct_allowance
== 0)
684 RCObject
** block
= NULL
;
685 if (freeList
!= NULL
) {
686 block
= (RCObject
**)freeList
;
687 freeList
= (void**)*freeList
;
690 block
= (RCObject
**)GCHeap::GetGCHeap()->AllocNoOOM(1, GCHeap::flags_Alloc
|GCHeap::kCanFail
);
698 void ZCT::FreeBlock(RCObject
** block
)
703 *(void**)block
= (void*)freeList
;
704 freeList
= (void**)block
;