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

Side by Side Diff: src/execution.cc

Issue 359723005: 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 | « src/execution.h ('k') | src/isolate.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 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 #include "src/execution.h" 5 #include "src/execution.h"
6 6
7 #include "src/bootstrapper.h" 7 #include "src/bootstrapper.h"
8 #include "src/codegen.h" 8 #include "src/codegen.h"
9 #include "src/deoptimizer.h" 9 #include "src/deoptimizer.h"
10 #include "src/isolate-inl.h" 10 #include "src/isolate-inl.h"
11 #include "src/vm-state-inl.h" 11 #include "src/vm-state-inl.h"
12 12
13 namespace v8 { 13 namespace v8 {
14 namespace internal { 14 namespace internal {
15 15
16 StackGuard::StackGuard() 16 StackGuard::StackGuard()
17 : isolate_(NULL) { 17 : isolate_(NULL) {
18 } 18 }
19 19
20 20
21 void StackGuard::set_interrupt_limits(const ExecutionAccess& lock) { 21 void StackGuard::set_interrupt_limits(const ExecutionAccess& lock) {
22 ASSERT(isolate_ != NULL); 22 ASSERT(isolate_ != NULL);
23 // Ignore attempts to interrupt when interrupts are postponed.
24 if (should_postpone_interrupts(lock)) return;
25 thread_local_.jslimit_ = kInterruptLimit; 23 thread_local_.jslimit_ = kInterruptLimit;
26 thread_local_.climit_ = kInterruptLimit; 24 thread_local_.climit_ = kInterruptLimit;
27 isolate_->heap()->SetStackLimits(); 25 isolate_->heap()->SetStackLimits();
28 } 26 }
29 27
30 28
31 void StackGuard::reset_limits(const ExecutionAccess& lock) { 29 void StackGuard::reset_limits(const ExecutionAccess& lock) {
32 ASSERT(isolate_ != NULL); 30 ASSERT(isolate_ != NULL);
33 thread_local_.jslimit_ = thread_local_.real_jslimit_; 31 thread_local_.jslimit_ = thread_local_.real_jslimit_;
34 thread_local_.climit_ = thread_local_.real_climit_; 32 thread_local_.climit_ = thread_local_.real_climit_;
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 thread_local_.real_jslimit_ = jslimit; 328 thread_local_.real_jslimit_ = jslimit;
331 } 329 }
332 330
333 331
334 void StackGuard::DisableInterrupts() { 332 void StackGuard::DisableInterrupts() {
335 ExecutionAccess access(isolate_); 333 ExecutionAccess access(isolate_);
336 reset_limits(access); 334 reset_limits(access);
337 } 335 }
338 336
339 337
340 bool StackGuard::CheckInterrupt(int flagbit) { 338 void StackGuard::PushPostponeInterruptsScope(PostponeInterruptsScope* scope) {
341 ExecutionAccess access(isolate_); 339 ExecutionAccess access(isolate_);
342 return thread_local_.interrupt_flags_ & flagbit; 340 scope->prev_ = thread_local_.postpone_interrupts_;
341 thread_local_.postpone_interrupts_ = scope;
343 } 342 }
344 343
345 344
346 void StackGuard::RequestInterrupt(int flagbit) { 345 void StackGuard::PopPostponeInterruptsScope() {
347 ExecutionAccess access(isolate_); 346 ExecutionAccess access(isolate_);
348 thread_local_.interrupt_flags_ |= flagbit; 347 PostponeInterruptsScope* top = thread_local_.postpone_interrupts_;
348 thread_local_.interrupt_flags_ |= top->intercepted_flags_;
349 thread_local_.postpone_interrupts_ = top->prev_;
350 if (has_pending_interrupts(access)) set_interrupt_limits(access);
351 }
352
353
354 bool StackGuard::CheckInterrupt(InterruptFlag flag) {
355 ExecutionAccess access(isolate_);
356 return thread_local_.interrupt_flags_ & flag;
357 }
358
359
360 void StackGuard::RequestInterrupt(InterruptFlag flag) {
361 ExecutionAccess access(isolate_);
362 // Check the chain of PostponeInterruptsScopes for interception.
363 if (thread_local_.postpone_interrupts_ &&
364 thread_local_.postpone_interrupts_->Intercept(flag)) {
365 return;
366 }
367
368 // Not intercepted. Set as active interrupt flag.
369 thread_local_.interrupt_flags_ |= flag;
349 set_interrupt_limits(access); 370 set_interrupt_limits(access);
350 } 371 }
351 372
352 373
353 void StackGuard::ClearInterrupt(int flagbit) { 374 void StackGuard::ClearInterrupt(InterruptFlag flag) {
354 ExecutionAccess access(isolate_); 375 ExecutionAccess access(isolate_);
355 thread_local_.interrupt_flags_ &= ~flagbit; 376 // Clear the interrupt flag from the chain of PostponeInterruptsScopes.
356 if (!should_postpone_interrupts(access) && !has_pending_interrupts(access)) { 377 for (PostponeInterruptsScope* current = thread_local_.postpone_interrupts_;
357 reset_limits(access); 378 current != NULL;
379 current = current->prev_) {
380 current->intercepted_flags_ &= ~flag;
358 } 381 }
382
383 // Clear the interrupt flag from the active interrupt flags.
384 thread_local_.interrupt_flags_ &= ~flag;
385 if (!has_pending_interrupts(access)) reset_limits(access);
359 } 386 }
360 387
361 388
362 bool StackGuard::CheckAndClearInterrupt(InterruptFlag flag) { 389 bool StackGuard::CheckAndClearInterrupt(InterruptFlag flag) {
363 ExecutionAccess access(isolate_); 390 ExecutionAccess access(isolate_);
364 int flagbit = 1 << flag; 391 bool result = (thread_local_.interrupt_flags_ & flag);
365 bool result = (thread_local_.interrupt_flags_ & flagbit); 392 thread_local_.interrupt_flags_ &= ~flag;
366 thread_local_.interrupt_flags_ &= ~flagbit; 393 if (!has_pending_interrupts(access)) reset_limits(access);
367 if (!should_postpone_interrupts(access) && !has_pending_interrupts(access)) {
368 reset_limits(access);
369 }
370 return result; 394 return result;
371 } 395 }
372 396
373 397
374 char* StackGuard::ArchiveStackGuard(char* to) { 398 char* StackGuard::ArchiveStackGuard(char* to) {
375 ExecutionAccess access(isolate_); 399 ExecutionAccess access(isolate_);
376 MemCopy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal)); 400 MemCopy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal));
377 ThreadLocal blank; 401 ThreadLocal blank;
378 402
379 // Set the stack limits using the old thread_local_. 403 // Set the stack limits using the old thread_local_.
(...skipping 21 matching lines...) Expand all
401 isolate_->FindOrAllocatePerThreadDataForThisThread(); 425 isolate_->FindOrAllocatePerThreadDataForThisThread();
402 per_thread->set_stack_limit(thread_local_.real_climit_); 426 per_thread->set_stack_limit(thread_local_.real_climit_);
403 } 427 }
404 428
405 429
406 void StackGuard::ThreadLocal::Clear() { 430 void StackGuard::ThreadLocal::Clear() {
407 real_jslimit_ = kIllegalLimit; 431 real_jslimit_ = kIllegalLimit;
408 jslimit_ = kIllegalLimit; 432 jslimit_ = kIllegalLimit;
409 real_climit_ = kIllegalLimit; 433 real_climit_ = kIllegalLimit;
410 climit_ = kIllegalLimit; 434 climit_ = kIllegalLimit;
411 nesting_ = 0; 435 postpone_interrupts_ = NULL;
412 postpone_interrupts_nesting_ = 0;
413 interrupt_flags_ = 0; 436 interrupt_flags_ = 0;
414 } 437 }
415 438
416 439
417 bool StackGuard::ThreadLocal::Initialize(Isolate* isolate) { 440 bool StackGuard::ThreadLocal::Initialize(Isolate* isolate) {
418 bool should_set_stack_limits = false; 441 bool should_set_stack_limits = false;
419 if (real_climit_ == kIllegalLimit) { 442 if (real_climit_ == kIllegalLimit) {
420 // Takes the address of the limit variable in order to find out where 443 // Takes the address of the limit variable in order to find out where
421 // the top of stack is right now. 444 // the top of stack is right now.
422 const uintptr_t kLimitSize = FLAG_stack_size * KB; 445 const uintptr_t kLimitSize = FLAG_stack_size * KB;
423 uintptr_t limit = reinterpret_cast<uintptr_t>(&limit) - kLimitSize; 446 uintptr_t limit = reinterpret_cast<uintptr_t>(&limit) - kLimitSize;
424 ASSERT(reinterpret_cast<uintptr_t>(&limit) > kLimitSize); 447 ASSERT(reinterpret_cast<uintptr_t>(&limit) > kLimitSize);
425 real_jslimit_ = SimulatorStack::JsLimitFromCLimit(isolate, limit); 448 real_jslimit_ = SimulatorStack::JsLimitFromCLimit(isolate, limit);
426 jslimit_ = SimulatorStack::JsLimitFromCLimit(isolate, limit); 449 jslimit_ = SimulatorStack::JsLimitFromCLimit(isolate, limit);
427 real_climit_ = limit; 450 real_climit_ = limit;
428 climit_ = limit; 451 climit_ = limit;
429 should_set_stack_limits = true; 452 should_set_stack_limits = true;
430 } 453 }
431 nesting_ = 0; 454 postpone_interrupts_ = NULL;
432 postpone_interrupts_nesting_ = 0;
433 interrupt_flags_ = 0; 455 interrupt_flags_ = 0;
434 return should_set_stack_limits; 456 return should_set_stack_limits;
435 } 457 }
436 458
437 459
438 void StackGuard::ClearThread(const ExecutionAccess& lock) { 460 void StackGuard::ClearThread(const ExecutionAccess& lock) {
439 thread_local_.Clear(); 461 thread_local_.Clear();
440 isolate_->heap()->SetStackLimits(); 462 isolate_->heap()->SetStackLimits();
441 } 463 }
442 464
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
641 Handle<Object> result; 663 Handle<Object> result;
642 if (!maybe_result.ToHandle(&result) || !result->IsString()) { 664 if (!maybe_result.ToHandle(&result) || !result->IsString()) {
643 return isolate->factory()->empty_string(); 665 return isolate->factory()->empty_string();
644 } 666 }
645 667
646 return Handle<String>::cast(result); 668 return Handle<String>::cast(result);
647 } 669 }
648 670
649 671
650 Object* StackGuard::HandleInterrupts() { 672 Object* StackGuard::HandleInterrupts() {
651 {
652 ExecutionAccess access(isolate_);
653 if (should_postpone_interrupts(access)) {
654 return isolate_->heap()->undefined_value();
655 }
656 }
657
658 if (CheckAndClearInterrupt(GC_REQUEST)) { 673 if (CheckAndClearInterrupt(GC_REQUEST)) {
659 isolate_->heap()->CollectAllGarbage(Heap::kNoGCFlags, "GC interrupt"); 674 isolate_->heap()->CollectAllGarbage(Heap::kNoGCFlags, "GC interrupt");
660 } 675 }
661 676
662 if (CheckDebugBreak() || CheckDebugCommand()) { 677 if (CheckDebugBreak() || CheckDebugCommand()) {
663 isolate_->debug()->HandleDebugBreak(); 678 isolate_->debug()->HandleDebugBreak();
664 } 679 }
665 680
666 if (CheckAndClearInterrupt(TERMINATE_EXECUTION)) { 681 if (CheckAndClearInterrupt(TERMINATE_EXECUTION)) {
667 return isolate_->TerminateExecution(); 682 return isolate_->TerminateExecution();
(...skipping 14 matching lines...) Expand all
682 } 697 }
683 698
684 isolate_->counters()->stack_interrupts()->Increment(); 699 isolate_->counters()->stack_interrupts()->Increment();
685 isolate_->counters()->runtime_profiler_ticks()->Increment(); 700 isolate_->counters()->runtime_profiler_ticks()->Increment();
686 isolate_->runtime_profiler()->OptimizeNow(); 701 isolate_->runtime_profiler()->OptimizeNow();
687 702
688 return isolate_->heap()->undefined_value(); 703 return isolate_->heap()->undefined_value();
689 } 704 }
690 705
691 } } // namespace v8::internal 706 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/execution.h ('k') | src/isolate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698