OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 21 matching lines...) Expand all Loading... |
32 namespace internal { | 32 namespace internal { |
33 | 33 |
34 | 34 |
35 // Zone scopes are in one of two modes. Either they delete the zone | 35 // Zone scopes are in one of two modes. Either they delete the zone |
36 // on exit or they do not. | 36 // on exit or they do not. |
37 enum ZoneScopeMode { | 37 enum ZoneScopeMode { |
38 DELETE_ON_EXIT, | 38 DELETE_ON_EXIT, |
39 DONT_DELETE_ON_EXIT | 39 DONT_DELETE_ON_EXIT |
40 }; | 40 }; |
41 | 41 |
| 42 class Segment; |
42 | 43 |
43 // The Zone supports very fast allocation of small chunks of | 44 // The Zone supports very fast allocation of small chunks of |
44 // memory. The chunks cannot be deallocated individually, but instead | 45 // memory. The chunks cannot be deallocated individually, but instead |
45 // the Zone supports deallocating all chunks in one fast | 46 // the Zone supports deallocating all chunks in one fast |
46 // operation. The Zone is used to hold temporary data structures like | 47 // operation. The Zone is used to hold temporary data structures like |
47 // the abstract syntax tree, which is deallocated after compilation. | 48 // the abstract syntax tree, which is deallocated after compilation. |
48 | 49 |
49 // Note: There is no need to initialize the Zone; the first time an | 50 // Note: There is no need to initialize the Zone; the first time an |
50 // allocation is attempted, a segment of memory will be requested | 51 // allocation is attempted, a segment of memory will be requested |
51 // through a call to malloc(). | 52 // through a call to malloc(). |
52 | 53 |
53 // Note: The implementation is inherently not thread safe. Do not use | 54 // Note: The implementation is inherently not thread safe. Do not use |
54 // from multi-threaded code. | 55 // from multi-threaded code. |
55 | 56 |
56 class Zone { | 57 class Zone { |
57 public: | 58 public: |
58 // Allocate 'size' bytes of memory in the Zone; expands the Zone by | 59 // Allocate 'size' bytes of memory in the Zone; expands the Zone by |
59 // allocating new segments of memory on demand using malloc(). | 60 // allocating new segments of memory on demand using malloc(). |
60 static inline void* New(int size); | 61 inline void* New(int size); |
61 | 62 |
62 template <typename T> | 63 template <typename T> |
63 static inline T* NewArray(int length); | 64 inline T* NewArray(int length); |
64 | 65 |
65 // Delete all objects and free all memory allocated in the Zone. | 66 // Delete all objects and free all memory allocated in the Zone. |
66 static void DeleteAll(); | 67 void DeleteAll(); |
67 | 68 |
68 // Returns true if more memory has been allocated in zones than | 69 // Returns true if more memory has been allocated in zones than |
69 // the limit allows. | 70 // the limit allows. |
70 static inline bool excess_allocation(); | 71 inline bool excess_allocation(); |
71 | 72 |
72 static inline void adjust_segment_bytes_allocated(int delta); | 73 inline void adjust_segment_bytes_allocated(int delta); |
73 | 74 |
74 static unsigned allocation_size_; | 75 static unsigned allocation_size_; |
75 | 76 |
76 private: | 77 private: |
| 78 friend class Isolate; |
| 79 friend class ZoneScope; |
77 | 80 |
78 // All pointers returned from New() have this alignment. | 81 // All pointers returned from New() have this alignment. |
79 static const int kAlignment = kPointerSize; | 82 static const int kAlignment = kPointerSize; |
80 | 83 |
81 // Never allocate segments smaller than this size in bytes. | 84 // Never allocate segments smaller than this size in bytes. |
82 static const int kMinimumSegmentSize = 8 * KB; | 85 static const int kMinimumSegmentSize = 8 * KB; |
83 | 86 |
84 // Never allocate segments larger than this size in bytes. | 87 // Never allocate segments larger than this size in bytes. |
85 static const int kMaximumSegmentSize = 1 * MB; | 88 static const int kMaximumSegmentSize = 1 * MB; |
86 | 89 |
87 // Never keep segments larger than this size in bytes around. | 90 // Never keep segments larger than this size in bytes around. |
88 static const int kMaximumKeptSegmentSize = 64 * KB; | 91 static const int kMaximumKeptSegmentSize = 64 * KB; |
89 | 92 |
90 // Report zone excess when allocation exceeds this limit. | 93 // Report zone excess when allocation exceeds this limit. |
91 static int zone_excess_limit_; | 94 int zone_excess_limit_; |
92 | 95 |
93 // The number of bytes allocated in segments. Note that this number | 96 // The number of bytes allocated in segments. Note that this number |
94 // includes memory allocated from the OS but not yet allocated from | 97 // includes memory allocated from the OS but not yet allocated from |
95 // the zone. | 98 // the zone. |
96 static int segment_bytes_allocated_; | 99 int segment_bytes_allocated_; |
97 | 100 |
98 // The Zone is intentionally a singleton; you should not try to | 101 // Each isolate gets its own zone. |
99 // allocate instances of the class. | 102 Zone(); |
100 Zone() { UNREACHABLE(); } | |
101 | |
102 | 103 |
103 // Expand the Zone to hold at least 'size' more bytes and allocate | 104 // Expand the Zone to hold at least 'size' more bytes and allocate |
104 // the bytes. Returns the address of the newly allocated chunk of | 105 // the bytes. Returns the address of the newly allocated chunk of |
105 // memory in the Zone. Should only be called if there isn't enough | 106 // memory in the Zone. Should only be called if there isn't enough |
106 // room in the Zone already. | 107 // room in the Zone already. |
107 static Address NewExpand(int size); | 108 Address NewExpand(int size); |
108 | 109 |
| 110 // Creates a new segment, sets it size, and pushes it to the front |
| 111 // of the segment chain. Returns the new segment. |
| 112 Segment* NewSegment(int size); |
| 113 |
| 114 // Deletes the given segment. Does not touch the segment chain. |
| 115 void DeleteSegment(Segment* segment, int size); |
109 | 116 |
110 // The free region in the current (front) segment is represented as | 117 // The free region in the current (front) segment is represented as |
111 // the half-open interval [position, limit). The 'position' variable | 118 // the half-open interval [position, limit). The 'position' variable |
112 // is guaranteed to be aligned as dictated by kAlignment. | 119 // is guaranteed to be aligned as dictated by kAlignment. |
113 static Address position_; | 120 Address position_; |
114 static Address limit_; | 121 Address limit_; |
| 122 |
| 123 int scope_nesting_; |
| 124 |
| 125 Segment* segment_head_; |
| 126 Isolate* isolate_; |
115 }; | 127 }; |
116 | 128 |
117 | 129 |
118 // ZoneObject is an abstraction that helps define classes of objects | 130 // ZoneObject is an abstraction that helps define classes of objects |
119 // allocated in the Zone. Use it as a base class; see ast.h. | 131 // allocated in the Zone. Use it as a base class; see ast.h. |
120 class ZoneObject { | 132 class ZoneObject { |
121 public: | 133 public: |
122 // Allocate a new ZoneObject of 'size' bytes in the Zone. | 134 // Allocate a new ZoneObject of 'size' bytes in the Zone. |
123 void* operator new(size_t size) { return Zone::New(static_cast<int>(size)); } | 135 inline void* operator new(size_t size); |
124 | 136 |
125 // Ideally, the delete operator should be private instead of | 137 // Ideally, the delete operator should be private instead of |
126 // public, but unfortunately the compiler sometimes synthesizes | 138 // public, but unfortunately the compiler sometimes synthesizes |
127 // (unused) destructors for classes derived from ZoneObject, which | 139 // (unused) destructors for classes derived from ZoneObject, which |
128 // require the operator to be visible. MSVC requires the delete | 140 // require the operator to be visible. MSVC requires the delete |
129 // operator to be public. | 141 // operator to be public. |
130 | 142 |
131 // ZoneObjects should never be deleted individually; use | 143 // ZoneObjects should never be deleted individually; use |
132 // Zone::DeleteAll() to delete all zone objects in one go. | 144 // Zone::DeleteAll() to delete all zone objects in one go. |
133 void operator delete(void*, size_t) { UNREACHABLE(); } | 145 void operator delete(void*, size_t) { UNREACHABLE(); } |
134 }; | 146 }; |
135 | 147 |
136 | 148 |
137 class AssertNoZoneAllocation { | 149 class AssertNoZoneAllocation { |
138 public: | 150 public: |
139 AssertNoZoneAllocation() : prev_(allow_allocation_) { | 151 inline AssertNoZoneAllocation(); |
140 allow_allocation_ = false; | 152 inline ~AssertNoZoneAllocation(); |
141 } | |
142 ~AssertNoZoneAllocation() { allow_allocation_ = prev_; } | |
143 static bool allow_allocation() { return allow_allocation_; } | |
144 private: | 153 private: |
145 bool prev_; | 154 bool prev_; |
146 static bool allow_allocation_; | |
147 }; | 155 }; |
148 | 156 |
149 | 157 |
150 // The ZoneListAllocationPolicy is used to specialize the GenericList | 158 // The ZoneListAllocationPolicy is used to specialize the GenericList |
151 // implementation to allocate ZoneLists and their elements in the | 159 // implementation to allocate ZoneLists and their elements in the |
152 // Zone. | 160 // Zone. |
153 class ZoneListAllocationPolicy { | 161 class ZoneListAllocationPolicy { |
154 public: | 162 public: |
155 // Allocate 'size' bytes of memory in the zone. | 163 // Allocate 'size' bytes of memory in the zone. |
156 static void* New(int size) { return Zone::New(size); } | 164 static inline void* New(int size); |
157 | 165 |
158 // De-allocation attempts are silently ignored. | 166 // De-allocation attempts are silently ignored. |
159 static void Delete(void* p) { } | 167 static void Delete(void* p) { } |
160 }; | 168 }; |
161 | 169 |
162 | 170 |
163 // ZoneLists are growable lists with constant-time access to the | 171 // ZoneLists are growable lists with constant-time access to the |
164 // elements. The list itself and all its elements are allocated in the | 172 // elements. The list itself and all its elements are allocated in the |
165 // Zone. ZoneLists cannot be deleted individually; you can delete all | 173 // Zone. ZoneLists cannot be deleted individually; you can delete all |
166 // objects in the Zone by calling Zone::DeleteAll(). | 174 // objects in the Zone by calling Zone::DeleteAll(). |
(...skipping 15 matching lines...) Expand all Loading... |
182 | 190 |
183 // Introduce a convenience type for zone lists of map handles. | 191 // Introduce a convenience type for zone lists of map handles. |
184 typedef ZoneList<Handle<Map> > ZoneMapList; | 192 typedef ZoneList<Handle<Map> > ZoneMapList; |
185 | 193 |
186 | 194 |
187 // ZoneScopes keep track of the current parsing and compilation | 195 // ZoneScopes keep track of the current parsing and compilation |
188 // nesting and cleans up generated ASTs in the Zone when exiting the | 196 // nesting and cleans up generated ASTs in the Zone when exiting the |
189 // outer-most scope. | 197 // outer-most scope. |
190 class ZoneScope BASE_EMBEDDED { | 198 class ZoneScope BASE_EMBEDDED { |
191 public: | 199 public: |
192 explicit ZoneScope(ZoneScopeMode mode) : mode_(mode) { | 200 // TODO(isolates): pass isolate pointer here. |
193 nesting_++; | 201 inline explicit ZoneScope(ZoneScopeMode mode); |
194 } | |
195 | 202 |
196 virtual ~ZoneScope() { | 203 virtual ~ZoneScope(); |
197 if (ShouldDeleteOnExit()) Zone::DeleteAll(); | |
198 --nesting_; | |
199 } | |
200 | 204 |
201 bool ShouldDeleteOnExit() { | 205 inline bool ShouldDeleteOnExit(); |
202 return nesting_ == 1 && mode_ == DELETE_ON_EXIT; | |
203 } | |
204 | 206 |
205 // For ZoneScopes that do not delete on exit by default, call this | 207 // For ZoneScopes that do not delete on exit by default, call this |
206 // method to request deletion on exit. | 208 // method to request deletion on exit. |
207 void DeleteOnExit() { | 209 void DeleteOnExit() { |
208 mode_ = DELETE_ON_EXIT; | 210 mode_ = DELETE_ON_EXIT; |
209 } | 211 } |
210 | 212 |
211 static int nesting() { return nesting_; } | 213 inline static int nesting(); |
212 | 214 |
213 private: | 215 private: |
| 216 Isolate* isolate_; |
214 ZoneScopeMode mode_; | 217 ZoneScopeMode mode_; |
215 static int nesting_; | |
216 }; | 218 }; |
217 | 219 |
218 | 220 |
219 // A zone splay tree. The config type parameter encapsulates the | 221 // A zone splay tree. The config type parameter encapsulates the |
220 // different configurations of a concrete splay tree (see splay-tree.h). | 222 // different configurations of a concrete splay tree (see splay-tree.h). |
221 // The tree itself and all its elements are allocated in the Zone. | 223 // The tree itself and all its elements are allocated in the Zone. |
222 template <typename Config> | 224 template <typename Config> |
223 class ZoneSplayTree: public SplayTree<Config, ZoneListAllocationPolicy> { | 225 class ZoneSplayTree: public SplayTree<Config, ZoneListAllocationPolicy> { |
224 public: | 226 public: |
225 ZoneSplayTree() | 227 ZoneSplayTree() |
226 : SplayTree<Config, ZoneListAllocationPolicy>() {} | 228 : SplayTree<Config, ZoneListAllocationPolicy>() {} |
227 ~ZoneSplayTree(); | 229 ~ZoneSplayTree(); |
228 }; | 230 }; |
229 | 231 |
230 | 232 |
231 } } // namespace v8::internal | 233 } } // namespace v8::internal |
232 | 234 |
233 #endif // V8_ZONE_H_ | 235 #endif // V8_ZONE_H_ |
OLD | NEW |