Page Speed Optimization Libraries  1.13.35.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
arena.h
Go to the documentation of this file.
1 /*
2  * Copyright 2011 Google Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http:///www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
18 
19 #ifndef PAGESPEED_KERNEL_BASE_ARENA_H_
20 #define PAGESPEED_KERNEL_BASE_ARENA_H_
21 
22 #include <vector>
23 #include <cstddef>
24 
25 #include "base/logging.h"
27 
28 namespace net_instaweb {
29 
33 template<typename T>
34 class Arena {
35  public:
38  static const size_t kAlign = 8;
39 
40  Arena() {
41  InitEmpty();
42  }
43 
44  ~Arena() {
45  CHECK(chunks_.empty());
46  }
47 
48  void* Allocate(size_t size) {
49  size += kAlign;
50  size = ExpandToAlign(size);
51 
52  DCHECK(sizeof(void*) <= kAlign);
53  DCHECK(size < Chunk::kSize);
54 
55  if (next_alloc_ + size > chunk_end_) {
56  AddChunk();
57  }
58 
59  char* base = next_alloc_;
60 
64  char** our_last_link_field = reinterpret_cast<char**>(base);
65  *last_link_ = base;
66  *our_last_link_field = NULL;
67  last_link_ = our_last_link_field;
68 
69  next_alloc_ += size;
70 
71  char* out = base + kAlign;
74  DCHECK((reinterpret_cast<uintptr_t>(out) & (kAlign - 1)) == 0);
75  return out;
76  }
77 
79  void DestroyObjects();
80 
82  static size_t ExpandToAlign(size_t in) {
83  return (in + kAlign - 1) & ~(kAlign - 1);
84  }
85 
86  private:
87  struct Chunk {
105  static const size_t kSize = 8192;
106  char buf[kSize];
107  };
108 
110  void AddChunk();
111 
113  void InitEmpty();
114 
116  char* next_alloc_;
117 
121  char** last_link_;
122 
124  char* chunk_end_;
125 
128  char* scratch_;
129 
130  std::vector<Chunk*> chunks_;
131 };
132 
133 template<typename T>
134 void Arena<T>::AddChunk() {
135  Chunk* chunk = new Chunk();
136  chunks_.push_back(chunk);
137  next_alloc_ = chunk->buf;
138  chunk_end_ = next_alloc_ + Chunk::kSize;
139  last_link_ = &scratch_;
140 }
141 
142 template<typename T>
144  for (int i = 0; i < static_cast<int>(chunks_.size()); ++i) {
146  char* base = chunks_[i]->buf;
147  while (base != NULL) {
148  reinterpret_cast<T*>(base + kAlign)->~T();
149  base = *reinterpret_cast<char**>(base);
150  }
151  delete chunks_[i];
152  }
153  chunks_.clear();
154  InitEmpty();
155 }
156 
157 template<typename T>
158 void Arena<T>::InitEmpty() {
163  next_alloc_ = NULL;
164  last_link_ = NULL;
165  chunk_end_ = NULL;
166 }
167 
168 }
169 
170 #endif
static size_t ExpandToAlign(size_t in)
Rounds block size up to 8; we always align to it, even on 32-bit.
Definition: arena.h:82
void * Allocate(size_t size)
Definition: arena.h:48
Definition: arena.h:34
void DestroyObjects()
Cleans up all the objects in the arena. You must call this explicitly.
Definition: arena.h:143
static const size_t kAlign
Definition: arena.h:38