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 |