| OLD | NEW |
| 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 "execution.h" | 5 #include "execution.h" |
| 6 | 6 |
| 7 #include "bootstrapper.h" | 7 #include "bootstrapper.h" |
| 8 #include "codegen.h" | 8 #include "codegen.h" |
| 9 #include "deoptimizer.h" | 9 #include "deoptimizer.h" |
| 10 #include "isolate-inl.h" | 10 #include "isolate-inl.h" |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 96 | 96 |
| 97 #ifdef VERIFY_HEAP | 97 #ifdef VERIFY_HEAP |
| 98 value->Verify(); | 98 value->Verify(); |
| 99 #endif | 99 #endif |
| 100 | 100 |
| 101 // Update the pending exception flag and return the value. | 101 // Update the pending exception flag and return the value. |
| 102 bool has_exception = value->IsException(); | 102 bool has_exception = value->IsException(); |
| 103 ASSERT(has_exception == isolate->has_pending_exception()); | 103 ASSERT(has_exception == isolate->has_pending_exception()); |
| 104 if (has_exception) { | 104 if (has_exception) { |
| 105 isolate->ReportPendingMessages(); | 105 isolate->ReportPendingMessages(); |
| 106 #ifdef ENABLE_DEBUGGER_SUPPORT | |
| 107 // Reset stepping state when script exits with uncaught exception. | 106 // Reset stepping state when script exits with uncaught exception. |
| 108 if (isolate->debugger()->IsDebuggerActive()) { | 107 if (isolate->debugger()->IsDebuggerActive()) { |
| 109 isolate->debug()->ClearStepping(); | 108 isolate->debug()->ClearStepping(); |
| 110 } | 109 } |
| 111 #endif // ENABLE_DEBUGGER_SUPPORT | |
| 112 return MaybeHandle<Object>(); | 110 return MaybeHandle<Object>(); |
| 113 } else { | 111 } else { |
| 114 isolate->clear_pending_message(); | 112 isolate->clear_pending_message(); |
| 115 } | 113 } |
| 116 | 114 |
| 117 return Handle<Object>(value, isolate); | 115 return Handle<Object>(value, isolate); |
| 118 } | 116 } |
| 119 | 117 |
| 120 | 118 |
| 121 MaybeHandle<Object> Execution::Call(Isolate* isolate, | 119 MaybeHandle<Object> Execution::Call(Isolate* isolate, |
| (...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 471 } | 469 } |
| 472 | 470 |
| 473 | 471 |
| 474 void StackGuard::DeoptMarkedAllocationSites() { | 472 void StackGuard::DeoptMarkedAllocationSites() { |
| 475 ExecutionAccess access(isolate_); | 473 ExecutionAccess access(isolate_); |
| 476 thread_local_.interrupt_flags_ |= DEOPT_MARKED_ALLOCATION_SITES; | 474 thread_local_.interrupt_flags_ |= DEOPT_MARKED_ALLOCATION_SITES; |
| 477 set_interrupt_limits(access); | 475 set_interrupt_limits(access); |
| 478 } | 476 } |
| 479 | 477 |
| 480 | 478 |
| 481 #ifdef ENABLE_DEBUGGER_SUPPORT | |
| 482 bool StackGuard::IsDebugBreak() { | 479 bool StackGuard::IsDebugBreak() { |
| 483 ExecutionAccess access(isolate_); | 480 ExecutionAccess access(isolate_); |
| 484 return thread_local_.interrupt_flags_ & DEBUGBREAK; | 481 return thread_local_.interrupt_flags_ & DEBUGBREAK; |
| 485 } | 482 } |
| 486 | 483 |
| 487 | 484 |
| 488 void StackGuard::DebugBreak() { | 485 void StackGuard::DebugBreak() { |
| 489 ExecutionAccess access(isolate_); | 486 ExecutionAccess access(isolate_); |
| 490 thread_local_.interrupt_flags_ |= DEBUGBREAK; | 487 thread_local_.interrupt_flags_ |= DEBUGBREAK; |
| 491 set_interrupt_limits(access); | 488 set_interrupt_limits(access); |
| 492 } | 489 } |
| 493 | 490 |
| 494 | 491 |
| 495 bool StackGuard::IsDebugCommand() { | 492 bool StackGuard::IsDebugCommand() { |
| 496 ExecutionAccess access(isolate_); | 493 ExecutionAccess access(isolate_); |
| 497 return thread_local_.interrupt_flags_ & DEBUGCOMMAND; | 494 return thread_local_.interrupt_flags_ & DEBUGCOMMAND; |
| 498 } | 495 } |
| 499 | 496 |
| 500 | 497 |
| 501 void StackGuard::DebugCommand() { | 498 void StackGuard::DebugCommand() { |
| 502 ExecutionAccess access(isolate_); | 499 ExecutionAccess access(isolate_); |
| 503 thread_local_.interrupt_flags_ |= DEBUGCOMMAND; | 500 thread_local_.interrupt_flags_ |= DEBUGCOMMAND; |
| 504 set_interrupt_limits(access); | 501 set_interrupt_limits(access); |
| 505 } | 502 } |
| 506 #endif | 503 |
| 507 | 504 |
| 508 void StackGuard::Continue(InterruptFlag after_what) { | 505 void StackGuard::Continue(InterruptFlag after_what) { |
| 509 ExecutionAccess access(isolate_); | 506 ExecutionAccess access(isolate_); |
| 510 thread_local_.interrupt_flags_ &= ~static_cast<int>(after_what); | 507 thread_local_.interrupt_flags_ &= ~static_cast<int>(after_what); |
| 511 if (!should_postpone_interrupts(access) && !has_pending_interrupts(access)) { | 508 if (!should_postpone_interrupts(access) && !has_pending_interrupts(access)) { |
| 512 reset_limits(access); | 509 reset_limits(access); |
| 513 } | 510 } |
| 514 } | 511 } |
| 515 | 512 |
| 516 | 513 |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 834 } | 831 } |
| 835 | 832 |
| 836 return Handle<String>::cast(result); | 833 return Handle<String>::cast(result); |
| 837 } | 834 } |
| 838 | 835 |
| 839 | 836 |
| 840 static Object* RuntimePreempt(Isolate* isolate) { | 837 static Object* RuntimePreempt(Isolate* isolate) { |
| 841 // Clear the preempt request flag. | 838 // Clear the preempt request flag. |
| 842 isolate->stack_guard()->Continue(PREEMPT); | 839 isolate->stack_guard()->Continue(PREEMPT); |
| 843 | 840 |
| 844 #ifdef ENABLE_DEBUGGER_SUPPORT | |
| 845 if (isolate->debug()->InDebugger()) { | 841 if (isolate->debug()->InDebugger()) { |
| 846 // If currently in the debugger don't do any actual preemption but record | 842 // If currently in the debugger don't do any actual preemption but record |
| 847 // that preemption occoured while in the debugger. | 843 // that preemption occoured while in the debugger. |
| 848 isolate->debug()->PreemptionWhileInDebugger(); | 844 isolate->debug()->PreemptionWhileInDebugger(); |
| 849 } else { | 845 } else { |
| 850 // Perform preemption. | 846 // Perform preemption. |
| 851 v8::Unlocker unlocker(reinterpret_cast<v8::Isolate*>(isolate)); | 847 v8::Unlocker unlocker(reinterpret_cast<v8::Isolate*>(isolate)); |
| 852 Thread::YieldCPU(); | 848 Thread::YieldCPU(); |
| 853 } | 849 } |
| 854 #else | |
| 855 { // NOLINT | |
| 856 // Perform preemption. | |
| 857 v8::Unlocker unlocker(reinterpret_cast<v8::Isolate*>(isolate)); | |
| 858 Thread::YieldCPU(); | |
| 859 } | |
| 860 #endif | |
| 861 | 850 |
| 862 return isolate->heap()->undefined_value(); | 851 return isolate->heap()->undefined_value(); |
| 863 } | 852 } |
| 864 | 853 |
| 865 | 854 |
| 866 #ifdef ENABLE_DEBUGGER_SUPPORT | |
| 867 Object* Execution::DebugBreakHelper(Isolate* isolate) { | 855 Object* Execution::DebugBreakHelper(Isolate* isolate) { |
| 868 // Just continue if breaks are disabled. | 856 // Just continue if breaks are disabled. |
| 869 if (isolate->debug()->disable_break()) { | 857 if (isolate->debug()->disable_break()) { |
| 870 return isolate->heap()->undefined_value(); | 858 return isolate->heap()->undefined_value(); |
| 871 } | 859 } |
| 872 | 860 |
| 873 // Ignore debug break during bootstrapping. | 861 // Ignore debug break during bootstrapping. |
| 874 if (isolate->bootstrapper()->IsActive()) { | 862 if (isolate->bootstrapper()->IsActive()) { |
| 875 return isolate->heap()->undefined_value(); | 863 return isolate->heap()->undefined_value(); |
| 876 } | 864 } |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 932 EnterDebugger debugger(isolate); | 920 EnterDebugger debugger(isolate); |
| 933 if (debugger.FailedToEnter()) { | 921 if (debugger.FailedToEnter()) { |
| 934 return; | 922 return; |
| 935 } | 923 } |
| 936 | 924 |
| 937 // Notify the debug event listeners. Indicate auto continue if the break was | 925 // Notify the debug event listeners. Indicate auto continue if the break was |
| 938 // a debug command break. | 926 // a debug command break. |
| 939 isolate->debugger()->OnDebugBreak(isolate->factory()->undefined_value(), | 927 isolate->debugger()->OnDebugBreak(isolate->factory()->undefined_value(), |
| 940 debug_command_only); | 928 debug_command_only); |
| 941 } | 929 } |
| 942 #endif | 930 |
| 943 | 931 |
| 944 Object* Execution::HandleStackGuardInterrupt(Isolate* isolate) { | 932 Object* Execution::HandleStackGuardInterrupt(Isolate* isolate) { |
| 945 StackGuard* stack_guard = isolate->stack_guard(); | 933 StackGuard* stack_guard = isolate->stack_guard(); |
| 946 if (stack_guard->ShouldPostponeInterrupts()) { | 934 if (stack_guard->ShouldPostponeInterrupts()) { |
| 947 return isolate->heap()->undefined_value(); | 935 return isolate->heap()->undefined_value(); |
| 948 } | 936 } |
| 949 | 937 |
| 950 if (stack_guard->IsAPIInterrupt()) { | 938 if (stack_guard->IsAPIInterrupt()) { |
| 951 stack_guard->InvokeInterruptCallback(); | 939 stack_guard->InvokeInterruptCallback(); |
| 952 stack_guard->Continue(API_INTERRUPT); | 940 stack_guard->Continue(API_INTERRUPT); |
| 953 } | 941 } |
| 954 | 942 |
| 955 if (stack_guard->IsGCRequest()) { | 943 if (stack_guard->IsGCRequest()) { |
| 956 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 944 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
| 957 "StackGuard GC request"); | 945 "StackGuard GC request"); |
| 958 stack_guard->Continue(GC_REQUEST); | 946 stack_guard->Continue(GC_REQUEST); |
| 959 } | 947 } |
| 960 | 948 |
| 961 isolate->counters()->stack_interrupts()->Increment(); | 949 isolate->counters()->stack_interrupts()->Increment(); |
| 962 isolate->counters()->runtime_profiler_ticks()->Increment(); | 950 isolate->counters()->runtime_profiler_ticks()->Increment(); |
| 963 #ifdef ENABLE_DEBUGGER_SUPPORT | |
| 964 if (stack_guard->IsDebugBreak() || stack_guard->IsDebugCommand()) { | 951 if (stack_guard->IsDebugBreak() || stack_guard->IsDebugCommand()) { |
| 965 DebugBreakHelper(isolate); | 952 DebugBreakHelper(isolate); |
| 966 } | 953 } |
| 967 #endif | |
| 968 if (stack_guard->IsPreempted()) RuntimePreempt(isolate); | 954 if (stack_guard->IsPreempted()) RuntimePreempt(isolate); |
| 969 if (stack_guard->IsTerminateExecution()) { | 955 if (stack_guard->IsTerminateExecution()) { |
| 970 stack_guard->Continue(TERMINATE); | 956 stack_guard->Continue(TERMINATE); |
| 971 return isolate->TerminateExecution(); | 957 return isolate->TerminateExecution(); |
| 972 } | 958 } |
| 973 if (stack_guard->IsInterrupted()) { | 959 if (stack_guard->IsInterrupted()) { |
| 974 stack_guard->Continue(INTERRUPT); | 960 stack_guard->Continue(INTERRUPT); |
| 975 return isolate->StackOverflow(); | 961 return isolate->StackOverflow(); |
| 976 } | 962 } |
| 977 if (stack_guard->IsFullDeopt()) { | 963 if (stack_guard->IsFullDeopt()) { |
| 978 stack_guard->Continue(FULL_DEOPT); | 964 stack_guard->Continue(FULL_DEOPT); |
| 979 Deoptimizer::DeoptimizeAll(isolate); | 965 Deoptimizer::DeoptimizeAll(isolate); |
| 980 } | 966 } |
| 981 if (stack_guard->IsDeoptMarkedAllocationSites()) { | 967 if (stack_guard->IsDeoptMarkedAllocationSites()) { |
| 982 stack_guard->Continue(DEOPT_MARKED_ALLOCATION_SITES); | 968 stack_guard->Continue(DEOPT_MARKED_ALLOCATION_SITES); |
| 983 isolate->heap()->DeoptMarkedAllocationSites(); | 969 isolate->heap()->DeoptMarkedAllocationSites(); |
| 984 } | 970 } |
| 985 if (stack_guard->IsInstallCodeRequest()) { | 971 if (stack_guard->IsInstallCodeRequest()) { |
| 986 ASSERT(isolate->concurrent_recompilation_enabled()); | 972 ASSERT(isolate->concurrent_recompilation_enabled()); |
| 987 stack_guard->Continue(INSTALL_CODE); | 973 stack_guard->Continue(INSTALL_CODE); |
| 988 isolate->optimizing_compiler_thread()->InstallOptimizedFunctions(); | 974 isolate->optimizing_compiler_thread()->InstallOptimizedFunctions(); |
| 989 } | 975 } |
| 990 isolate->runtime_profiler()->OptimizeNow(); | 976 isolate->runtime_profiler()->OptimizeNow(); |
| 991 return isolate->heap()->undefined_value(); | 977 return isolate->heap()->undefined_value(); |
| 992 } | 978 } |
| 993 | 979 |
| 994 } } // namespace v8::internal | 980 } } // namespace v8::internal |
| OLD | NEW |