root/MMgc/GCLargeAlloc.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is [Open Source Virtual Machine.].
 *
 * The Initial Developer of the Original Code is
 * Adobe System Incorporated.
 * Portions created by the Initial Developer are Copyright (C) 2004-2006
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *   Adobe AS3 Team
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

#ifndef __GCLargeAlloc__
#define __GCLargeAlloc__

namespace MMgc
{
        /**
         * This is a garbage collecting allocator for large memory blocks.
         */
        class GCLargeAlloc
        {
                friend class GC;
                friend class GCLargeAllocIterator;
        private:
                enum {
                        kMarkFlag         = 0x1,
                        kQueuedFlag       = 0x2,
                        kFinalizeFlag     = 0x4,
                        kHasWeakRef       = 0x8,
                        kContainsPointers = 0x10,
                        kRCObject         = 0x20
                };

        public:
                GCLargeAlloc(GC* gc);
                ~GCLargeAlloc();

#if defined DEBUG || defined MMGC_MEMORY_PROFILER
                void* Alloc(size_t originalSize, size_t requestSize, int flags);
#else
                void* Alloc(size_t requestSize, int flags);
#endif
                void Free(const void *ptr);

                void Finalize();
                void ClearMarks();

                // not a hot method
                static void SetHasWeakRef(const void *item, bool to);

                // not a hot method
                static bool HasWeakRef(const void *item);

                static bool IsLargeBlock(const void *item);

                static bool SetMark(const void *item);

                // Not a hot method but always inlining probably shrinks the code
                static void SetFinalize(const void *item);
                
                static bool GetMark(const void *item);

#ifdef _DEBUG
                static bool IsWhite(const void *item);
#endif
        
                static bool IsMarkedThenMakeQueued(const void *item);

                static bool IsQueued(const void *item);

                static void* FindBeginning(const void *item);

                // not a hot method
                static void ClearFinalized(const void *item);

                // Not hot, because GC::MarkItem open-codes it
                static bool ContainsPointers(const void *item);
                
                // not a hot method
                static bool IsFinalized(const void *item);

                // Can be hot - used by PinStackObjects
                static bool IsRCObject(const void *item);

                //This method returns the number bytes allocated by FixedMalloc
                size_t GetBytesInUse();
                
                //This method is for more fine grained allocation details
                //It reports the total number of bytes requested (i.e. ask size) and
                //the number of bytes actually allocated.  The latter is the same
                //number as reported by GetBytesInUse()
                void GetUsageInfo(size_t& totalAskSize, size_t& totalAllocated);

        private:
                struct LargeBlock : GCBlockHeader
                {
                        uint32_t flags;

                        int GetNumBlocks() const;
                };

                static LargeBlock* GetLargeBlock(const void *addr);
                
                // not a hot method
                static bool NeedsFinalize(LargeBlock *block);
                
                // not a hot method
                static void ClearQueued(const void *item);
                
                // The list of chunk blocks
                LargeBlock* m_blocks;
#ifdef MMGC_MEMORY_PROFILER
                size_t m_totalAskSize;
#endif

                bool m_startedFinalize;
                
#ifdef _DEBUG
                static bool ConservativeGetMark(const void *item, bool bogusPointerReturnValue);
#endif

        protected:
                GC *m_gc;

        public:
                static LargeBlock* Next(LargeBlock* b);
        };

        /**
         * A utility class used by the marker to handle mark stack overflow: it abstracts
         * iterating across marked, non-free objects in one allocator instance.
         *
         * No blocks must be added or removed during the iteration.  If an object's
         * bits are changed, those changes will visible to the iterator if the object has
         * not yet been reached by the iteration. 
         */
        class GCLargeAllocIterator
        {
        public:
                GCLargeAllocIterator(MMgc::GCLargeAlloc* alloc);
                
                bool GetNextMarkedObject(void*& out_ptr, uint32_t& out_size);
                
        private:
                GCLargeAlloc* const alloc;
                GCLargeAlloc::LargeBlock* block;
        };
}

#endif /* __GCLargeAlloc__ */

/* [<][>][^][v][top][bottom][index][help] */