Setup a experiment to enable background tracing.
[chromium-blink-merge.git] / cc / base / sidecar_list_container.h
blob52deaf4b0a47f11b3eeabaa780bb1ee2bcded359
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef CC_BASE_SIDECAR_LIST_CONTAINER_H_
6 #define CC_BASE_SIDECAR_LIST_CONTAINER_H_
8 #include "base/logging.h"
9 #include "cc/base/list_container.h"
11 namespace cc {
13 // This is a container, based on ListContainer, which allocates space in a
14 // contiguous block for objects subclassing BaseElementType, as well as an
15 // additional "sidecar" of opaque type.
17 // It takes a pointer to a function for tearing down sidecar objects, which must
18 // free any resources held by it as its memory will be deallocated by the
19 // container afterwards. When an element is constructed, callers are expected to
20 // immediately construct the sidecar as well (such that the sidecar destroyer
21 // will run safely and successfully).
23 // TODO(jbroman): It would be nice to be clear about the memory alignment
24 // constraints here, but that probably requires closer inspection of
25 // ListContainer first.
26 template <class BaseElementType>
27 class SidecarListContainer {
28 public:
29 using SidecarDestroyer = void (*)(void* sidecar);
30 using Iterator = typename ListContainer<BaseElementType>::Iterator;
31 using ConstIterator = typename ListContainer<BaseElementType>::ConstIterator;
33 explicit SidecarListContainer(size_t max_size_for_derived_class,
34 size_t max_size_for_sidecar,
35 size_t num_of_elements_to_reserve_for,
36 SidecarDestroyer destroyer)
37 : list_(max_size_for_derived_class + max_size_for_sidecar,
38 num_of_elements_to_reserve_for),
39 destroyer_(destroyer),
40 sidecar_offset_(max_size_for_derived_class) {}
41 ~SidecarListContainer() { DestroyAllSidecars(); }
43 // Forward most of the reading logic to ListContainer.
44 bool empty() const { return list_.empty(); }
45 size_t size() const { return list_.size(); }
46 ConstIterator begin() const { return list_.begin(); }
47 ConstIterator end() const { return list_.end(); }
49 template <typename DerivedElementType>
50 DerivedElementType* AllocateAndConstruct() {
51 return list_.template AllocateAndConstruct<DerivedElementType>();
53 template <typename DerivedElementType>
54 DerivedElementType* AllocateAndCopyFrom(const DerivedElementType* source) {
55 return list_.template AllocateAndCopyFrom<DerivedElementType>(source);
58 void clear() {
59 DestroyAllSidecars();
60 list_.clear();
63 // This permits a client to exchange a pointer to an element to a pointer to
64 // its corresponding sidecar.
65 void* GetSidecar(BaseElementType* element) {
66 DCHECK_GT(sidecar_offset_, 0u);
67 return reinterpret_cast<char*>(element) + sidecar_offset_;
69 const void* GetSidecar(const BaseElementType* element) {
70 DCHECK_GT(sidecar_offset_, 0u);
71 return reinterpret_cast<const char*>(element) + sidecar_offset_;
74 private:
75 void DestroyAllSidecars() {
76 for (auto* element : list_)
77 destroyer_(GetSidecar(element));
80 ListContainer<BaseElementType> list_;
81 SidecarDestroyer destroyer_;
82 size_t sidecar_offset_;
85 } // namespace cc
87 #endif // CC_BASE_SIDECAR_LIST_CONTAINER_H_