Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(83)

Side by Side Diff: src/execution.h

Issue 362493002: Revert "Add mechanism to postpone interrupts selectively." (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | src/execution.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef V8_EXECUTION_H_ 5 #ifndef V8_EXECUTION_H_
6 #define V8_EXECUTION_H_ 6 #define V8_EXECUTION_H_
7 7
8 #include "src/handles.h" 8 #include "src/handles.h"
9 9
10 namespace v8 { 10 namespace v8 {
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 // Get a function delegate (or undefined) for the given non-function 115 // Get a function delegate (or undefined) for the given non-function
116 // object. Used for support calling objects as constructors. 116 // object. Used for support calling objects as constructors.
117 static Handle<Object> GetConstructorDelegate(Isolate* isolate, 117 static Handle<Object> GetConstructorDelegate(Isolate* isolate,
118 Handle<Object> object); 118 Handle<Object> object);
119 static MaybeHandle<Object> TryGetConstructorDelegate(Isolate* isolate, 119 static MaybeHandle<Object> TryGetConstructorDelegate(Isolate* isolate,
120 Handle<Object> object); 120 Handle<Object> object);
121 }; 121 };
122 122
123 123
124 class ExecutionAccess; 124 class ExecutionAccess;
125 class PostponeInterruptsScope;
126 125
127 126
128 // StackGuard contains the handling of the limits that are used to limit the 127 // StackGuard contains the handling of the limits that are used to limit the
129 // number of nested invocations of JavaScript and the stack size used in each 128 // number of nested invocations of JavaScript and the stack size used in each
130 // invocation. 129 // invocation.
131 class StackGuard V8_FINAL { 130 class StackGuard V8_FINAL {
132 public: 131 public:
133 // Pass the address beyond which the stack should not grow. The stack 132 // Pass the address beyond which the stack should not grow. The stack
134 // is assumed to grow downwards. 133 // is assumed to grow downwards.
135 void SetStackLimit(uintptr_t limit); 134 void SetStackLimit(uintptr_t limit);
136 135
137 // Threading support. 136 // Threading support.
138 char* ArchiveStackGuard(char* to); 137 char* ArchiveStackGuard(char* to);
139 char* RestoreStackGuard(char* from); 138 char* RestoreStackGuard(char* from);
140 static int ArchiveSpacePerThread() { return sizeof(ThreadLocal); } 139 static int ArchiveSpacePerThread() { return sizeof(ThreadLocal); }
141 void FreeThreadResources(); 140 void FreeThreadResources();
142 // Sets up the default stack guard for this thread if it has not 141 // Sets up the default stack guard for this thread if it has not
143 // already been set up. 142 // already been set up.
144 void InitThread(const ExecutionAccess& lock); 143 void InitThread(const ExecutionAccess& lock);
145 // Clears the stack guard for this thread so it does not look as if 144 // Clears the stack guard for this thread so it does not look as if
146 // it has been set up. 145 // it has been set up.
147 void ClearThread(const ExecutionAccess& lock); 146 void ClearThread(const ExecutionAccess& lock);
148 147
149 #define INTERRUPT_LIST(V) \ 148 #define INTERRUPT_LIST(V) \
150 V(DEBUGBREAK, DebugBreak, 0) \ 149 V(DEBUGBREAK, DebugBreak) \
151 V(DEBUGCOMMAND, DebugCommand, 1) \ 150 V(DEBUGCOMMAND, DebugCommand) \
152 V(TERMINATE_EXECUTION, TerminateExecution, 2) \ 151 V(TERMINATE_EXECUTION, TerminateExecution) \
153 V(GC_REQUEST, GC, 3) \ 152 V(GC_REQUEST, GC) \
154 V(INSTALL_CODE, InstallCode, 4) \ 153 V(INSTALL_CODE, InstallCode) \
155 V(API_INTERRUPT, ApiInterrupt, 5) \ 154 V(API_INTERRUPT, ApiInterrupt) \
156 V(DEOPT_MARKED_ALLOCATION_SITES, DeoptMarkedAllocationSites, 6) 155 V(DEOPT_MARKED_ALLOCATION_SITES, DeoptMarkedAllocationSites)
157 156
158 #define V(NAME, Name, id) \ 157 #define V(NAME, Name) \
159 inline bool Check##Name() { return CheckInterrupt(NAME); } \ 158 inline bool Check##Name() { return CheckInterrupt(1 << NAME); } \
160 inline void Request##Name() { RequestInterrupt(NAME); } \ 159 inline void Request##Name() { RequestInterrupt(1 << NAME); } \
161 inline void Clear##Name() { ClearInterrupt(NAME); } 160 inline void Clear##Name() { ClearInterrupt(1 << NAME); }
162 INTERRUPT_LIST(V) 161 INTERRUPT_LIST(V)
163 #undef V 162 #undef V
164 163
165 // Flag used to set the interrupt causes.
166 enum InterruptFlag {
167 #define V(NAME, Name, id) NAME = (1 << id),
168 INTERRUPT_LIST(V)
169 #undef V
170 #define V(NAME, Name, id) NAME |
171 ALL_INTERRUPTS = INTERRUPT_LIST(V) 0
172 #undef V
173 };
174
175 // This provides an asynchronous read of the stack limits for the current 164 // This provides an asynchronous read of the stack limits for the current
176 // thread. There are no locks protecting this, but it is assumed that you 165 // thread. There are no locks protecting this, but it is assumed that you
177 // have the global V8 lock if you are using multiple V8 threads. 166 // have the global V8 lock if you are using multiple V8 threads.
178 uintptr_t climit() { 167 uintptr_t climit() {
179 return thread_local_.climit_; 168 return thread_local_.climit_;
180 } 169 }
181 uintptr_t real_climit() { 170 uintptr_t real_climit() {
182 return thread_local_.real_climit_; 171 return thread_local_.real_climit_;
183 } 172 }
184 uintptr_t jslimit() { 173 uintptr_t jslimit() {
185 return thread_local_.jslimit_; 174 return thread_local_.jslimit_;
186 } 175 }
187 uintptr_t real_jslimit() { 176 uintptr_t real_jslimit() {
188 return thread_local_.real_jslimit_; 177 return thread_local_.real_jslimit_;
189 } 178 }
190 Address address_of_jslimit() { 179 Address address_of_jslimit() {
191 return reinterpret_cast<Address>(&thread_local_.jslimit_); 180 return reinterpret_cast<Address>(&thread_local_.jslimit_);
192 } 181 }
193 Address address_of_real_jslimit() { 182 Address address_of_real_jslimit() {
194 return reinterpret_cast<Address>(&thread_local_.real_jslimit_); 183 return reinterpret_cast<Address>(&thread_local_.real_jslimit_);
195 } 184 }
196 185
197 // If the stack guard is triggered, but it is not an actual 186 // If the stack guard is triggered, but it is not an actual
198 // stack overflow, then handle the interruption accordingly. 187 // stack overflow, then handle the interruption accordingly.
199 Object* HandleInterrupts(); 188 Object* HandleInterrupts();
200 189
201 private: 190 private:
202 StackGuard(); 191 StackGuard();
203 192
204 bool CheckInterrupt(InterruptFlag flag); 193 // Flag used to set the interrupt causes.
205 void RequestInterrupt(InterruptFlag flag); 194 enum InterruptFlag {
206 void ClearInterrupt(InterruptFlag flag); 195 #define V(NAME, Name) NAME,
196 INTERRUPT_LIST(V)
197 #undef V
198 NUMBER_OF_INTERRUPTS
199 };
200
201 bool CheckInterrupt(int flagbit);
202 void RequestInterrupt(int flagbit);
203 void ClearInterrupt(int flagbit);
207 bool CheckAndClearInterrupt(InterruptFlag flag); 204 bool CheckAndClearInterrupt(InterruptFlag flag);
208 205
209 // You should hold the ExecutionAccess lock when calling this method. 206 // You should hold the ExecutionAccess lock when calling this method.
210 bool has_pending_interrupts(const ExecutionAccess& lock) { 207 bool has_pending_interrupts(const ExecutionAccess& lock) {
208 // Sanity check: We shouldn't be asking about pending interrupts
209 // unless we're not postponing them anymore.
210 ASSERT(!should_postpone_interrupts(lock));
211 return thread_local_.interrupt_flags_ != 0; 211 return thread_local_.interrupt_flags_ != 0;
212 } 212 }
213 213
214 // You should hold the ExecutionAccess lock when calling this method. 214 // You should hold the ExecutionAccess lock when calling this method.
215 bool should_postpone_interrupts(const ExecutionAccess& lock) {
216 return thread_local_.postpone_interrupts_nesting_ > 0;
217 }
218
219 // You should hold the ExecutionAccess lock when calling this method.
215 inline void set_interrupt_limits(const ExecutionAccess& lock); 220 inline void set_interrupt_limits(const ExecutionAccess& lock);
216 221
217 // Reset limits to actual values. For example after handling interrupt. 222 // Reset limits to actual values. For example after handling interrupt.
218 // You should hold the ExecutionAccess lock when calling this method. 223 // You should hold the ExecutionAccess lock when calling this method.
219 inline void reset_limits(const ExecutionAccess& lock); 224 inline void reset_limits(const ExecutionAccess& lock);
220 225
221 // Enable or disable interrupts. 226 // Enable or disable interrupts.
222 void EnableInterrupts(); 227 void EnableInterrupts();
223 void DisableInterrupts(); 228 void DisableInterrupts();
224 229
225 #if V8_TARGET_ARCH_64_BIT 230 #if V8_TARGET_ARCH_64_BIT
226 static const uintptr_t kInterruptLimit = V8_UINT64_C(0xfffffffffffffffe); 231 static const uintptr_t kInterruptLimit = V8_UINT64_C(0xfffffffffffffffe);
227 static const uintptr_t kIllegalLimit = V8_UINT64_C(0xfffffffffffffff8); 232 static const uintptr_t kIllegalLimit = V8_UINT64_C(0xfffffffffffffff8);
228 #else 233 #else
229 static const uintptr_t kInterruptLimit = 0xfffffffe; 234 static const uintptr_t kInterruptLimit = 0xfffffffe;
230 static const uintptr_t kIllegalLimit = 0xfffffff8; 235 static const uintptr_t kIllegalLimit = 0xfffffff8;
231 #endif 236 #endif
232 237
233 void PushPostponeInterruptsScope(PostponeInterruptsScope* scope);
234 void PopPostponeInterruptsScope();
235
236 class ThreadLocal V8_FINAL { 238 class ThreadLocal V8_FINAL {
237 public: 239 public:
238 ThreadLocal() { Clear(); } 240 ThreadLocal() { Clear(); }
239 // You should hold the ExecutionAccess lock when you call Initialize or 241 // You should hold the ExecutionAccess lock when you call Initialize or
240 // Clear. 242 // Clear.
241 void Clear(); 243 void Clear();
242 244
243 // Returns true if the heap's stack limits should be set, false if not. 245 // Returns true if the heap's stack limits should be set, false if not.
244 bool Initialize(Isolate* isolate); 246 bool Initialize(Isolate* isolate);
245 247
246 // The stack limit is split into a JavaScript and a C++ stack limit. These 248 // The stack limit is split into a JavaScript and a C++ stack limit. These
247 // two are the same except when running on a simulator where the C++ and 249 // two are the same except when running on a simulator where the C++ and
248 // JavaScript stacks are separate. Each of the two stack limits have two 250 // JavaScript stacks are separate. Each of the two stack limits have two
249 // values. The one eith the real_ prefix is the actual stack limit 251 // values. The one eith the real_ prefix is the actual stack limit
250 // set for the VM. The one without the real_ prefix has the same value as 252 // set for the VM. The one without the real_ prefix has the same value as
251 // the actual stack limit except when there is an interruption (e.g. debug 253 // the actual stack limit except when there is an interruption (e.g. debug
252 // break or preemption) in which case it is lowered to make stack checks 254 // break or preemption) in which case it is lowered to make stack checks
253 // fail. Both the generated code and the runtime system check against the 255 // fail. Both the generated code and the runtime system check against the
254 // one without the real_ prefix. 256 // one without the real_ prefix.
255 uintptr_t real_jslimit_; // Actual JavaScript stack limit set for the VM. 257 uintptr_t real_jslimit_; // Actual JavaScript stack limit set for the VM.
256 uintptr_t jslimit_; 258 uintptr_t jslimit_;
257 uintptr_t real_climit_; // Actual C++ stack limit set for the VM. 259 uintptr_t real_climit_; // Actual C++ stack limit set for the VM.
258 uintptr_t climit_; 260 uintptr_t climit_;
259 261
260 PostponeInterruptsScope* postpone_interrupts_; 262 int nesting_;
263 int postpone_interrupts_nesting_;
261 int interrupt_flags_; 264 int interrupt_flags_;
262 }; 265 };
263 266
264 class StackPointer { 267 class StackPointer {
265 public: 268 public:
266 inline uintptr_t address() { return reinterpret_cast<uintptr_t>(this); } 269 inline uintptr_t address() { return reinterpret_cast<uintptr_t>(this); }
267 }; 270 };
268 271
269 // TODO(isolates): Technically this could be calculated directly from a 272 // TODO(isolates): Technically this could be calculated directly from a
270 // pointer to StackGuard. 273 // pointer to StackGuard.
271 Isolate* isolate_; 274 Isolate* isolate_;
272 ThreadLocal thread_local_; 275 ThreadLocal thread_local_;
273 276
274 friend class Isolate; 277 friend class Isolate;
275 friend class StackLimitCheck; 278 friend class StackLimitCheck;
276 friend class PostponeInterruptsScope; 279 friend class PostponeInterruptsScope;
277 280
278 DISALLOW_COPY_AND_ASSIGN(StackGuard); 281 DISALLOW_COPY_AND_ASSIGN(StackGuard);
279 }; 282 };
280 283
281 } } // namespace v8::internal 284 } } // namespace v8::internal
282 285
283 #endif // V8_EXECUTION_H_ 286 #endif // V8_EXECUTION_H_
OLDNEW
« no previous file with comments | « no previous file | src/execution.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698