| 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_ = NULL; |
| 627 interrupt_callback_data_ = NULL; |
| 584 } | 628 } |
| 585 | 629 |
| 586 | 630 |
| 587 bool StackGuard::ThreadLocal::Initialize(Isolate* isolate) { | 631 bool StackGuard::ThreadLocal::Initialize(Isolate* isolate) { |
| 588 bool should_set_stack_limits = false; | 632 bool should_set_stack_limits = false; |
| 589 if (real_climit_ == kIllegalLimit) { | 633 if (real_climit_ == kIllegalLimit) { |
| 590 // Takes the address of the limit variable in order to find out where | 634 // Takes the address of the limit variable in order to find out where |
| 591 // the top of stack is right now. | 635 // the top of stack is right now. |
| 592 const uintptr_t kLimitSize = FLAG_stack_size * KB; | 636 const uintptr_t kLimitSize = FLAG_stack_size * KB; |
| 593 uintptr_t limit = reinterpret_cast<uintptr_t>(&limit) - kLimitSize; | 637 uintptr_t limit = reinterpret_cast<uintptr_t>(&limit) - kLimitSize; |
| 594 ASSERT(reinterpret_cast<uintptr_t>(&limit) > kLimitSize); | 638 ASSERT(reinterpret_cast<uintptr_t>(&limit) > kLimitSize); |
| 595 real_jslimit_ = SimulatorStack::JsLimitFromCLimit(isolate, limit); | 639 real_jslimit_ = SimulatorStack::JsLimitFromCLimit(isolate, limit); |
| 596 jslimit_ = SimulatorStack::JsLimitFromCLimit(isolate, limit); | 640 jslimit_ = SimulatorStack::JsLimitFromCLimit(isolate, limit); |
| 597 real_climit_ = limit; | 641 real_climit_ = limit; |
| 598 climit_ = limit; | 642 climit_ = limit; |
| 599 should_set_stack_limits = true; | 643 should_set_stack_limits = true; |
| 600 } | 644 } |
| 601 nesting_ = 0; | 645 nesting_ = 0; |
| 602 postpone_interrupts_nesting_ = 0; | 646 postpone_interrupts_nesting_ = 0; |
| 603 interrupt_flags_ = 0; | 647 interrupt_flags_ = 0; |
| 648 interrupt_callback_ = NULL; |
| 649 interrupt_callback_data_ = NULL; |
| 604 return should_set_stack_limits; | 650 return should_set_stack_limits; |
| 605 } | 651 } |
| 606 | 652 |
| 607 | 653 |
| 608 void StackGuard::ClearThread(const ExecutionAccess& lock) { | 654 void StackGuard::ClearThread(const ExecutionAccess& lock) { |
| 609 thread_local_.Clear(); | 655 thread_local_.Clear(); |
| 610 isolate_->heap()->SetStackLimits(); | 656 isolate_->heap()->SetStackLimits(); |
| 611 } | 657 } |
| 612 | 658 |
| 613 | 659 |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 929 | 975 |
| 930 | 976 |
| 931 #endif | 977 #endif |
| 932 | 978 |
| 933 MaybeObject* Execution::HandleStackGuardInterrupt(Isolate* isolate) { | 979 MaybeObject* Execution::HandleStackGuardInterrupt(Isolate* isolate) { |
| 934 StackGuard* stack_guard = isolate->stack_guard(); | 980 StackGuard* stack_guard = isolate->stack_guard(); |
| 935 if (stack_guard->ShouldPostponeInterrupts()) { | 981 if (stack_guard->ShouldPostponeInterrupts()) { |
| 936 return isolate->heap()->undefined_value(); | 982 return isolate->heap()->undefined_value(); |
| 937 } | 983 } |
| 938 | 984 |
| 985 if (stack_guard->IsAPIInterrupt()) { |
| 986 stack_guard->InvokeInterruptCallback(); |
| 987 stack_guard->Continue(API_INTERRUPT); |
| 988 } |
| 989 |
| 939 if (stack_guard->IsGCRequest()) { | 990 if (stack_guard->IsGCRequest()) { |
| 940 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 991 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
| 941 "StackGuard GC request"); | 992 "StackGuard GC request"); |
| 942 stack_guard->Continue(GC_REQUEST); | 993 stack_guard->Continue(GC_REQUEST); |
| 943 } | 994 } |
| 944 | 995 |
| 945 isolate->counters()->stack_interrupts()->Increment(); | 996 isolate->counters()->stack_interrupts()->Increment(); |
| 946 isolate->counters()->runtime_profiler_ticks()->Increment(); | 997 isolate->counters()->runtime_profiler_ticks()->Increment(); |
| 947 #ifdef ENABLE_DEBUGGER_SUPPORT | 998 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 948 if (stack_guard->IsDebugBreak() || stack_guard->IsDebugCommand()) { | 999 if (stack_guard->IsDebugBreak() || stack_guard->IsDebugCommand()) { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 966 ASSERT(isolate->concurrent_recompilation_enabled()); | 1017 ASSERT(isolate->concurrent_recompilation_enabled()); |
| 967 stack_guard->Continue(INSTALL_CODE); | 1018 stack_guard->Continue(INSTALL_CODE); |
| 968 isolate->optimizing_compiler_thread()->InstallOptimizedFunctions(); | 1019 isolate->optimizing_compiler_thread()->InstallOptimizedFunctions(); |
| 969 } | 1020 } |
| 970 isolate->runtime_profiler()->OptimizeNow(); | 1021 isolate->runtime_profiler()->OptimizeNow(); |
| 971 return isolate->heap()->undefined_value(); | 1022 return isolate->heap()->undefined_value(); |
| 972 } | 1023 } |
| 973 | 1024 |
| 974 | 1025 |
| 975 } } // namespace v8::internal | 1026 } } // namespace v8::internal |
| OLD | NEW |