| 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 |