blob: 2ca3c4d369e3977be5ecbf002c9b528985636547 [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
Ben Murdoch592a9fc2012-03-05 11:04:45 +000089 // All pointers returned from New() have this alignment. In addition, if the
90 // object being allocated has a size that is divisible by 8 then its alignment
91 // will be 8.
Steve Blocka7e24c12009-10-30 11:49:00 +000092 static const int kAlignment = kPointerSize;
93
94 // Never allocate segments smaller than this size in bytes.
95 static const int kMinimumSegmentSize = 8 * KB;
96
97 // Never allocate segments larger than this size in bytes.
98 static const int kMaximumSegmentSize = 1 * MB;
99
100 // Never keep segments larger than this size in bytes around.
101 static const int kMaximumKeptSegmentSize = 64 * KB;
102
103 // Report zone excess when allocation exceeds this limit.
Steve Block44f0eee2011-05-26 01:26:41 +0100104 int zone_excess_limit_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000105
106 // The number of bytes allocated in segments. Note that this number
107 // includes memory allocated from the OS but not yet allocated from
108 // the zone.
Steve Block44f0eee2011-05-26 01:26:41 +0100109 int segment_bytes_allocated_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000110
Steve Block44f0eee2011-05-26 01:26:41 +0100111 // Each isolate gets its own zone.
112 Zone();
Steve Blocka7e24c12009-10-30 11:49:00 +0000113
114 // Expand the Zone to hold at least 'size' more bytes and allocate
115 // the bytes. Returns the address of the newly allocated chunk of
116 // memory in the Zone. Should only be called if there isn't enough
117 // room in the Zone already.
Steve Block44f0eee2011-05-26 01:26:41 +0100118 Address NewExpand(int size);
Steve Blocka7e24c12009-10-30 11:49:00 +0000119
Steve Block44f0eee2011-05-26 01:26:41 +0100120 // Creates a new segment, sets it size, and pushes it to the front
121 // of the segment chain. Returns the new segment.
122 Segment* NewSegment(int size);
123
124 // Deletes the given segment. Does not touch the segment chain.
125 void DeleteSegment(Segment* segment, int size);
Steve Blocka7e24c12009-10-30 11:49:00 +0000126
127 // The free region in the current (front) segment is represented as
128 // the half-open interval [position, limit). The 'position' variable
129 // is guaranteed to be aligned as dictated by kAlignment.
Steve Block44f0eee2011-05-26 01:26:41 +0100130 Address position_;
131 Address limit_;
132
133 int scope_nesting_;
134
135 Segment* segment_head_;
136 Isolate* isolate_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000137};
138
139
140// ZoneObject is an abstraction that helps define classes of objects
141// allocated in the Zone. Use it as a base class; see ast.h.
142class ZoneObject {
143 public:
144 // Allocate a new ZoneObject of 'size' bytes in the Zone.
Ben Murdoch257744e2011-11-30 15:57:28 +0000145 INLINE(void* operator new(size_t size));
146 INLINE(void* operator new(size_t size, Zone* zone));
Steve Blocka7e24c12009-10-30 11:49:00 +0000147
148 // Ideally, the delete operator should be private instead of
149 // public, but unfortunately the compiler sometimes synthesizes
150 // (unused) destructors for classes derived from ZoneObject, which
151 // require the operator to be visible. MSVC requires the delete
152 // operator to be public.
153
154 // ZoneObjects should never be deleted individually; use
155 // Zone::DeleteAll() to delete all zone objects in one go.
156 void operator delete(void*, size_t) { UNREACHABLE(); }
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000157 void operator delete(void* pointer, Zone* zone) { UNREACHABLE(); }
Steve Blocka7e24c12009-10-30 11:49:00 +0000158};
159
160
161class AssertNoZoneAllocation {
162 public:
Steve Block44f0eee2011-05-26 01:26:41 +0100163 inline AssertNoZoneAllocation();
164 inline ~AssertNoZoneAllocation();
Steve Blocka7e24c12009-10-30 11:49:00 +0000165 private:
166 bool prev_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000167};
168
169
170// The ZoneListAllocationPolicy is used to specialize the GenericList
171// implementation to allocate ZoneLists and their elements in the
172// Zone.
173class ZoneListAllocationPolicy {
174 public:
175 // Allocate 'size' bytes of memory in the zone.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000176 static void* New(int size);
Steve Blocka7e24c12009-10-30 11:49:00 +0000177
178 // De-allocation attempts are silently ignored.
179 static void Delete(void* p) { }
180};
181
182
183// ZoneLists are growable lists with constant-time access to the
184// elements. The list itself and all its elements are allocated in the
185// Zone. ZoneLists cannot be deleted individually; you can delete all
186// objects in the Zone by calling Zone::DeleteAll().
187template<typename T>
188class ZoneList: public List<T, ZoneListAllocationPolicy> {
189 public:
Ben Murdoch257744e2011-11-30 15:57:28 +0000190 INLINE(void* operator new(size_t size));
191 INLINE(void* operator new(size_t size, Zone* zone));
192
Steve Blocka7e24c12009-10-30 11:49:00 +0000193 // Construct a new ZoneList with the given capacity; the length is
194 // always zero. The capacity must be non-negative.
195 explicit ZoneList(int capacity)
196 : List<T, ZoneListAllocationPolicy>(capacity) { }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100197
198 // Construct a new ZoneList by copying the elements of the given ZoneList.
199 explicit ZoneList(const ZoneList<T>& other)
200 : List<T, ZoneListAllocationPolicy>(other.length()) {
201 AddAll(other);
202 }
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000203
204 void operator delete(void* pointer) { UNREACHABLE(); }
205 void operator delete(void* pointer, Zone* zone) { UNREACHABLE(); }
Steve Blocka7e24c12009-10-30 11:49:00 +0000206};
207
208
209// ZoneScopes keep track of the current parsing and compilation
210// nesting and cleans up generated ASTs in the Zone when exiting the
211// outer-most scope.
212class ZoneScope BASE_EMBEDDED {
213 public:
Ben Murdoch257744e2011-11-30 15:57:28 +0000214 INLINE(ZoneScope(Isolate* isolate, ZoneScopeMode mode));
Steve Blocka7e24c12009-10-30 11:49:00 +0000215
Steve Block44f0eee2011-05-26 01:26:41 +0100216 virtual ~ZoneScope();
Steve Blocka7e24c12009-10-30 11:49:00 +0000217
Steve Block44f0eee2011-05-26 01:26:41 +0100218 inline bool ShouldDeleteOnExit();
Steve Blocka7e24c12009-10-30 11:49:00 +0000219
220 // For ZoneScopes that do not delete on exit by default, call this
221 // method to request deletion on exit.
222 void DeleteOnExit() {
223 mode_ = DELETE_ON_EXIT;
224 }
225
Steve Block44f0eee2011-05-26 01:26:41 +0100226 inline static int nesting();
Steve Blocka7e24c12009-10-30 11:49:00 +0000227
228 private:
Steve Block44f0eee2011-05-26 01:26:41 +0100229 Isolate* isolate_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000230 ZoneScopeMode mode_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000231};
232
233
234// A zone splay tree. The config type parameter encapsulates the
Steve Block6ded16b2010-05-10 14:33:55 +0100235// different configurations of a concrete splay tree (see splay-tree.h).
236// The tree itself and all its elements are allocated in the Zone.
Steve Blocka7e24c12009-10-30 11:49:00 +0000237template <typename Config>
Steve Block6ded16b2010-05-10 14:33:55 +0100238class ZoneSplayTree: public SplayTree<Config, ZoneListAllocationPolicy> {
Steve Blocka7e24c12009-10-30 11:49:00 +0000239 public:
Steve Block6ded16b2010-05-10 14:33:55 +0100240 ZoneSplayTree()
241 : SplayTree<Config, ZoneListAllocationPolicy>() {}
242 ~ZoneSplayTree();
Steve Blocka7e24c12009-10-30 11:49:00 +0000243};
244
245
246} } // namespace v8::internal
247
248#endif // V8_ZONE_H_