Ticket #2142: dynamic-arena.patch

File dynamic-arena.patch, 3.8 KB (added by historic_bruno, 11 years ago)

WIP dynamic arena

  • source/lib/allocators/arena.h

     
    1 /* Copyright (c) 2010 Wildfire Games
     1/* Copyright (c) 2013 Wildfire Games
    22 *
    33 * Permission is hereby granted, free of charge, to any person obtaining
    44 * a copy of this software and associated documentation files (the
     
    8383
    8484LIB_API void TestArena();
    8585
     86
     87/**
     88 * allocator design parameters:
     89 * - grow dynamically with a fixed chunkSize
     90 * - for frequent allocations of size << chunkSize
     91 * - no reallocations, pointers remain valid
     92 **/
     93class DynamicArena
     94{
     95    class ArenaChunk
     96    {
     97        NONCOPYABLE(ArenaChunk);
     98    public:
     99        ArenaChunk(size_t size)
     100            : capacity(size), end(0), storage(malloc(size))
     101        {
     102        }
     103
     104        ~ArenaChunk()
     105        {
     106            free(storage);
     107        }
     108
     109        bool Available(size_t size)
     110        {
     111            return size <= (capacity - end);
     112        }
     113
     114        uintptr_t Allocate(size_t size)
     115        {
     116            if (!Available(size))
     117                return 0;
     118            uintptr_t ptr = uintptr_t(storage) + end;
     119            end += size;
     120            return ptr;
     121        }
     122
     123        void* storage;
     124        size_t end;
     125        const size_t capacity;
     126    };
     127
     128    NONCOPYABLE(DynamicArena);
     129public:
     130    DynamicArena(size_t chunkSize) : chunkSize(chunkSize)
     131    {
     132        chunkList.push_back(new ArenaChunk(chunkSize));
     133    }
     134
     135    ~DynamicArena()
     136    {
     137        std::list<ArenaChunk*>::iterator it;
     138        for (it = chunkList.begin(); it != chunkList.end(); ++it)
     139            delete *it;
     140    }
     141
     142    void* allocate(size_t size)
     143    {
     144        if (!chunkList.back()->Available(size))
     145        {
     146            if (size > chunkSize)
     147            {
     148                debug_warn(L"DynamicArena cannot allocate more than chunk size");
     149                throw std::bad_alloc();
     150            }
     151            chunkList.push_back(new ArenaChunk(chunkSize));
     152        }
     153
     154        return (void*)chunkList.back()->Allocate(size);
     155    }
     156
     157    void deallocate(void* UNUSED(p), size_t UNUSED(size))
     158    {
     159        // ignored
     160    }
     161
     162private:
     163
     164    const size_t chunkSize;
     165    std::list<ArenaChunk*> chunkList;
     166};
     167
     168
    86169}   // namespace Allocators
    87170
    88171#endif  // #ifndef INCLUDED_ALLOCATORS_ARENA
  • source/simulation2/serialization/BinarySerializer.cpp

     
    5757
    5858CBinarySerializerScriptImpl::CBinarySerializerScriptImpl(ScriptInterface& scriptInterface, ISerializer& serializer) :
    5959    m_ScriptInterface(scriptInterface), m_Serializer(serializer), m_Rooter(m_ScriptInterface),
    60     m_ScriptBackrefsArena(16*MiB), m_ScriptBackrefs(backrefs_t::key_compare(), ScriptBackrefsAlloc(m_ScriptBackrefsArena)), m_ScriptBackrefsNext(1)
     60    m_ScriptBackrefsArena(1 * MiB), m_ScriptBackrefs(backrefs_t::key_compare(), ScriptBackrefsAlloc(m_ScriptBackrefsArena)), m_ScriptBackrefsNext(1)
    6161{
    6262}
    6363
  • source/simulation2/serialization/BinarySerializer.h

     
    6565    ISerializer& m_Serializer;
    6666
    6767    // Pooling helps since we do a lot of short-lived allocations
    68     typedef ProxyAllocator<std::pair<JSObject* const, u32>, Allocators::Arena<> > ScriptBackrefsAlloc;
     68    typedef ProxyAllocator<std::pair<JSObject* const, u32>, Allocators::DynamicArena > ScriptBackrefsAlloc;
    6969    typedef std::map<JSObject*, u32, std::less<JSObject*>, ScriptBackrefsAlloc> backrefs_t;
    7070
    71     Allocators::Arena<> m_ScriptBackrefsArena;
     71    Allocators::DynamicArena m_ScriptBackrefsArena;
    7272    backrefs_t m_ScriptBackrefs;
    7373    u32 m_ScriptBackrefsNext;
    7474    u32 GetScriptBackrefTag(JSObject* obj);