~alinuxninja/nginx-edge/trunk

« back to all changes in this revision

Viewing changes to debian/modules/ngx_pagespeed/psol/include/third_party/re2/src/util/arena.h

  • Committer: Vivian
  • Date: 2015-12-04 18:20:11 UTC
  • Revision ID: git-v1:a36f2bc32e884f7473b3a47040e5411306144d7d
* Do not extract psol.tar.gz

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// Copyright 2000 The RE2 Authors.  All Rights Reserved.
2
 
// Use of this source code is governed by a BSD-style
3
 
// license that can be found in the LICENSE file.
4
 
 
5
 
// Sometimes it is necessary to allocate a large number of small
6
 
// objects.  Doing this the usual way (malloc, new) is slow,
7
 
// especially for multithreaded programs.  An UnsafeArena provides a
8
 
// mark/release method of memory management: it asks for a large chunk
9
 
// from the operating system and doles it out bit by bit as required.
10
 
// Then you free all the memory at once by calling UnsafeArena::Reset().
11
 
// The "Unsafe" refers to the fact that UnsafeArena is not safe to
12
 
// call from multiple threads.
13
 
//
14
 
// The global operator new that can be used as follows:
15
 
//
16
 
//   #include "lib/arena-inl.h"
17
 
//
18
 
//   UnsafeArena arena(1000);
19
 
//   Foo* foo = new (AllocateInArena, &arena) Foo;
20
 
//
21
 
 
22
 
#ifndef RE2_UTIL_ARENA_H_
23
 
#define RE2_UTIL_ARENA_H_
24
 
 
25
 
namespace re2 {
26
 
 
27
 
// This class is thread-compatible.
28
 
class UnsafeArena {
29
 
 public:
30
 
  UnsafeArena(const size_t block_size);
31
 
  virtual ~UnsafeArena();
32
 
 
33
 
  void Reset();
34
 
 
35
 
  // This should be the worst-case alignment for any type.  This is
36
 
  // good for IA-32, SPARC version 7 (the last one I know), and
37
 
  // supposedly Alpha.  i386 would be more time-efficient with a
38
 
  // default alignment of 8, but ::operator new() uses alignment of 4,
39
 
  // and an assertion will fail below after the call to MakeNewBlock()
40
 
  // if you try to use a larger alignment.
41
 
#ifdef __i386__
42
 
  static const int kDefaultAlignment = 4;
43
 
#else
44
 
  static const int kDefaultAlignment = 8;
45
 
#endif
46
 
 
47
 
 private:
48
 
  void* GetMemoryFallback(const size_t size, const int align);
49
 
 
50
 
 public:
51
 
  void* GetMemory(const size_t size, const int align) {
52
 
    if ( size > 0 && size < remaining_ && align == 1 ) {       // common case
53
 
      last_alloc_ = freestart_;
54
 
      freestart_ += size;
55
 
      remaining_ -= size;
56
 
      return reinterpret_cast<void*>(last_alloc_);
57
 
    }
58
 
    return GetMemoryFallback(size, align);
59
 
  }
60
 
 
61
 
 private:
62
 
  struct AllocatedBlock {
63
 
    char *mem;
64
 
    size_t size;
65
 
  };
66
 
 
67
 
  // The returned AllocatedBlock* is valid until the next call to AllocNewBlock
68
 
  // or Reset (i.e. anything that might affect overflow_blocks_).
69
 
  AllocatedBlock *AllocNewBlock(const size_t block_size);
70
 
 
71
 
  const AllocatedBlock *IndexToBlock(int index) const;
72
 
 
73
 
  const size_t block_size_;
74
 
  char* freestart_;         // beginning of the free space in most recent block
75
 
  char* freestart_when_empty_;  // beginning of the free space when we're empty
76
 
  char* last_alloc_;         // used to make sure ReturnBytes() is safe
77
 
  size_t remaining_;
78
 
  // STL vector isn't as efficient as it could be, so we use an array at first
79
 
  int blocks_alloced_;       // how many of the first_blocks_ have been alloced
80
 
  AllocatedBlock first_blocks_[16];   // the length of this array is arbitrary
81
 
  // if the first_blocks_ aren't enough, expand into overflow_blocks_.
82
 
  vector<AllocatedBlock>* overflow_blocks_;
83
 
 
84
 
  void FreeBlocks();         // Frees all except first block
85
 
 
86
 
  DISALLOW_EVIL_CONSTRUCTORS(UnsafeArena);
87
 
};
88
 
 
89
 
// Operators for allocation on the arena
90
 
// Syntax: new (AllocateInArena, arena) MyClass;
91
 
// STL containers, etc.
92
 
enum AllocateInArenaType { AllocateInArena };
93
 
 
94
 
}  // namespace re2
95
 
 
96
 
inline void* operator new(size_t size,
97
 
                          re2::AllocateInArenaType /* unused */,
98
 
                          re2::UnsafeArena *arena) {
99
 
  return reinterpret_cast<char*>(arena->GetMemory(size, 1));
100
 
}
101
 
 
102
 
#endif  // RE2_UTIL_ARENA_H_
103