17242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci// Copyright 2014 The Chromium Authors. All rights reserved.
27242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci// Use of this source code is governed by a BSD-style license that can be
37242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci// found in the LICENSE file.
47242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
57242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#ifndef CallbackStack_h
67242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#define CallbackStack_h
77242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
87242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "platform/heap/ThreadState.h"
97242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
107242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccinamespace blink {
117242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
127242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci// The CallbackStack contains all the visitor callbacks used to trace and mark
137242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci// objects. A specific CallbackStack instance contains at most bufferSize elements.
147242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci// If more space is needed a new CallbackStack instance is created and chained
157242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci// together with the former instance. I.e. a logical CallbackStack can be made of
167242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci// multiple chained CallbackStack object instances.
177242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucciclass CallbackStack {
187242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccipublic:
197242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    class Item {
207242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    public:
217242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        Item() { }
227242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        Item(void* object, VisitorCallback callback)
237242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            : m_object(object)
247242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            , m_callback(callback)
257242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        {
267242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        }
277242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        void* object() { return m_object; }
287242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        VisitorCallback callback() { return m_callback; }
297242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        void call(Visitor* visitor) { m_callback(visitor, m_object); }
307242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
317242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    private:
327242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        void* m_object;
337242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        VisitorCallback m_callback;
347242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    };
357242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
367242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    CallbackStack();
377242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ~CallbackStack();
387242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
397242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    void clear();
407242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
417242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    Item* allocateEntry();
427242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    Item* pop();
437242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
447242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    bool isEmpty() const;
457242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    bool sizeExceeds(size_t) const;
467242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
477242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    void append(CallbackStack*);
487242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    void takeBlockFrom(CallbackStack*);
497242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
507242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    void invokeEphemeronCallbacks(Visitor*);
517242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
527242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#if ENABLE(ASSERT)
537242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    bool hasCallbackForObject(const void*);
547242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#endif
557242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
567242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    static const size_t blockSize = 200;
577242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
587242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucciprivate:
597242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    class Block;
607242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
617242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    void invokeOldestCallbacks(Block*, Block*, Visitor*);
627242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    bool hasJustOneBlock() const;
637242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    void swap(CallbackStack* other);
647242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
657242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    Block* m_first;
667242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    Block* m_last;
677242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci};
687242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
697242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci}
707242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
717242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#endif // CallbackStack_h
72