blob: abb53ad46d3b236096b13155076d3b53894d1f31 [file] [log] [blame]
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001// Copyright 2011 the V8 project authors. All rights reserved.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +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
lrn@chromium.org1c092762011-05-09 09:42:16 +000031#include "allocation.h"
32
kasperl@chromium.org71affb52009-05-26 05:44:31 +000033namespace v8 {
34namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000035
36
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +000037// 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
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000044class Segment;
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +000045
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000046// 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().
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000063 inline void* New(int size);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000064
ager@chromium.org41826e72009-03-30 13:30:57 +000065 template <typename T>
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000066 inline T* NewArray(int length);
ager@chromium.org41826e72009-03-30 13:30:57 +000067
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000068 // Delete all objects and free all memory allocated in the Zone.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000069 void DeleteAll();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000070
ager@chromium.orga74f0da2008-12-03 16:05:52 +000071 // Returns true if more memory has been allocated in zones than
72 // the limit allows.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000073 inline bool excess_allocation();
ager@chromium.orga74f0da2008-12-03 16:05:52 +000074
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000075 inline void adjust_segment_bytes_allocated(int delta);
ager@chromium.orga74f0da2008-12-03 16:05:52 +000076
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +000077 inline Isolate* isolate() { return isolate_; }
78
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +000079 static unsigned allocation_size_;
80
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000081 private:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000082 friend class Isolate;
83 friend class ZoneScope;
ager@chromium.orga74f0da2008-12-03 16:05:52 +000084
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000085 // All pointers returned from New() have this alignment.
86 static const int kAlignment = kPointerSize;
87
88 // Never allocate segments smaller than this size in bytes.
89 static const int kMinimumSegmentSize = 8 * KB;
90
ager@chromium.org8bb60582008-12-11 12:02:20 +000091 // Never allocate segments larger than this size in bytes.
92 static const int kMaximumSegmentSize = 1 * MB;
93
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000094 // Never keep segments larger than this size in bytes around.
95 static const int kMaximumKeptSegmentSize = 64 * KB;
96
ager@chromium.orga74f0da2008-12-03 16:05:52 +000097 // Report zone excess when allocation exceeds this limit.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000098 int zone_excess_limit_;
ager@chromium.orga74f0da2008-12-03 16:05:52 +000099
100 // The number of bytes allocated in segments. Note that this number
101 // includes memory allocated from the OS but not yet allocated from
102 // the zone.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000103 int segment_bytes_allocated_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000104
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000105 // Each isolate gets its own zone.
106 Zone();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000107
108 // Expand the Zone to hold at least 'size' more bytes and allocate
109 // the bytes. Returns the address of the newly allocated chunk of
110 // memory in the Zone. Should only be called if there isn't enough
111 // room in the Zone already.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000112 Address NewExpand(int size);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000113
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000114 // Creates a new segment, sets it size, and pushes it to the front
115 // of the segment chain. Returns the new segment.
116 Segment* NewSegment(int size);
117
118 // Deletes the given segment. Does not touch the segment chain.
119 void DeleteSegment(Segment* segment, int size);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000120
121 // The free region in the current (front) segment is represented as
122 // the half-open interval [position, limit). The 'position' variable
123 // is guaranteed to be aligned as dictated by kAlignment.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000124 Address position_;
125 Address limit_;
126
127 int scope_nesting_;
128
129 Segment* segment_head_;
130 Isolate* isolate_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000131};
132
133
134// ZoneObject is an abstraction that helps define classes of objects
135// allocated in the Zone. Use it as a base class; see ast.h.
136class ZoneObject {
137 public:
138 // Allocate a new ZoneObject of 'size' bytes in the Zone.
danno@chromium.org40cb8782011-05-25 07:58:50 +0000139 INLINE(void* operator new(size_t size));
140 INLINE(void* operator new(size_t size, Zone* zone));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000141
142 // Ideally, the delete operator should be private instead of
ager@chromium.org32912102009-01-16 10:38:43 +0000143 // public, but unfortunately the compiler sometimes synthesizes
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000144 // (unused) destructors for classes derived from ZoneObject, which
145 // require the operator to be visible. MSVC requires the delete
146 // operator to be public.
147
148 // ZoneObjects should never be deleted individually; use
149 // Zone::DeleteAll() to delete all zone objects in one go.
150 void operator delete(void*, size_t) { UNREACHABLE(); }
151};
152
153
154class AssertNoZoneAllocation {
155 public:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000156 inline AssertNoZoneAllocation();
157 inline ~AssertNoZoneAllocation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000158 private:
159 bool prev_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000160};
161
162
163// The ZoneListAllocationPolicy is used to specialize the GenericList
164// implementation to allocate ZoneLists and their elements in the
165// Zone.
166class ZoneListAllocationPolicy {
167 public:
168 // Allocate 'size' bytes of memory in the zone.
whesse@chromium.org030d38e2011-07-13 13:23:34 +0000169 static void* New(int size);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000170
171 // De-allocation attempts are silently ignored.
172 static void Delete(void* p) { }
173};
174
175
176// ZoneLists are growable lists with constant-time access to the
177// elements. The list itself and all its elements are allocated in the
178// Zone. ZoneLists cannot be deleted individually; you can delete all
179// objects in the Zone by calling Zone::DeleteAll().
180template<typename T>
181class ZoneList: public List<T, ZoneListAllocationPolicy> {
182 public:
danno@chromium.org40cb8782011-05-25 07:58:50 +0000183 INLINE(void* operator new(size_t size));
184 INLINE(void* operator new(size_t size, Zone* zone));
185
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000186 // Construct a new ZoneList with the given capacity; the length is
187 // always zero. The capacity must be non-negative.
188 explicit ZoneList(int capacity)
189 : List<T, ZoneListAllocationPolicy>(capacity) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000190
191 // Construct a new ZoneList by copying the elements of the given ZoneList.
192 explicit ZoneList(const ZoneList<T>& other)
193 : List<T, ZoneListAllocationPolicy>(other.length()) {
194 AddAll(other);
195 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000196};
197
198
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000199// Introduce a convenience type for zone lists of map handles.
200typedef ZoneList<Handle<Map> > ZoneMapList;
201
202
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000203// ZoneScopes keep track of the current parsing and compilation
204// nesting and cleans up generated ASTs in the Zone when exiting the
205// outer-most scope.
206class ZoneScope BASE_EMBEDDED {
207 public:
danno@chromium.org40cb8782011-05-25 07:58:50 +0000208 INLINE(ZoneScope(Isolate* isolate, ZoneScopeMode mode));
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000209
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000210 virtual ~ZoneScope();
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +0000211
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000212 inline bool ShouldDeleteOnExit();
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000213
214 // For ZoneScopes that do not delete on exit by default, call this
215 // method to request deletion on exit.
216 void DeleteOnExit() {
217 mode_ = DELETE_ON_EXIT;
218 }
219
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000220 inline static int nesting();
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000221
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000222 private:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000223 Isolate* isolate_;
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000224 ZoneScopeMode mode_;
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000225};
226
227
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000228// A zone splay tree. The config type parameter encapsulates the
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000229// different configurations of a concrete splay tree (see splay-tree.h).
230// The tree itself and all its elements are allocated in the Zone.
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000231template <typename Config>
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000232class ZoneSplayTree: public SplayTree<Config, ZoneListAllocationPolicy> {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000233 public:
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000234 ZoneSplayTree()
235 : SplayTree<Config, ZoneListAllocationPolicy>() {}
236 ~ZoneSplayTree();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000237};
238
239
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000240} } // namespace v8::internal
241
242#endif // V8_ZONE_H_