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)
4 // ***** BEGIN LICENSE BLOCK *****
5 // Version: MPL 1.1/GPL 2.0/LGPL 2.1
7 // The contents of this file are subject to the Mozilla Public License Version
8 // 1.1 (the "License"); you may not use this file except in compliance with
9 // the License. You may obtain a copy of the License at
10 // http://www.mozilla.org/MPL/
12 // Software distributed under the License is distributed on an "AS IS" basis,
13 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 // for the specific language governing rights and limitations under the
17 // The Original Code is [Open Source Virtual Machine.].
19 // The Initial Developer of the Original Code is
20 // Adobe System Incorporated.
21 // Portions created by the Initial Developer are Copyright (C) 2004-2006
22 // the Initial Developer. All Rights Reserved.
27 // Alternatively, the contents of this file may be used under the terms of
28 // either the GNU General Public License Version 2 or later (the "GPL"), or
29 // the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30 // in which case the provisions of the GPL or the LGPL are applicable instead
31 // of those above. If you wish to allow use of your version of this file only
32 // under the terms of either the GPL or the LGPL, and not to allow others to
33 // use your version of this file under the terms of the MPL, indicate your
34 // decision by deleting the provisions above and replace them with the notice
35 // and other provisions required by the GPL or the LGPL. If you do not delete
36 // the provisions above, a recipient may use your version of this file under
37 // the terms of any one of the MPL, the GPL or the LGPL.
39 // ***** END LICENSE BLOCK ***** */
41 // Bugzilla 565631 - We occasionally interleave invoking finalizers
42 // and clearing mark bits in GCAlloc::Finalize; so a finalizer can
43 // observe a live object that does not have its mark bit set.
45 // This complicates things because we want to ensure that unmarked
46 // weakly-referenced objects are resurrected by the GC if the weak
47 // reference is dereferenced during presweep, but we do not want to
48 // schedule collection work (or set bits that are supposed to be
49 // unmarked) during finalization.
51 // (Long term we might want to get rid of the interleaving of
52 // finalization and mark-bit clearing. Short term, lets just
53 // try to detect this on our own.)
56 %%category bugzilla_575631
61 // Upon destruction, start reading weak refs of "friends" near and far
62 class Snoopy : public GCFinalizedObject
65 Snoopy(int key, GCWeakRef** refs, int len)
66 : key(key), friends(refs), len(len)
71 static int alive_count;
78 // To take D samples from an array of N elems, walk thru by floor(N/D)
79 // steps (but avoid the pathological case when the floor is zero).
80 int compute_stride(int numerator, int denominator)
82 int delta = numerator / denominator;
83 return (delta > 0) ? delta : 1;
87 // collecting twice is only "sure" way to gc in presence of incrementality
88 void collect2() { core->gc->Collect(); core->gc->Collect(); }
92 /*static*/ int Snoopy::alive_count = 0;
94 const int arr_len = 1000;
95 const int lookups_per_destruct = 10;
96 const int destructs = 10;
99 int delta = compute_stride(arr_len, lookups_per_destruct);
101 for ( int i = 1 ; i < arr_len ; i += delta ) {
102 int idx = (key + i) % len;
103 // printf("referencing ref[%d] from Snoopy(%d)\n", idx, key);
113 Snoopy* objs[arr_len];
114 GCWeakRef* refs[arr_len];
117 for (int i=0 ; i < arr_len; ++i ) {
118 objs[i] = new (gc) Snoopy(i, refs, arr_len);
119 refs[i] = objs[i]->GetWeakRef();
124 int delta = compute_stride(arr_len, destructs);
126 for (int i=0; i < arr_len; i += delta) {
131 // not assert failing within get() is passing the test.
133 ; // (make my auto-indenter happy)
135 // cleanup code; letting ~Snoopy occur outside test extent is big no-no.
137 for (int i=0; i < arr_len; ++i ) {
138 if (! refs[i]->isNull())
142 // if something went wrong above and some Snoopy's are still alive,
143 // we'll get burned during their destructors. Make sure that
145 %%verify (Snoopy::alive_count == 0)