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

Side by Side Diff: src/execution.cc

Issue 435003: Patch for allowing several V8 instances in process:... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years 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 | « src/execution.h ('k') | src/factory.h » ('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 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 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 20 matching lines...) Expand all
31 31
32 #include "api.h" 32 #include "api.h"
33 #include "codegen-inl.h" 33 #include "codegen-inl.h"
34 #include "debug.h" 34 #include "debug.h"
35 #include "simulator.h" 35 #include "simulator.h"
36 #include "v8threads.h" 36 #include "v8threads.h"
37 37
38 namespace v8 { 38 namespace v8 {
39 namespace internal { 39 namespace internal {
40 40
41 class StackGuardPrivateData {
42 public:
43 Thread::LocalStorageKey stack_limit_key;
44
45 StackGuardPrivateData()
46 :stack_limit_key(internal::Thread::CreateThreadLocalKey()) {
47 }
48 };
49
50 StackGuardData::StackGuardData()
51 :thread_local_(0),
52 stack_guard_private_data_(NULL) {
53 }
41 54
42 static Handle<Object> Invoke(bool construct, 55 static Handle<Object> Invoke(bool construct,
43 Handle<JSFunction> func, 56 Handle<JSFunction> func,
44 Handle<Object> receiver, 57 Handle<Object> receiver,
45 int argc, 58 int argc,
46 Object*** args, 59 Object*** args,
47 bool* has_pending_exception) { 60 bool* has_pending_exception) {
48 // Make sure we have a real function, not a boilerplate function. 61 // Make sure we have a real function, not a boilerplate function.
49 ASSERT(!func->IsBoilerplate()); 62 ASSERT(!func->IsBoilerplate());
50 63
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 HeapObject::cast(*object)->map()->has_instance_call_handler()) { 210 HeapObject::cast(*object)->map()->has_instance_call_handler()) {
198 return Handle<JSFunction>( 211 return Handle<JSFunction>(
199 Top::global_context()->call_as_constructor_delegate()); 212 Top::global_context()->call_as_constructor_delegate());
200 } 213 }
201 214
202 return Factory::undefined_value(); 215 return Factory::undefined_value();
203 } 216 }
204 217
205 218
206 // Static state for stack guards. 219 // Static state for stack guards.
207 StackGuard::ThreadLocal StackGuard::thread_local_;
208 220
209 221
210 bool StackGuard::IsStackOverflow() { 222 bool StackGuard::IsStackOverflow() {
211 ExecutionAccess access; 223 ExecutionAccess access;
212 return (thread_local_.jslimit_ != kInterruptLimit && 224 StackGuardData::ThreadLocal& thread_local = v8_context()->
213 thread_local_.climit_ != kInterruptLimit); 225 stack_guard_data_.thread_local_;
226 return (thread_local.jslimit_ != kInterruptLimit &&
227 thread_local.climit_ != kInterruptLimit);
214 } 228 }
215 229
216 230
217 void StackGuard::EnableInterrupts() { 231 void StackGuard::EnableInterrupts() {
218 ExecutionAccess access; 232 ExecutionAccess access;
219 if (IsSet(access)) { 233 if (IsSet(access)) {
220 set_limits(kInterruptLimit, access); 234 set_limits(kInterruptLimit, access);
221 } 235 }
222 } 236 }
223 237
224 238
225 void StackGuard::SetStackLimit(uintptr_t limit) { 239 void StackGuard::SetStackLimit(uintptr_t limit) {
226 ExecutionAccess access; 240 ExecutionAccess access;
241 StackGuardData::ThreadLocal& thread_local = v8_context()->
242 stack_guard_data_.thread_local_;
227 // If the current limits are special (eg due to a pending interrupt) then 243 // If the current limits are special (eg due to a pending interrupt) then
228 // leave them alone. 244 // leave them alone.
229 uintptr_t jslimit = SimulatorStack::JsLimitFromCLimit(limit); 245 uintptr_t jslimit = SimulatorStack::JsLimitFromCLimit(limit);
230 if (thread_local_.jslimit_ == thread_local_.real_jslimit_) { 246 if (thread_local.jslimit_ == thread_local.real_jslimit_) {
231 thread_local_.jslimit_ = jslimit; 247 thread_local.jslimit_ = jslimit;
232 } 248 }
233 if (thread_local_.climit_ == thread_local_.real_climit_) { 249 if (thread_local.climit_ == thread_local.real_climit_) {
234 thread_local_.climit_ = limit; 250 thread_local.climit_ = limit;
235 } 251 }
236 thread_local_.real_climit_ = limit; 252 thread_local.real_climit_ = limit;
237 thread_local_.real_jslimit_ = jslimit; 253 thread_local.real_jslimit_ = jslimit;
238 } 254 }
239 255
240 256
241 void StackGuard::DisableInterrupts() { 257 void StackGuard::DisableInterrupts() {
242 ExecutionAccess access; 258 ExecutionAccess access;
243 reset_limits(access); 259 reset_limits(access);
244 } 260 }
245 261
246 262
247 bool StackGuard::IsSet(const ExecutionAccess& lock) { 263 bool StackGuard::IsSet(const ExecutionAccess& lock) {
248 return thread_local_.interrupt_flags_ != 0; 264 return v8_context()->stack_guard_data_.thread_local_.interrupt_flags_ != 0;
249 } 265 }
250 266
251 267
252 bool StackGuard::IsInterrupted() { 268 bool StackGuard::IsInterrupted() {
253 ExecutionAccess access; 269 ExecutionAccess access;
254 return thread_local_.interrupt_flags_ & INTERRUPT; 270 return v8_context()->
271 stack_guard_data_.thread_local_.interrupt_flags_ & INTERRUPT;
255 } 272 }
256 273
257 274
258 void StackGuard::Interrupt() { 275 void StackGuard::Interrupt() {
259 ExecutionAccess access; 276 ExecutionAccess access;
260 thread_local_.interrupt_flags_ |= INTERRUPT; 277 v8_context()->stack_guard_data_.thread_local_.interrupt_flags_ |= INTERRUPT;
261 set_limits(kInterruptLimit, access); 278 set_limits(kInterruptLimit, access);
262 } 279 }
263 280
264 281
265 bool StackGuard::IsPreempted() { 282 bool StackGuard::IsPreempted() {
266 ExecutionAccess access; 283 ExecutionAccess access;
267 return thread_local_.interrupt_flags_ & PREEMPT; 284 return v8_context()->
285 stack_guard_data_.thread_local_.interrupt_flags_ & PREEMPT;
268 } 286 }
269 287
270 288
271 void StackGuard::Preempt() { 289 void StackGuard::Preempt() {
272 ExecutionAccess access; 290 ExecutionAccess access;
273 thread_local_.interrupt_flags_ |= PREEMPT; 291 v8_context()->stack_guard_data_.thread_local_.interrupt_flags_ |= PREEMPT;
274 set_limits(kInterruptLimit, access); 292 set_limits(kInterruptLimit, access);
275 } 293 }
276 294
277 295
278 bool StackGuard::IsTerminateExecution() { 296 bool StackGuard::IsTerminateExecution() {
279 ExecutionAccess access; 297 ExecutionAccess access;
280 return thread_local_.interrupt_flags_ & TERMINATE; 298 return v8_context()->
299 stack_guard_data_.thread_local_.interrupt_flags_ & TERMINATE;
281 } 300 }
282 301
283 302
284 void StackGuard::TerminateExecution() { 303 void StackGuard::TerminateExecution() {
285 ExecutionAccess access; 304 ExecutionAccess access;
286 thread_local_.interrupt_flags_ |= TERMINATE; 305 v8_context()->stack_guard_data_.thread_local_.interrupt_flags_ |= TERMINATE;
287 set_limits(kInterruptLimit, access); 306 set_limits(kInterruptLimit, access);
288 } 307 }
289 308
290 309
291 #ifdef ENABLE_DEBUGGER_SUPPORT 310 #ifdef ENABLE_DEBUGGER_SUPPORT
292 bool StackGuard::IsDebugBreak() { 311 bool StackGuard::IsDebugBreak() {
293 ExecutionAccess access; 312 ExecutionAccess access;
294 return thread_local_.interrupt_flags_ & DEBUGBREAK; 313 return v8_context()->
314 stack_guard_data_.thread_local_.interrupt_flags_ & DEBUGBREAK;
295 } 315 }
296 316
297 317
298 void StackGuard::DebugBreak() { 318 void StackGuard::DebugBreak() {
299 ExecutionAccess access; 319 ExecutionAccess access;
300 thread_local_.interrupt_flags_ |= DEBUGBREAK; 320 v8_context()->stack_guard_data_.thread_local_.interrupt_flags_ |= DEBUGBREAK;
301 set_limits(kInterruptLimit, access); 321 set_limits(kInterruptLimit, access);
302 } 322 }
303 323
304 324
305 bool StackGuard::IsDebugCommand() { 325 bool StackGuard::IsDebugCommand() {
306 ExecutionAccess access; 326 ExecutionAccess access;
307 return thread_local_.interrupt_flags_ & DEBUGCOMMAND; 327 return v8_context()->
328 stack_guard_data_.thread_local_.interrupt_flags_ & DEBUGCOMMAND;
308 } 329 }
309 330
310 331
311 void StackGuard::DebugCommand() { 332 void StackGuard::DebugCommand() {
312 if (FLAG_debugger_auto_break) { 333 if (FLAG_debugger_auto_break) {
313 ExecutionAccess access; 334 ExecutionAccess access;
314 thread_local_.interrupt_flags_ |= DEBUGCOMMAND; 335 v8_context()->
336 stack_guard_data_.thread_local_.interrupt_flags_ |= DEBUGCOMMAND;
315 set_limits(kInterruptLimit, access); 337 set_limits(kInterruptLimit, access);
316 } 338 }
317 } 339 }
318 #endif 340 #endif
319 341
320 void StackGuard::Continue(InterruptFlag after_what) { 342 void StackGuard::Continue(InterruptFlag after_what) {
321 ExecutionAccess access; 343 ExecutionAccess access;
322 thread_local_.interrupt_flags_ &= ~static_cast<int>(after_what); 344 StackGuardData::ThreadLocal& thread_local = v8_context()->
323 if (thread_local_.interrupt_flags_ == 0) { 345 stack_guard_data_.thread_local_;
346 thread_local.interrupt_flags_ &= ~static_cast<int>(after_what);
347 if (thread_local.interrupt_flags_ == 0) {
324 reset_limits(access); 348 reset_limits(access);
325 } 349 }
326 } 350 }
327 351
328 352
329 int StackGuard::ArchiveSpacePerThread() { 353 int StackGuard::ArchiveSpacePerThread() {
330 return sizeof(ThreadLocal); 354 return sizeof(StackGuardData::ThreadLocal);
331 } 355 }
332 356
333 357
334 char* StackGuard::ArchiveStackGuard(char* to) { 358 char* StackGuard::ArchiveStackGuard(char* to) {
335 ExecutionAccess access; 359 ExecutionAccess access;
336 memcpy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal)); 360 StackGuardData::ThreadLocal& thread_local = v8_context()->
337 ThreadLocal blank; 361 stack_guard_data_.thread_local_;
338 thread_local_ = blank; 362 memcpy(
339 return to + sizeof(ThreadLocal); 363 to,
364 reinterpret_cast<char*>(&thread_local),
365 sizeof(StackGuardData::ThreadLocal));
366 StackGuardData::ThreadLocal blank;
367 thread_local = blank;
368 return to + sizeof(StackGuardData::ThreadLocal);
340 } 369 }
341 370
342 371
343 char* StackGuard::RestoreStackGuard(char* from) { 372 char* StackGuard::RestoreStackGuard(char* from) {
344 ExecutionAccess access; 373 ExecutionAccess access;
345 memcpy(reinterpret_cast<char*>(&thread_local_), from, sizeof(ThreadLocal)); 374 memcpy(
375 reinterpret_cast<char*>(&v8_context()->stack_guard_data_.thread_local_),
376 from,
377 sizeof(StackGuardData::ThreadLocal));
346 Heap::SetStackLimits(); 378 Heap::SetStackLimits();
347 return from + sizeof(ThreadLocal); 379 return from + sizeof(StackGuardData::ThreadLocal);
348 } 380 }
349 381
350 382
351 static internal::Thread::LocalStorageKey stack_limit_key = 383 void StackGuard::PostConstruct() {
352 internal::Thread::CreateThreadLocalKey(); 384 V8Context* const v8context = v8_context();
385 v8context->stack_guard_data_.thread_local_.Clear();
386 v8context->stack_guard_data_.stack_guard_private_data_ =
387 new StackGuardPrivateData();
388 }
353 389
390 void StackGuard::PreDestroy() {
391 delete v8_context()->stack_guard_data_.stack_guard_private_data_;
392 }
354 393
355 void StackGuard::FreeThreadResources() { 394 void StackGuard::FreeThreadResources() {
395 StackGuardData& stack_guard_data = v8_context()->stack_guard_data_;
356 Thread::SetThreadLocal( 396 Thread::SetThreadLocal(
357 stack_limit_key, 397 stack_guard_data.stack_guard_private_data_->stack_limit_key,
358 reinterpret_cast<void*>(thread_local_.real_climit_)); 398 reinterpret_cast<void*>(stack_guard_data.thread_local_.real_climit_));
359 } 399 }
360 400
361 401
362 void StackGuard::ThreadLocal::Clear() { 402 void StackGuardData::ThreadLocal::Clear() {
363 real_jslimit_ = kIllegalLimit; 403 real_jslimit_ = StackGuard::kIllegalLimit;
364 jslimit_ = kIllegalLimit; 404 jslimit_ = StackGuard::kIllegalLimit;
365 real_climit_ = kIllegalLimit; 405 real_climit_ = StackGuard::kIllegalLimit;
366 climit_ = kIllegalLimit; 406 climit_ = StackGuard::kIllegalLimit;
367 nesting_ = 0; 407 nesting_ = 0;
368 postpone_interrupts_nesting_ = 0; 408 postpone_interrupts_nesting_ = 0;
369 interrupt_flags_ = 0; 409 interrupt_flags_ = 0;
370 Heap::SetStackLimits(); 410 Heap::SetStackLimits();
371 } 411 }
372 412
373 413
374 void StackGuard::ThreadLocal::Initialize() { 414 void StackGuardData::ThreadLocal::Initialize() {
375 if (real_climit_ == kIllegalLimit) { 415 if (real_climit_ == StackGuard::kIllegalLimit) {
376 // Takes the address of the limit variable in order to find out where 416 // Takes the address of the limit variable in order to find out where
377 // the top of stack is right now. 417 // the top of stack is right now.
378 uintptr_t limit = reinterpret_cast<uintptr_t>(&limit) - kLimitSize; 418 uintptr_t limit = reinterpret_cast<uintptr_t>(&limit) -
379 ASSERT(reinterpret_cast<uintptr_t>(&limit) > kLimitSize); 419 StackGuard::kLimitSize;
420 ASSERT(reinterpret_cast<uintptr_t>(&limit) > StackGuard::kLimitSize);
380 real_jslimit_ = SimulatorStack::JsLimitFromCLimit(limit); 421 real_jslimit_ = SimulatorStack::JsLimitFromCLimit(limit);
381 jslimit_ = SimulatorStack::JsLimitFromCLimit(limit); 422 jslimit_ = SimulatorStack::JsLimitFromCLimit(limit);
382 real_climit_ = limit; 423 real_climit_ = limit;
383 climit_ = limit; 424 climit_ = limit;
384 Heap::SetStackLimits(); 425 Heap::SetStackLimits();
385 } 426 }
386 nesting_ = 0; 427 nesting_ = 0;
387 postpone_interrupts_nesting_ = 0; 428 postpone_interrupts_nesting_ = 0;
388 interrupt_flags_ = 0; 429 interrupt_flags_ = 0;
389 } 430 }
390 431
391 432
392 void StackGuard::ClearThread(const ExecutionAccess& lock) { 433 void StackGuard::ClearThread(const ExecutionAccess& lock) {
393 thread_local_.Clear(); 434 v8_context()->stack_guard_data_.thread_local_.Clear();
394 } 435 }
395 436
396 437
397 void StackGuard::InitThread(const ExecutionAccess& lock) { 438 void StackGuard::InitThread(const ExecutionAccess& lock) {
398 thread_local_.Initialize(); 439 StackGuardData& stack_guard_data = v8_context()->stack_guard_data_;
399 void* stored_limit = Thread::GetThreadLocal(stack_limit_key); 440 stack_guard_data.thread_local_.Initialize();
441 void* stored_limit = Thread::GetThreadLocal(
442 stack_guard_data.stack_guard_private_data_->stack_limit_key);
400 // You should hold the ExecutionAccess lock when you call this. 443 // You should hold the ExecutionAccess lock when you call this.
401 if (stored_limit != NULL) { 444 if (stored_limit != NULL) {
402 StackGuard::SetStackLimit(reinterpret_cast<intptr_t>(stored_limit)); 445 StackGuard::SetStackLimit(reinterpret_cast<intptr_t>(stored_limit));
403 } 446 }
404 } 447 }
405 448
406 449
407 // --- C a l l s t o n a t i v e s --- 450 // --- C a l l s t o n a t i v e s ---
408 451
409 #define RETURN_NATIVE_CALL(name, argc, argv, has_pending_exception) \ 452 #define RETURN_NATIVE_CALL(name, argc, argv, has_pending_exception) \
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
682 // All allocation spaces other than NEW_SPACE have the same effect. 725 // All allocation spaces other than NEW_SPACE have the same effect.
683 Heap::CollectAllGarbage(false); 726 Heap::CollectAllGarbage(false);
684 return v8::Undefined(); 727 return v8::Undefined();
685 } 728 }
686 729
687 730
688 static GCExtension kGCExtension; 731 static GCExtension kGCExtension;
689 v8::DeclareExtension kGCExtensionDeclaration(&kGCExtension); 732 v8::DeclareExtension kGCExtensionDeclaration(&kGCExtension);
690 733
691 } } // namespace v8::internal 734 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/execution.h ('k') | src/factory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698