blob: 864846553a234d82cfd88c3e527f1f5c7416e654 [file] [log] [blame]
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001// Copyright 2012 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"
Ben Murdoch3ef787d2012-04-12 10:51:47 +010032#include "checks.h"
33#include "hashmap.h"
34#include "globals.h"
35#include "list.h"
36#include "splay-tree.h"
Ben Murdoch257744e2011-11-30 15:57:28 +000037
Steve Blocka7e24c12009-10-30 11:49:00 +000038namespace v8 {
39namespace internal {
40
41
42// Zone scopes are in one of two modes. Either they delete the zone
43// on exit or they do not.
44enum ZoneScopeMode {
45 DELETE_ON_EXIT,
46 DONT_DELETE_ON_EXIT
47};
48
Steve Block44f0eee2011-05-26 01:26:41 +010049class Segment;
Ben Murdoch3ef787d2012-04-12 10:51:47 +010050class Isolate;
Steve Blocka7e24c12009-10-30 11:49:00 +000051
52// The Zone supports very fast allocation of small chunks of
53// memory. The chunks cannot be deallocated individually, but instead
54// the Zone supports deallocating all chunks in one fast
55// operation. The Zone is used to hold temporary data structures like
56// the abstract syntax tree, which is deallocated after compilation.
57
58// Note: There is no need to initialize the Zone; the first time an
59// allocation is attempted, a segment of memory will be requested
60// through a call to malloc().
61
62// Note: The implementation is inherently not thread safe. Do not use
63// from multi-threaded code.
64
65class Zone {
66 public:
67 // Allocate 'size' bytes of memory in the Zone; expands the Zone by
68 // allocating new segments of memory on demand using malloc().
Steve Block44f0eee2011-05-26 01:26:41 +010069 inline void* New(int size);
Steve Blocka7e24c12009-10-30 11:49:00 +000070
71 template <typename T>
Steve Block44f0eee2011-05-26 01:26:41 +010072 inline T* NewArray(int length);
Steve Blocka7e24c12009-10-30 11:49:00 +000073
Ben Murdoch69a99ed2011-11-30 16:03:39 +000074 // Deletes all objects and free all memory allocated in the Zone. Keeps one
75 // small (size <= kMaximumKeptSegmentSize) segment around if it finds one.
Steve Block44f0eee2011-05-26 01:26:41 +010076 void DeleteAll();
Steve Blocka7e24c12009-10-30 11:49:00 +000077
Ben Murdoch69a99ed2011-11-30 16:03:39 +000078 // Deletes the last small segment kept around by DeleteAll().
79 void DeleteKeptSegment();
80
Steve Blocka7e24c12009-10-30 11:49:00 +000081 // Returns true if more memory has been allocated in zones than
82 // the limit allows.
Steve Block44f0eee2011-05-26 01:26:41 +010083 inline bool excess_allocation();
Steve Blocka7e24c12009-10-30 11:49:00 +000084
Steve Block44f0eee2011-05-26 01:26:41 +010085 inline void adjust_segment_bytes_allocated(int delta);
Steve Blocka7e24c12009-10-30 11:49:00 +000086
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000087 inline Isolate* isolate() { return isolate_; }
88
Ben Murdochb8e0da22011-05-16 14:20:40 +010089 static unsigned allocation_size_;
90
Steve Blocka7e24c12009-10-30 11:49:00 +000091 private:
Steve Block44f0eee2011-05-26 01:26:41 +010092 friend class Isolate;
93 friend class ZoneScope;
Steve Blocka7e24c12009-10-30 11:49:00 +000094
Ben Murdoch3ef787d2012-04-12 10:51:47 +010095 // All pointers returned from New() have this alignment. In addition, if the
96 // object being allocated has a size that is divisible by 8 then its alignment
97 // will be 8.
Steve Blocka7e24c12009-10-30 11:49:00 +000098 static const int kAlignment = kPointerSize;
99
100 // Never allocate segments smaller than this size in bytes.
101 static const int kMinimumSegmentSize = 8 * KB;
102
103 // Never allocate segments larger than this size in bytes.
104 static const int kMaximumSegmentSize = 1 * MB;
105
106 // Never keep segments larger than this size in bytes around.
107 static const int kMaximumKeptSegmentSize = 64 * KB;
108
109 // Report zone excess when allocation exceeds this limit.
Steve Block44f0eee2011-05-26 01:26:41 +0100110 int zone_excess_limit_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000111
112 // The number of bytes allocated in segments. Note that this number
113 // includes memory allocated from the OS but not yet allocated from
114 // the zone.
Steve Block44f0eee2011-05-26 01:26:41 +0100115 int segment_bytes_allocated_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000116
Steve Block44f0eee2011-05-26 01:26:41 +0100117 // Each isolate gets its own zone.
118 Zone();
Steve Blocka7e24c12009-10-30 11:49:00 +0000119
120 // Expand the Zone to hold at least 'size' more bytes and allocate
121 // the bytes. Returns the address of the newly allocated chunk of
122 // memory in the Zone. Should only be called if there isn't enough
123 // room in the Zone already.
Steve Block44f0eee2011-05-26 01:26:41 +0100124 Address NewExpand(int size);
Steve Blocka7e24c12009-10-30 11:49:00 +0000125
Steve Block44f0eee2011-05-26 01:26:41 +0100126 // Creates a new segment, sets it size, and pushes it to the front
127 // of the segment chain. Returns the new segment.
128 Segment* NewSegment(int size);
129
130 // Deletes the given segment. Does not touch the segment chain.
131 void DeleteSegment(Segment* segment, int size);
Steve Blocka7e24c12009-10-30 11:49:00 +0000132
133 // The free region in the current (front) segment is represented as
134 // the half-open interval [position, limit). The 'position' variable
135 // is guaranteed to be aligned as dictated by kAlignment.
Steve Block44f0eee2011-05-26 01:26:41 +0100136 Address position_;
137 Address limit_;
138
139 int scope_nesting_;
140
141 Segment* segment_head_;
142 Isolate* isolate_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000143};
144
145
146// ZoneObject is an abstraction that helps define classes of objects
147// allocated in the Zone. Use it as a base class; see ast.h.
148class ZoneObject {
149 public:
150 // Allocate a new ZoneObject of 'size' bytes in the Zone.
Ben Murdoch257744e2011-11-30 15:57:28 +0000151 INLINE(void* operator new(size_t size));
152 INLINE(void* operator new(size_t size, Zone* zone));
Steve Blocka7e24c12009-10-30 11:49:00 +0000153
154 // Ideally, the delete operator should be private instead of
155 // public, but unfortunately the compiler sometimes synthesizes
156 // (unused) destructors for classes derived from ZoneObject, which
157 // require the operator to be visible. MSVC requires the delete
158 // operator to be public.
159
160 // ZoneObjects should never be deleted individually; use
161 // Zone::DeleteAll() to delete all zone objects in one go.
162 void operator delete(void*, size_t) { UNREACHABLE(); }
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000163 void operator delete(void* pointer, Zone* zone) { UNREACHABLE(); }
Steve Blocka7e24c12009-10-30 11:49:00 +0000164};
165
166
Steve Blocka7e24c12009-10-30 11:49:00 +0000167// The ZoneListAllocationPolicy is used to specialize the GenericList
168// implementation to allocate ZoneLists and their elements in the
169// Zone.
170class ZoneListAllocationPolicy {
171 public:
172 // Allocate 'size' bytes of memory in the zone.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000173 static void* New(int size);
Steve Blocka7e24c12009-10-30 11:49:00 +0000174
175 // De-allocation attempts are silently ignored.
176 static void Delete(void* p) { }
177};
178
179
180// ZoneLists are growable lists with constant-time access to the
181// elements. The list itself and all its elements are allocated in the
182// Zone. ZoneLists cannot be deleted individually; you can delete all
183// objects in the Zone by calling Zone::DeleteAll().
184template<typename T>
185class ZoneList: public List<T, ZoneListAllocationPolicy> {
186 public:
Ben Murdoch257744e2011-11-30 15:57:28 +0000187 INLINE(void* operator new(size_t size));
188 INLINE(void* operator new(size_t size, Zone* zone));
189
Steve Blocka7e24c12009-10-30 11:49:00 +0000190 // Construct a new ZoneList with the given capacity; the length is
191 // always zero. The capacity must be non-negative.
192 explicit ZoneList(int capacity)
193 : List<T, ZoneListAllocationPolicy>(capacity) { }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100194
195 // Construct a new ZoneList by copying the elements of the given ZoneList.
196 explicit ZoneList(const ZoneList<T>& other)
197 : List<T, ZoneListAllocationPolicy>(other.length()) {
198 AddAll(other);
199 }
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000200
201 void operator delete(void* pointer) { UNREACHABLE(); }
202 void operator delete(void* pointer, Zone* zone) { UNREACHABLE(); }
Steve Blocka7e24c12009-10-30 11:49:00 +0000203};
204
205
206// ZoneScopes keep track of the current parsing and compilation
207// nesting and cleans up generated ASTs in the Zone when exiting the
208// outer-most scope.
209class ZoneScope BASE_EMBEDDED {
210 public:
Ben Murdoch257744e2011-11-30 15:57:28 +0000211 INLINE(ZoneScope(Isolate* isolate, ZoneScopeMode mode));
Steve Blocka7e24c12009-10-30 11:49:00 +0000212
Steve Block44f0eee2011-05-26 01:26:41 +0100213 virtual ~ZoneScope();
Steve Blocka7e24c12009-10-30 11:49:00 +0000214
Steve Block44f0eee2011-05-26 01:26:41 +0100215 inline bool ShouldDeleteOnExit();
Steve Blocka7e24c12009-10-30 11:49:00 +0000216
217 // For ZoneScopes that do not delete on exit by default, call this
218 // method to request deletion on exit.
219 void DeleteOnExit() {
220 mode_ = DELETE_ON_EXIT;
221 }
222
Steve Block44f0eee2011-05-26 01:26:41 +0100223 inline static int nesting();
Steve Blocka7e24c12009-10-30 11:49:00 +0000224
225 private:
Steve Block44f0eee2011-05-26 01:26:41 +0100226 Isolate* isolate_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000227 ZoneScopeMode mode_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000228};
229
230
231// A zone splay tree. The config type parameter encapsulates the
Steve Block6ded16b2010-05-10 14:33:55 +0100232// different configurations of a concrete splay tree (see splay-tree.h).
233// The tree itself and all its elements are allocated in the Zone.
Steve Blocka7e24c12009-10-30 11:49:00 +0000234template <typename Config>
Steve Block6ded16b2010-05-10 14:33:55 +0100235class ZoneSplayTree: public SplayTree<Config, ZoneListAllocationPolicy> {
Steve Blocka7e24c12009-10-30 11:49:00 +0000236 public:
Steve Block6ded16b2010-05-10 14:33:55 +0100237 ZoneSplayTree()
238 : SplayTree<Config, ZoneListAllocationPolicy>() {}
239 ~ZoneSplayTree();
Steve Blocka7e24c12009-10-30 11:49:00 +0000240};
241
242
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100243typedef TemplateHashMapImpl<ZoneListAllocationPolicy> ZoneHashMap;
244
Steve Blocka7e24c12009-10-30 11:49:00 +0000245} } // namespace v8::internal
246
247#endif // V8_ZONE_H_