OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 522 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
533 | 533 |
534 void StackGuard::Continue(InterruptFlag after_what) { | 534 void StackGuard::Continue(InterruptFlag after_what) { |
535 ExecutionAccess access(isolate_); | 535 ExecutionAccess access(isolate_); |
536 thread_local_.interrupt_flags_ &= ~static_cast<int>(after_what); | 536 thread_local_.interrupt_flags_ &= ~static_cast<int>(after_what); |
537 if (!should_postpone_interrupts(access) && !has_pending_interrupts(access)) { | 537 if (!should_postpone_interrupts(access) && !has_pending_interrupts(access)) { |
538 reset_limits(access); | 538 reset_limits(access); |
539 } | 539 } |
540 } | 540 } |
541 | 541 |
542 | 542 |
543 void StackGuard::RequestInterrupt(InterruptCallback callback, void* data) { | |
544 ExecutionAccess access(isolate_); | |
545 thread_local_.interrupt_flags_ |= API_INTERRUPT; | |
546 thread_local_.interrupt_callback_ = callback; | |
547 thread_local_.interrupt_callback_data_ = data; | |
548 set_interrupt_limits(access); | |
549 } | |
550 | |
551 | |
552 void StackGuard::ClearInterrupt() { | |
553 thread_local_.interrupt_callback_ = 0; | |
554 thread_local_.interrupt_callback_data_ = 0; | |
555 Continue(API_INTERRUPT); | |
556 } | |
557 | |
558 | |
559 bool StackGuard::IsAPIInterrupt() { | |
560 ExecutionAccess access(isolate_); | |
561 return thread_local_.interrupt_flags_ & API_INTERRUPT; | |
562 } | |
563 | |
564 | |
565 void StackGuard::InvokeInterruptCallback() { | |
566 InterruptCallback callback = 0; | |
567 void* data = 0; | |
568 | |
569 { | |
570 ExecutionAccess access(isolate_); | |
571 callback = thread_local_.interrupt_callback_; | |
572 data = thread_local_.interrupt_callback_data_; | |
573 thread_local_.interrupt_callback_ = NULL; | |
574 thread_local_.interrupt_callback_data_ = NULL; | |
575 } | |
576 | |
577 if (callback != NULL) { | |
578 VMState<EXTERNAL> state(isolate_); | |
579 HandleScope handle_scope(isolate_); | |
580 callback(reinterpret_cast<v8::Isolate*>(isolate_), data); | |
581 } | |
582 } | |
583 | |
584 | |
585 char* StackGuard::ArchiveStackGuard(char* to) { | 543 char* StackGuard::ArchiveStackGuard(char* to) { |
586 ExecutionAccess access(isolate_); | 544 ExecutionAccess access(isolate_); |
587 OS::MemCopy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal)); | 545 OS::MemCopy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal)); |
588 ThreadLocal blank; | 546 ThreadLocal blank; |
589 | 547 |
590 // Set the stack limits using the old thread_local_. | 548 // Set the stack limits using the old thread_local_. |
591 // TODO(isolates): This was the old semantics of constructing a ThreadLocal | 549 // TODO(isolates): This was the old semantics of constructing a ThreadLocal |
592 // (as the ctor called SetStackLimits, which looked at the | 550 // (as the ctor called SetStackLimits, which looked at the |
593 // current thread_local_ from StackGuard)-- but is this | 551 // current thread_local_ from StackGuard)-- but is this |
594 // really what was intended? | 552 // really what was intended? |
(...skipping 21 matching lines...) Expand all Loading... |
616 | 574 |
617 | 575 |
618 void StackGuard::ThreadLocal::Clear() { | 576 void StackGuard::ThreadLocal::Clear() { |
619 real_jslimit_ = kIllegalLimit; | 577 real_jslimit_ = kIllegalLimit; |
620 jslimit_ = kIllegalLimit; | 578 jslimit_ = kIllegalLimit; |
621 real_climit_ = kIllegalLimit; | 579 real_climit_ = kIllegalLimit; |
622 climit_ = kIllegalLimit; | 580 climit_ = kIllegalLimit; |
623 nesting_ = 0; | 581 nesting_ = 0; |
624 postpone_interrupts_nesting_ = 0; | 582 postpone_interrupts_nesting_ = 0; |
625 interrupt_flags_ = 0; | 583 interrupt_flags_ = 0; |
626 interrupt_callback_ = 0; | |
627 } | 584 } |
628 | 585 |
629 | 586 |
630 bool StackGuard::ThreadLocal::Initialize(Isolate* isolate) { | 587 bool StackGuard::ThreadLocal::Initialize(Isolate* isolate) { |
631 bool should_set_stack_limits = false; | 588 bool should_set_stack_limits = false; |
632 if (real_climit_ == kIllegalLimit) { | 589 if (real_climit_ == kIllegalLimit) { |
633 // Takes the address of the limit variable in order to find out where | 590 // Takes the address of the limit variable in order to find out where |
634 // the top of stack is right now. | 591 // the top of stack is right now. |
635 const uintptr_t kLimitSize = FLAG_stack_size * KB; | 592 const uintptr_t kLimitSize = FLAG_stack_size * KB; |
636 uintptr_t limit = reinterpret_cast<uintptr_t>(&limit) - kLimitSize; | 593 uintptr_t limit = reinterpret_cast<uintptr_t>(&limit) - kLimitSize; |
637 ASSERT(reinterpret_cast<uintptr_t>(&limit) > kLimitSize); | 594 ASSERT(reinterpret_cast<uintptr_t>(&limit) > kLimitSize); |
638 real_jslimit_ = SimulatorStack::JsLimitFromCLimit(isolate, limit); | 595 real_jslimit_ = SimulatorStack::JsLimitFromCLimit(isolate, limit); |
639 jslimit_ = SimulatorStack::JsLimitFromCLimit(isolate, limit); | 596 jslimit_ = SimulatorStack::JsLimitFromCLimit(isolate, limit); |
640 real_climit_ = limit; | 597 real_climit_ = limit; |
641 climit_ = limit; | 598 climit_ = limit; |
642 should_set_stack_limits = true; | 599 should_set_stack_limits = true; |
643 } | 600 } |
644 nesting_ = 0; | 601 nesting_ = 0; |
645 postpone_interrupts_nesting_ = 0; | 602 postpone_interrupts_nesting_ = 0; |
646 interrupt_flags_ = 0; | 603 interrupt_flags_ = 0; |
647 interrupt_callback_ = 0; | |
648 return should_set_stack_limits; | 604 return should_set_stack_limits; |
649 } | 605 } |
650 | 606 |
651 | 607 |
652 void StackGuard::ClearThread(const ExecutionAccess& lock) { | 608 void StackGuard::ClearThread(const ExecutionAccess& lock) { |
653 thread_local_.Clear(); | 609 thread_local_.Clear(); |
654 isolate_->heap()->SetStackLimits(); | 610 isolate_->heap()->SetStackLimits(); |
655 } | 611 } |
656 | 612 |
657 | 613 |
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
973 | 929 |
974 | 930 |
975 #endif | 931 #endif |
976 | 932 |
977 MaybeObject* Execution::HandleStackGuardInterrupt(Isolate* isolate) { | 933 MaybeObject* Execution::HandleStackGuardInterrupt(Isolate* isolate) { |
978 StackGuard* stack_guard = isolate->stack_guard(); | 934 StackGuard* stack_guard = isolate->stack_guard(); |
979 if (stack_guard->ShouldPostponeInterrupts()) { | 935 if (stack_guard->ShouldPostponeInterrupts()) { |
980 return isolate->heap()->undefined_value(); | 936 return isolate->heap()->undefined_value(); |
981 } | 937 } |
982 | 938 |
983 if (stack_guard->IsAPIInterrupt()) { | |
984 stack_guard->InvokeInterruptCallback(); | |
985 stack_guard->Continue(API_INTERRUPT); | |
986 } | |
987 | |
988 if (stack_guard->IsGCRequest()) { | 939 if (stack_guard->IsGCRequest()) { |
989 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 940 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
990 "StackGuard GC request"); | 941 "StackGuard GC request"); |
991 stack_guard->Continue(GC_REQUEST); | 942 stack_guard->Continue(GC_REQUEST); |
992 } | 943 } |
993 | 944 |
994 isolate->counters()->stack_interrupts()->Increment(); | 945 isolate->counters()->stack_interrupts()->Increment(); |
995 isolate->counters()->runtime_profiler_ticks()->Increment(); | 946 isolate->counters()->runtime_profiler_ticks()->Increment(); |
996 #ifdef ENABLE_DEBUGGER_SUPPORT | 947 #ifdef ENABLE_DEBUGGER_SUPPORT |
997 if (stack_guard->IsDebugBreak() || stack_guard->IsDebugCommand()) { | 948 if (stack_guard->IsDebugBreak() || stack_guard->IsDebugCommand()) { |
(...skipping 17 matching lines...) Expand all Loading... |
1015 ASSERT(isolate->concurrent_recompilation_enabled()); | 966 ASSERT(isolate->concurrent_recompilation_enabled()); |
1016 stack_guard->Continue(INSTALL_CODE); | 967 stack_guard->Continue(INSTALL_CODE); |
1017 isolate->optimizing_compiler_thread()->InstallOptimizedFunctions(); | 968 isolate->optimizing_compiler_thread()->InstallOptimizedFunctions(); |
1018 } | 969 } |
1019 isolate->runtime_profiler()->OptimizeNow(); | 970 isolate->runtime_profiler()->OptimizeNow(); |
1020 return isolate->heap()->undefined_value(); | 971 return isolate->heap()->undefined_value(); |
1021 } | 972 } |
1022 | 973 |
1023 | 974 |
1024 } } // namespace v8::internal | 975 } } // namespace v8::internal |
OLD | NEW |