• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 //     * Redistributions of source code must retain the above copyright
7 //       notice, this list of conditions and the following disclaimer.
8 //     * Redistributions in binary form must reproduce the above
9 //       copyright notice, this list of conditions and the following
10 //       disclaimer in the documentation and/or other materials provided
11 //       with the distribution.
12 //     * Neither the name of Google Inc. nor the names of its
13 //       contributors may be used to endorse or promote products derived
14 //       from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28 #ifndef V8_ZONE_H_
29 #define V8_ZONE_H_
30 
31 namespace v8 {
32 namespace internal {
33 
34 
35 // Zone scopes are in one of two modes.  Either they delete the zone
36 // on exit or they do not.
37 enum ZoneScopeMode {
38   DELETE_ON_EXIT,
39   DONT_DELETE_ON_EXIT
40 };
41 
42 class Segment;
43 
44 // The Zone supports very fast allocation of small chunks of
45 // memory. The chunks cannot be deallocated individually, but instead
46 // the Zone supports deallocating all chunks in one fast
47 // operation. The Zone is used to hold temporary data structures like
48 // the abstract syntax tree, which is deallocated after compilation.
49 
50 // Note: There is no need to initialize the Zone; the first time an
51 // allocation is attempted, a segment of memory will be requested
52 // through a call to malloc().
53 
54 // Note: The implementation is inherently not thread safe. Do not use
55 // from multi-threaded code.
56 
57 class Zone {
58  public:
59   // Allocate 'size' bytes of memory in the Zone; expands the Zone by
60   // allocating new segments of memory on demand using malloc().
61   inline void* New(int size);
62 
63   template <typename T>
64   inline T* NewArray(int length);
65 
66   // Delete all objects and free all memory allocated in the Zone.
67   void DeleteAll();
68 
69   // Returns true if more memory has been allocated in zones than
70   // the limit allows.
71   inline bool excess_allocation();
72 
73   inline void adjust_segment_bytes_allocated(int delta);
74 
75   static unsigned allocation_size_;
76 
77  private:
78   friend class Isolate;
79   friend class ZoneScope;
80 
81   // All pointers returned from New() have this alignment.
82   static const int kAlignment = kPointerSize;
83 
84   // Never allocate segments smaller than this size in bytes.
85   static const int kMinimumSegmentSize = 8 * KB;
86 
87   // Never allocate segments larger than this size in bytes.
88   static const int kMaximumSegmentSize = 1 * MB;
89 
90   // Never keep segments larger than this size in bytes around.
91   static const int kMaximumKeptSegmentSize = 64 * KB;
92 
93   // Report zone excess when allocation exceeds this limit.
94   int zone_excess_limit_;
95 
96   // The number of bytes allocated in segments.  Note that this number
97   // includes memory allocated from the OS but not yet allocated from
98   // the zone.
99   int segment_bytes_allocated_;
100 
101   // Each isolate gets its own zone.
102   Zone();
103 
104   // Expand the Zone to hold at least 'size' more bytes and allocate
105   // the bytes. Returns the address of the newly allocated chunk of
106   // memory in the Zone. Should only be called if there isn't enough
107   // room in the Zone already.
108   Address NewExpand(int size);
109 
110   // Creates a new segment, sets it size, and pushes it to the front
111   // of the segment chain. Returns the new segment.
112   Segment* NewSegment(int size);
113 
114   // Deletes the given segment. Does not touch the segment chain.
115   void DeleteSegment(Segment* segment, int size);
116 
117   // The free region in the current (front) segment is represented as
118   // the half-open interval [position, limit). The 'position' variable
119   // is guaranteed to be aligned as dictated by kAlignment.
120   Address position_;
121   Address limit_;
122 
123   int scope_nesting_;
124 
125   Segment* segment_head_;
126   Isolate* isolate_;
127 };
128 
129 
130 // ZoneObject is an abstraction that helps define classes of objects
131 // allocated in the Zone. Use it as a base class; see ast.h.
132 class ZoneObject {
133  public:
134   // Allocate a new ZoneObject of 'size' bytes in the Zone.
135   inline void* operator new(size_t size);
136   inline void* operator new(size_t size, Zone* zone);
137 
138   // Ideally, the delete operator should be private instead of
139   // public, but unfortunately the compiler sometimes synthesizes
140   // (unused) destructors for classes derived from ZoneObject, which
141   // require the operator to be visible. MSVC requires the delete
142   // operator to be public.
143 
144   // ZoneObjects should never be deleted individually; use
145   // Zone::DeleteAll() to delete all zone objects in one go.
delete(void *,size_t)146   void operator delete(void*, size_t) { UNREACHABLE(); }
147 };
148 
149 
150 class AssertNoZoneAllocation {
151  public:
152   inline AssertNoZoneAllocation();
153   inline ~AssertNoZoneAllocation();
154  private:
155   bool prev_;
156 };
157 
158 
159 // The ZoneListAllocationPolicy is used to specialize the GenericList
160 // implementation to allocate ZoneLists and their elements in the
161 // Zone.
162 class ZoneListAllocationPolicy {
163  public:
164   // Allocate 'size' bytes of memory in the zone.
165   static inline void* New(int size);
166 
167   // De-allocation attempts are silently ignored.
Delete(void * p)168   static void Delete(void* p) { }
169 };
170 
171 
172 // ZoneLists are growable lists with constant-time access to the
173 // elements. The list itself and all its elements are allocated in the
174 // Zone. ZoneLists cannot be deleted individually; you can delete all
175 // objects in the Zone by calling Zone::DeleteAll().
176 template<typename T>
177 class ZoneList: public List<T, ZoneListAllocationPolicy> {
178  public:
179   // Construct a new ZoneList with the given capacity; the length is
180   // always zero. The capacity must be non-negative.
ZoneList(int capacity)181   explicit ZoneList(int capacity)
182       : List<T, ZoneListAllocationPolicy>(capacity) { }
183 
184   // Construct a new ZoneList by copying the elements of the given ZoneList.
ZoneList(const ZoneList<T> & other)185   explicit ZoneList(const ZoneList<T>& other)
186       : List<T, ZoneListAllocationPolicy>(other.length()) {
187     AddAll(other);
188   }
189 };
190 
191 
192 // Introduce a convenience type for zone lists of map handles.
193 typedef ZoneList<Handle<Map> > ZoneMapList;
194 
195 
196 // ZoneScopes keep track of the current parsing and compilation
197 // nesting and cleans up generated ASTs in the Zone when exiting the
198 // outer-most scope.
199 class ZoneScope BASE_EMBEDDED {
200  public:
201   // TODO(isolates): pass isolate pointer here.
202   inline explicit ZoneScope(ZoneScopeMode mode);
203 
204   virtual ~ZoneScope();
205 
206   inline bool ShouldDeleteOnExit();
207 
208   // For ZoneScopes that do not delete on exit by default, call this
209   // method to request deletion on exit.
DeleteOnExit()210   void DeleteOnExit() {
211     mode_ = DELETE_ON_EXIT;
212   }
213 
214   inline static int nesting();
215 
216  private:
217   Isolate* isolate_;
218   ZoneScopeMode mode_;
219 };
220 
221 
222 // A zone splay tree.  The config type parameter encapsulates the
223 // different configurations of a concrete splay tree (see splay-tree.h).
224 // The tree itself and all its elements are allocated in the Zone.
225 template <typename Config>
226 class ZoneSplayTree: public SplayTree<Config, ZoneListAllocationPolicy> {
227  public:
ZoneSplayTree()228   ZoneSplayTree()
229       : SplayTree<Config, ZoneListAllocationPolicy>() {}
230   ~ZoneSplayTree();
231 };
232 
233 
234 } }  // namespace v8::internal
235 
236 #endif  // V8_ZONE_H_
237