blob: a5e437f7fa4e5e89a9aeb5c20d3a649abdb3bb10 [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
68 // Delete all objects and free all memory allocated in the Zone.
Steve Block44f0eee2011-05-26 01:26:41 +010069 void DeleteAll();
Steve Blocka7e24c12009-10-30 11:49:00 +000070
71 // Returns true if more memory has been allocated in zones than
72 // the limit allows.
Steve Block44f0eee2011-05-26 01:26:41 +010073 inline bool excess_allocation();
Steve Blocka7e24c12009-10-30 11:49:00 +000074
Steve Block44f0eee2011-05-26 01:26:41 +010075 inline void adjust_segment_bytes_allocated(int delta);
Steve Blocka7e24c12009-10-30 11:49:00 +000076
Ben Murdochb8e0da22011-05-16 14:20:40 +010077 static unsigned allocation_size_;
78
Steve Blocka7e24c12009-10-30 11:49:00 +000079 private:
Steve Block44f0eee2011-05-26 01:26:41 +010080 friend class Isolate;
81 friend class ZoneScope;
Steve Blocka7e24c12009-10-30 11:49:00 +000082
83 // All pointers returned from New() have this alignment.
84 static const int kAlignment = kPointerSize;
85
86 // Never allocate segments smaller than this size in bytes.
87 static const int kMinimumSegmentSize = 8 * KB;
88
89 // Never allocate segments larger than this size in bytes.
90 static const int kMaximumSegmentSize = 1 * MB;
91
92 // Never keep segments larger than this size in bytes around.
93 static const int kMaximumKeptSegmentSize = 64 * KB;
94
95 // Report zone excess when allocation exceeds this limit.
Steve Block44f0eee2011-05-26 01:26:41 +010096 int zone_excess_limit_;
Steve Blocka7e24c12009-10-30 11:49:00 +000097
98 // The number of bytes allocated in segments. Note that this number
99 // includes memory allocated from the OS but not yet allocated from
100 // the zone.
Steve Block44f0eee2011-05-26 01:26:41 +0100101 int segment_bytes_allocated_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000102
Steve Block44f0eee2011-05-26 01:26:41 +0100103 // Each isolate gets its own zone.
104 Zone();
Steve Blocka7e24c12009-10-30 11:49:00 +0000105
106 // Expand the Zone to hold at least 'size' more bytes and allocate
107 // the bytes. Returns the address of the newly allocated chunk of
108 // memory in the Zone. Should only be called if there isn't enough
109 // room in the Zone already.
Steve Block44f0eee2011-05-26 01:26:41 +0100110 Address NewExpand(int size);
Steve Blocka7e24c12009-10-30 11:49:00 +0000111
Steve Block44f0eee2011-05-26 01:26:41 +0100112 // Creates a new segment, sets it size, and pushes it to the front
113 // of the segment chain. Returns the new segment.
114 Segment* NewSegment(int size);
115
116 // Deletes the given segment. Does not touch the segment chain.
117 void DeleteSegment(Segment* segment, int size);
Steve Blocka7e24c12009-10-30 11:49:00 +0000118
119 // The free region in the current (front) segment is represented as
120 // the half-open interval [position, limit). The 'position' variable
121 // is guaranteed to be aligned as dictated by kAlignment.
Steve Block44f0eee2011-05-26 01:26:41 +0100122 Address position_;
123 Address limit_;
124
125 int scope_nesting_;
126
127 Segment* segment_head_;
128 Isolate* isolate_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000129};
130
131
132// ZoneObject is an abstraction that helps define classes of objects
133// allocated in the Zone. Use it as a base class; see ast.h.
134class ZoneObject {
135 public:
136 // Allocate a new ZoneObject of 'size' bytes in the Zone.
Ben Murdoch257744e2011-11-30 15:57:28 +0000137 INLINE(void* operator new(size_t size));
138 INLINE(void* operator new(size_t size, Zone* zone));
Steve Blocka7e24c12009-10-30 11:49:00 +0000139
140 // Ideally, the delete operator should be private instead of
141 // public, but unfortunately the compiler sometimes synthesizes
142 // (unused) destructors for classes derived from ZoneObject, which
143 // require the operator to be visible. MSVC requires the delete
144 // operator to be public.
145
146 // ZoneObjects should never be deleted individually; use
147 // Zone::DeleteAll() to delete all zone objects in one go.
148 void operator delete(void*, size_t) { UNREACHABLE(); }
149};
150
151
152class AssertNoZoneAllocation {
153 public:
Steve Block44f0eee2011-05-26 01:26:41 +0100154 inline AssertNoZoneAllocation();
155 inline ~AssertNoZoneAllocation();
Steve Blocka7e24c12009-10-30 11:49:00 +0000156 private:
157 bool prev_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000158};
159
160
161// The ZoneListAllocationPolicy is used to specialize the GenericList
162// implementation to allocate ZoneLists and their elements in the
163// Zone.
164class ZoneListAllocationPolicy {
165 public:
166 // Allocate 'size' bytes of memory in the zone.
Ben Murdoch257744e2011-11-30 15:57:28 +0000167 INLINE(static void* New(int size));
Steve Blocka7e24c12009-10-30 11:49:00 +0000168
169 // De-allocation attempts are silently ignored.
170 static void Delete(void* p) { }
171};
172
173
174// ZoneLists are growable lists with constant-time access to the
175// elements. The list itself and all its elements are allocated in the
176// Zone. ZoneLists cannot be deleted individually; you can delete all
177// objects in the Zone by calling Zone::DeleteAll().
178template<typename T>
179class ZoneList: public List<T, ZoneListAllocationPolicy> {
180 public:
Ben Murdoch257744e2011-11-30 15:57:28 +0000181 INLINE(void* operator new(size_t size));
182 INLINE(void* operator new(size_t size, Zone* zone));
183
Steve Blocka7e24c12009-10-30 11:49:00 +0000184 // Construct a new ZoneList with the given capacity; the length is
185 // always zero. The capacity must be non-negative.
186 explicit ZoneList(int capacity)
187 : List<T, ZoneListAllocationPolicy>(capacity) { }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100188
189 // Construct a new ZoneList by copying the elements of the given ZoneList.
190 explicit ZoneList(const ZoneList<T>& other)
191 : List<T, ZoneListAllocationPolicy>(other.length()) {
192 AddAll(other);
193 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000194};
195
196
Ben Murdochb0fe1622011-05-05 13:52:32 +0100197// Introduce a convenience type for zone lists of map handles.
198typedef ZoneList<Handle<Map> > ZoneMapList;
199
200
Steve Blocka7e24c12009-10-30 11:49:00 +0000201// ZoneScopes keep track of the current parsing and compilation
202// nesting and cleans up generated ASTs in the Zone when exiting the
203// outer-most scope.
204class ZoneScope BASE_EMBEDDED {
205 public:
Ben Murdoch257744e2011-11-30 15:57:28 +0000206 INLINE(ZoneScope(Isolate* isolate, ZoneScopeMode mode));
Steve Blocka7e24c12009-10-30 11:49:00 +0000207
Steve Block44f0eee2011-05-26 01:26:41 +0100208 virtual ~ZoneScope();
Steve Blocka7e24c12009-10-30 11:49:00 +0000209
Steve Block44f0eee2011-05-26 01:26:41 +0100210 inline bool ShouldDeleteOnExit();
Steve Blocka7e24c12009-10-30 11:49:00 +0000211
212 // For ZoneScopes that do not delete on exit by default, call this
213 // method to request deletion on exit.
214 void DeleteOnExit() {
215 mode_ = DELETE_ON_EXIT;
216 }
217
Steve Block44f0eee2011-05-26 01:26:41 +0100218 inline static int nesting();
Steve Blocka7e24c12009-10-30 11:49:00 +0000219
220 private:
Steve Block44f0eee2011-05-26 01:26:41 +0100221 Isolate* isolate_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000222 ZoneScopeMode mode_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000223};
224
225
226// A zone splay tree. The config type parameter encapsulates the
Steve Block6ded16b2010-05-10 14:33:55 +0100227// different configurations of a concrete splay tree (see splay-tree.h).
228// The tree itself and all its elements are allocated in the Zone.
Steve Blocka7e24c12009-10-30 11:49:00 +0000229template <typename Config>
Steve Block6ded16b2010-05-10 14:33:55 +0100230class ZoneSplayTree: public SplayTree<Config, ZoneListAllocationPolicy> {
Steve Blocka7e24c12009-10-30 11:49:00 +0000231 public:
Steve Block6ded16b2010-05-10 14:33:55 +0100232 ZoneSplayTree()
233 : SplayTree<Config, ZoneListAllocationPolicy>() {}
234 ~ZoneSplayTree();
Steve Blocka7e24c12009-10-30 11:49:00 +0000235};
236
237
238} } // namespace v8::internal
239
240#endif // V8_ZONE_H_