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