blob: f60ac0d3efc9363a6ecbbe1911d41a05b33fd6bc [file] [log] [blame]
Ben Murdochb8e0da22011-05-16 14:20:40 +01001// Copyright 2011 the V8 project authors. All rights reserved.
Steve Blocka7e24c12009-10-30 11:49:00 +00002// 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
Ben Murdoch257744e2011-11-30 15:57:28 +000031#include "allocation.h"
32
Steve Blocka7e24c12009-10-30 11:49:00 +000033namespace v8 {
34namespace internal {
35
36
37// Zone scopes are in one of two modes. Either they delete the zone
38// on exit or they do not.
39enum ZoneScopeMode {
40 DELETE_ON_EXIT,
41 DONT_DELETE_ON_EXIT
42};
43
Steve Block44f0eee2011-05-26 01:26:41 +010044class Segment;
Steve Blocka7e24c12009-10-30 11:49:00 +000045
46// The Zone supports very fast allocation of small chunks of
47// memory. The chunks cannot be deallocated individually, but instead
48// the Zone supports deallocating all chunks in one fast
49// operation. The Zone is used to hold temporary data structures like
50// the abstract syntax tree, which is deallocated after compilation.
51
52// Note: There is no need to initialize the Zone; the first time an
53// allocation is attempted, a segment of memory will be requested
54// through a call to malloc().
55
56// Note: The implementation is inherently not thread safe. Do not use
57// from multi-threaded code.
58
59class Zone {
60 public:
61 // Allocate 'size' bytes of memory in the Zone; expands the Zone by
62 // allocating new segments of memory on demand using malloc().
Steve Block44f0eee2011-05-26 01:26:41 +010063 inline void* New(int size);
Steve Blocka7e24c12009-10-30 11:49:00 +000064
65 template <typename T>
Steve Block44f0eee2011-05-26 01:26:41 +010066 inline T* NewArray(int length);
Steve Blocka7e24c12009-10-30 11:49:00 +000067
Ben Murdoch69a99ed2011-11-30 16:03:39 +000068 // Deletes all objects and free all memory allocated in the Zone. Keeps one
69 // small (size <= kMaximumKeptSegmentSize) segment around if it finds one.
Steve Block44f0eee2011-05-26 01:26:41 +010070 void DeleteAll();
Steve Blocka7e24c12009-10-30 11:49:00 +000071
Ben Murdoch69a99ed2011-11-30 16:03:39 +000072 // Deletes the last small segment kept around by DeleteAll().
73 void DeleteKeptSegment();
74
Steve Blocka7e24c12009-10-30 11:49:00 +000075 // Returns true if more memory has been allocated in zones than
76 // the limit allows.
Steve Block44f0eee2011-05-26 01:26:41 +010077 inline bool excess_allocation();
Steve Blocka7e24c12009-10-30 11:49:00 +000078
Steve Block44f0eee2011-05-26 01:26:41 +010079 inline void adjust_segment_bytes_allocated(int delta);
Steve Blocka7e24c12009-10-30 11:49:00 +000080
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000081 inline Isolate* isolate() { return isolate_; }
82
Ben Murdochb8e0da22011-05-16 14:20:40 +010083 static unsigned allocation_size_;
84
Steve Blocka7e24c12009-10-30 11:49:00 +000085 private:
Steve Block44f0eee2011-05-26 01:26:41 +010086 friend class Isolate;
87 friend class ZoneScope;
Steve Blocka7e24c12009-10-30 11:49:00 +000088
89 // All pointers returned from New() have this alignment.
90 static const int kAlignment = kPointerSize;
91
92 // Never allocate segments smaller than this size in bytes.
93 static const int kMinimumSegmentSize = 8 * KB;
94
95 // Never allocate segments larger than this size in bytes.
96 static const int kMaximumSegmentSize = 1 * MB;
97
98 // Never keep segments larger than this size in bytes around.
99 static const int kMaximumKeptSegmentSize = 64 * KB;
100
101 // Report zone excess when allocation exceeds this limit.
Steve Block44f0eee2011-05-26 01:26:41 +0100102 int zone_excess_limit_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000103
104 // The number of bytes allocated in segments. Note that this number
105 // includes memory allocated from the OS but not yet allocated from
106 // the zone.
Steve Block44f0eee2011-05-26 01:26:41 +0100107 int segment_bytes_allocated_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000108
Steve Block44f0eee2011-05-26 01:26:41 +0100109 // Each isolate gets its own zone.
110 Zone();
Steve Blocka7e24c12009-10-30 11:49:00 +0000111
112 // Expand the Zone to hold at least 'size' more bytes and allocate
113 // the bytes. Returns the address of the newly allocated chunk of
114 // memory in the Zone. Should only be called if there isn't enough
115 // room in the Zone already.
Steve Block44f0eee2011-05-26 01:26:41 +0100116 Address NewExpand(int size);
Steve Blocka7e24c12009-10-30 11:49:00 +0000117
Steve Block44f0eee2011-05-26 01:26:41 +0100118 // Creates a new segment, sets it size, and pushes it to the front
119 // of the segment chain. Returns the new segment.
120 Segment* NewSegment(int size);
121
122 // Deletes the given segment. Does not touch the segment chain.
123 void DeleteSegment(Segment* segment, int size);
Steve Blocka7e24c12009-10-30 11:49:00 +0000124
125 // The free region in the current (front) segment is represented as
126 // the half-open interval [position, limit). The 'position' variable
127 // is guaranteed to be aligned as dictated by kAlignment.
Steve Block44f0eee2011-05-26 01:26:41 +0100128 Address position_;
129 Address limit_;
130
131 int scope_nesting_;
132
133 Segment* segment_head_;
134 Isolate* isolate_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000135};
136
137
138// ZoneObject is an abstraction that helps define classes of objects
139// allocated in the Zone. Use it as a base class; see ast.h.
140class ZoneObject {
141 public:
142 // Allocate a new ZoneObject of 'size' bytes in the Zone.
Ben Murdoch257744e2011-11-30 15:57:28 +0000143 INLINE(void* operator new(size_t size));
144 INLINE(void* operator new(size_t size, Zone* zone));
Steve Blocka7e24c12009-10-30 11:49:00 +0000145
146 // Ideally, the delete operator should be private instead of
147 // public, but unfortunately the compiler sometimes synthesizes
148 // (unused) destructors for classes derived from ZoneObject, which
149 // require the operator to be visible. MSVC requires the delete
150 // operator to be public.
151
152 // ZoneObjects should never be deleted individually; use
153 // Zone::DeleteAll() to delete all zone objects in one go.
154 void operator delete(void*, size_t) { UNREACHABLE(); }
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000155 void operator delete(void* pointer, Zone* zone) { UNREACHABLE(); }
Steve Blocka7e24c12009-10-30 11:49:00 +0000156};
157
158
159class AssertNoZoneAllocation {
160 public:
Steve Block44f0eee2011-05-26 01:26:41 +0100161 inline AssertNoZoneAllocation();
162 inline ~AssertNoZoneAllocation();
Steve Blocka7e24c12009-10-30 11:49:00 +0000163 private:
164 bool prev_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000165};
166
167
168// The ZoneListAllocationPolicy is used to specialize the GenericList
169// implementation to allocate ZoneLists and their elements in the
170// Zone.
171class ZoneListAllocationPolicy {
172 public:
173 // Allocate 'size' bytes of memory in the zone.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000174 static void* New(int size);
Steve Blocka7e24c12009-10-30 11:49:00 +0000175
176 // De-allocation attempts are silently ignored.
177 static void Delete(void* p) { }
178};
179
180
181// ZoneLists are growable lists with constant-time access to the
182// elements. The list itself and all its elements are allocated in the
183// Zone. ZoneLists cannot be deleted individually; you can delete all
184// objects in the Zone by calling Zone::DeleteAll().
185template<typename T>
186class ZoneList: public List<T, ZoneListAllocationPolicy> {
187 public:
Ben Murdoch257744e2011-11-30 15:57:28 +0000188 INLINE(void* operator new(size_t size));
189 INLINE(void* operator new(size_t size, Zone* zone));
190
Steve Blocka7e24c12009-10-30 11:49:00 +0000191 // Construct a new ZoneList with the given capacity; the length is
192 // always zero. The capacity must be non-negative.
193 explicit ZoneList(int capacity)
194 : List<T, ZoneListAllocationPolicy>(capacity) { }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100195
196 // Construct a new ZoneList by copying the elements of the given ZoneList.
197 explicit ZoneList(const ZoneList<T>& other)
198 : List<T, ZoneListAllocationPolicy>(other.length()) {
199 AddAll(other);
200 }
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000201
202 void operator delete(void* pointer) { UNREACHABLE(); }
203 void operator delete(void* pointer, Zone* zone) { UNREACHABLE(); }
Steve Blocka7e24c12009-10-30 11:49:00 +0000204};
205
206
207// ZoneScopes keep track of the current parsing and compilation
208// nesting and cleans up generated ASTs in the Zone when exiting the
209// outer-most scope.
210class ZoneScope BASE_EMBEDDED {
211 public:
Ben Murdoch257744e2011-11-30 15:57:28 +0000212 INLINE(ZoneScope(Isolate* isolate, ZoneScopeMode mode));
Steve Blocka7e24c12009-10-30 11:49:00 +0000213
Steve Block44f0eee2011-05-26 01:26:41 +0100214 virtual ~ZoneScope();
Steve Blocka7e24c12009-10-30 11:49:00 +0000215
Steve Block44f0eee2011-05-26 01:26:41 +0100216 inline bool ShouldDeleteOnExit();
Steve Blocka7e24c12009-10-30 11:49:00 +0000217
218 // For ZoneScopes that do not delete on exit by default, call this
219 // method to request deletion on exit.
220 void DeleteOnExit() {
221 mode_ = DELETE_ON_EXIT;
222 }
223
Steve Block44f0eee2011-05-26 01:26:41 +0100224 inline static int nesting();
Steve Blocka7e24c12009-10-30 11:49:00 +0000225
226 private:
Steve Block44f0eee2011-05-26 01:26:41 +0100227 Isolate* isolate_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000228 ZoneScopeMode mode_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000229};
230
231
232// A zone splay tree. The config type parameter encapsulates the
Steve Block6ded16b2010-05-10 14:33:55 +0100233// different configurations of a concrete splay tree (see splay-tree.h).
234// The tree itself and all its elements are allocated in the Zone.
Steve Blocka7e24c12009-10-30 11:49:00 +0000235template <typename Config>
Steve Block6ded16b2010-05-10 14:33:55 +0100236class ZoneSplayTree: public SplayTree<Config, ZoneListAllocationPolicy> {
Steve Blocka7e24c12009-10-30 11:49:00 +0000237 public:
Steve Block6ded16b2010-05-10 14:33:55 +0100238 ZoneSplayTree()
239 : SplayTree<Config, ZoneListAllocationPolicy>() {}
240 ~ZoneSplayTree();
Steve Blocka7e24c12009-10-30 11:49:00 +0000241};
242
243
244} } // namespace v8::internal
245
246#endif // V8_ZONE_H_