Chromium Code Reviews| 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 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 359 thread_local_.real_jslimit_ = jslimit; | 359 thread_local_.real_jslimit_ = jslimit; |
| 360 } | 360 } |
| 361 | 361 |
| 362 | 362 |
| 363 void StackGuard::DisableInterrupts() { | 363 void StackGuard::DisableInterrupts() { |
| 364 ExecutionAccess access(isolate_); | 364 ExecutionAccess access(isolate_); |
| 365 reset_limits(access); | 365 reset_limits(access); |
| 366 } | 366 } |
| 367 | 367 |
| 368 | 368 |
| 369 bool StackGuard::ShouldPostponeInterrupts() { | 369 bool StackGuard::CheckInterrupt(int flagbit) { |
| 370 ExecutionAccess access(isolate_); | 370 ExecutionAccess access(isolate_); |
| 371 return should_postpone_interrupts(access); | 371 return thread_local_.interrupt_flags_ & flagbit; |
| 372 } | 372 } |
| 373 | 373 |
| 374 | 374 |
| 375 bool StackGuard::IsInterrupted() { | 375 void StackGuard::RequestInterrupt(int flagbit) { |
| 376 ExecutionAccess access(isolate_); | 376 ExecutionAccess access(isolate_); |
| 377 return (thread_local_.interrupt_flags_ & INTERRUPT) != 0; | 377 thread_local_.interrupt_flags_ |= flagbit; |
| 378 } | |
| 379 | |
| 380 | |
| 381 void StackGuard::Interrupt() { | |
| 382 ExecutionAccess access(isolate_); | |
| 383 thread_local_.interrupt_flags_ |= INTERRUPT; | |
| 384 set_interrupt_limits(access); | 378 set_interrupt_limits(access); |
| 385 } | 379 } |
| 386 | 380 |
| 387 | 381 |
| 388 bool StackGuard::IsPreempted() { | 382 void StackGuard::ClearInterrupt(int flagbit) { |
| 389 ExecutionAccess access(isolate_); | 383 ExecutionAccess access(isolate_); |
| 390 return thread_local_.interrupt_flags_ & PREEMPT; | 384 thread_local_.interrupt_flags_ &= ~flagbit; |
| 391 } | |
| 392 | |
| 393 | |
| 394 void StackGuard::Preempt() { | |
| 395 ExecutionAccess access(isolate_); | |
| 396 thread_local_.interrupt_flags_ |= PREEMPT; | |
| 397 set_interrupt_limits(access); | |
| 398 } | |
| 399 | |
| 400 | |
| 401 bool StackGuard::IsTerminateExecution() { | |
| 402 ExecutionAccess access(isolate_); | |
| 403 return (thread_local_.interrupt_flags_ & TERMINATE) != 0; | |
| 404 } | |
| 405 | |
| 406 | |
| 407 void StackGuard::CancelTerminateExecution() { | |
| 408 ExecutionAccess access(isolate_); | |
| 409 Continue(TERMINATE); | |
| 410 isolate_->CancelTerminateExecution(); | |
| 411 } | |
| 412 | |
| 413 | |
| 414 void StackGuard::TerminateExecution() { | |
| 415 ExecutionAccess access(isolate_); | |
| 416 thread_local_.interrupt_flags_ |= TERMINATE; | |
| 417 set_interrupt_limits(access); | |
| 418 } | |
| 419 | |
| 420 | |
| 421 bool StackGuard::IsGCRequest() { | |
| 422 ExecutionAccess access(isolate_); | |
| 423 return (thread_local_.interrupt_flags_ & GC_REQUEST) != 0; | |
| 424 } | |
| 425 | |
| 426 | |
| 427 void StackGuard::RequestGC() { | |
| 428 ExecutionAccess access(isolate_); | |
| 429 thread_local_.interrupt_flags_ |= GC_REQUEST; | |
| 430 if (thread_local_.postpone_interrupts_nesting_ == 0) { | |
| 431 thread_local_.jslimit_ = thread_local_.climit_ = kInterruptLimit; | |
| 432 isolate_->heap()->SetStackLimits(); | |
| 433 } | |
| 434 } | |
| 435 | |
| 436 | |
| 437 bool StackGuard::IsInstallCodeRequest() { | |
| 438 ExecutionAccess access(isolate_); | |
| 439 return (thread_local_.interrupt_flags_ & INSTALL_CODE) != 0; | |
| 440 } | |
| 441 | |
| 442 | |
| 443 void StackGuard::RequestInstallCode() { | |
| 444 ExecutionAccess access(isolate_); | |
| 445 thread_local_.interrupt_flags_ |= INSTALL_CODE; | |
| 446 if (thread_local_.postpone_interrupts_nesting_ == 0) { | |
| 447 thread_local_.jslimit_ = thread_local_.climit_ = kInterruptLimit; | |
| 448 isolate_->heap()->SetStackLimits(); | |
| 449 } | |
| 450 } | |
| 451 | |
| 452 | |
| 453 bool StackGuard::IsFullDeopt() { | |
| 454 ExecutionAccess access(isolate_); | |
| 455 return (thread_local_.interrupt_flags_ & FULL_DEOPT) != 0; | |
| 456 } | |
| 457 | |
| 458 | |
| 459 void StackGuard::FullDeopt() { | |
| 460 ExecutionAccess access(isolate_); | |
| 461 thread_local_.interrupt_flags_ |= FULL_DEOPT; | |
| 462 set_interrupt_limits(access); | |
| 463 } | |
| 464 | |
| 465 | |
| 466 bool StackGuard::IsDeoptMarkedAllocationSites() { | |
| 467 ExecutionAccess access(isolate_); | |
| 468 return (thread_local_.interrupt_flags_ & DEOPT_MARKED_ALLOCATION_SITES) != 0; | |
| 469 } | |
| 470 | |
| 471 | |
| 472 void StackGuard::DeoptMarkedAllocationSites() { | |
| 473 ExecutionAccess access(isolate_); | |
| 474 thread_local_.interrupt_flags_ |= DEOPT_MARKED_ALLOCATION_SITES; | |
| 475 set_interrupt_limits(access); | |
| 476 } | |
| 477 | |
| 478 | |
| 479 bool StackGuard::IsDebugBreak() { | |
| 480 ExecutionAccess access(isolate_); | |
| 481 return thread_local_.interrupt_flags_ & DEBUGBREAK; | |
| 482 } | |
| 483 | |
| 484 | |
| 485 void StackGuard::DebugBreak() { | |
| 486 ExecutionAccess access(isolate_); | |
| 487 thread_local_.interrupt_flags_ |= DEBUGBREAK; | |
| 488 set_interrupt_limits(access); | |
| 489 } | |
| 490 | |
| 491 | |
| 492 bool StackGuard::IsDebugCommand() { | |
| 493 ExecutionAccess access(isolate_); | |
| 494 return thread_local_.interrupt_flags_ & DEBUGCOMMAND; | |
| 495 } | |
| 496 | |
| 497 | |
| 498 void StackGuard::DebugCommand() { | |
| 499 ExecutionAccess access(isolate_); | |
| 500 thread_local_.interrupt_flags_ |= DEBUGCOMMAND; | |
| 501 set_interrupt_limits(access); | |
| 502 } | |
| 503 | |
| 504 | |
| 505 void StackGuard::Continue(InterruptFlag after_what) { | |
| 506 ExecutionAccess access(isolate_); | |
| 507 thread_local_.interrupt_flags_ &= ~static_cast<int>(after_what); | |
| 508 if (!should_postpone_interrupts(access) && !has_pending_interrupts(access)) { | 385 if (!should_postpone_interrupts(access) && !has_pending_interrupts(access)) { |
| 509 reset_limits(access); | 386 reset_limits(access); |
| 510 } | 387 } |
| 511 } | 388 } |
| 512 | 389 |
| 513 | 390 |
| 514 void StackGuard::RequestInterrupt(InterruptCallback callback, void* data) { | 391 bool StackGuard::CheckAndClearInterrupt(InterruptFlag flag, |
| 515 ExecutionAccess access(isolate_); | 392 const ExecutionAccess& lock) { |
| 516 thread_local_.interrupt_flags_ |= API_INTERRUPT; | 393 int flagbit = 1 << flag; |
| 517 thread_local_.interrupt_callback_ = callback; | 394 bool result = (thread_local_.interrupt_flags_ & flagbit); |
| 518 thread_local_.interrupt_callback_data_ = data; | 395 thread_local_.interrupt_flags_ &= ~flagbit; |
| 519 set_interrupt_limits(access); | 396 if (!should_postpone_interrupts(lock) && !has_pending_interrupts(lock)) { |
| 397 reset_limits(lock); | |
| 398 } | |
| 399 return result; | |
| 520 } | 400 } |
| 521 | 401 |
| 522 | 402 |
| 523 void StackGuard::ClearInterrupt() { | |
| 524 thread_local_.interrupt_callback_ = 0; | |
| 525 thread_local_.interrupt_callback_data_ = 0; | |
| 526 Continue(API_INTERRUPT); | |
| 527 } | |
| 528 | |
| 529 | |
| 530 bool StackGuard::IsAPIInterrupt() { | |
| 531 ExecutionAccess access(isolate_); | |
| 532 return thread_local_.interrupt_flags_ & API_INTERRUPT; | |
| 533 } | |
| 534 | |
| 535 | |
| 536 void StackGuard::InvokeInterruptCallback() { | |
| 537 InterruptCallback callback = 0; | |
| 538 void* data = 0; | |
| 539 | |
| 540 { | |
| 541 ExecutionAccess access(isolate_); | |
| 542 callback = thread_local_.interrupt_callback_; | |
| 543 data = thread_local_.interrupt_callback_data_; | |
| 544 thread_local_.interrupt_callback_ = NULL; | |
| 545 thread_local_.interrupt_callback_data_ = NULL; | |
| 546 } | |
| 547 | |
| 548 if (callback != NULL) { | |
| 549 VMState<EXTERNAL> state(isolate_); | |
| 550 HandleScope handle_scope(isolate_); | |
| 551 callback(reinterpret_cast<v8::Isolate*>(isolate_), data); | |
| 552 } | |
| 553 } | |
| 554 | |
| 555 | |
| 556 char* StackGuard::ArchiveStackGuard(char* to) { | 403 char* StackGuard::ArchiveStackGuard(char* to) { |
| 557 ExecutionAccess access(isolate_); | 404 ExecutionAccess access(isolate_); |
| 558 OS::MemCopy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal)); | 405 OS::MemCopy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal)); |
| 559 ThreadLocal blank; | 406 ThreadLocal blank; |
| 560 | 407 |
| 561 // Set the stack limits using the old thread_local_. | 408 // Set the stack limits using the old thread_local_. |
| 562 // TODO(isolates): This was the old semantics of constructing a ThreadLocal | 409 // TODO(isolates): This was the old semantics of constructing a ThreadLocal |
| 563 // (as the ctor called SetStackLimits, which looked at the | 410 // (as the ctor called SetStackLimits, which looked at the |
| 564 // current thread_local_ from StackGuard)-- but is this | 411 // current thread_local_ from StackGuard)-- but is this |
| 565 // really what was intended? | 412 // really what was intended? |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 587 | 434 |
| 588 | 435 |
| 589 void StackGuard::ThreadLocal::Clear() { | 436 void StackGuard::ThreadLocal::Clear() { |
| 590 real_jslimit_ = kIllegalLimit; | 437 real_jslimit_ = kIllegalLimit; |
| 591 jslimit_ = kIllegalLimit; | 438 jslimit_ = kIllegalLimit; |
| 592 real_climit_ = kIllegalLimit; | 439 real_climit_ = kIllegalLimit; |
| 593 climit_ = kIllegalLimit; | 440 climit_ = kIllegalLimit; |
| 594 nesting_ = 0; | 441 nesting_ = 0; |
| 595 postpone_interrupts_nesting_ = 0; | 442 postpone_interrupts_nesting_ = 0; |
| 596 interrupt_flags_ = 0; | 443 interrupt_flags_ = 0; |
| 597 interrupt_callback_ = NULL; | |
| 598 interrupt_callback_data_ = NULL; | |
| 599 } | 444 } |
| 600 | 445 |
| 601 | 446 |
| 602 bool StackGuard::ThreadLocal::Initialize(Isolate* isolate) { | 447 bool StackGuard::ThreadLocal::Initialize(Isolate* isolate) { |
| 603 bool should_set_stack_limits = false; | 448 bool should_set_stack_limits = false; |
| 604 if (real_climit_ == kIllegalLimit) { | 449 if (real_climit_ == kIllegalLimit) { |
| 605 // Takes the address of the limit variable in order to find out where | 450 // Takes the address of the limit variable in order to find out where |
| 606 // the top of stack is right now. | 451 // the top of stack is right now. |
| 607 const uintptr_t kLimitSize = FLAG_stack_size * KB; | 452 const uintptr_t kLimitSize = FLAG_stack_size * KB; |
| 608 uintptr_t limit = reinterpret_cast<uintptr_t>(&limit) - kLimitSize; | 453 uintptr_t limit = reinterpret_cast<uintptr_t>(&limit) - kLimitSize; |
| 609 ASSERT(reinterpret_cast<uintptr_t>(&limit) > kLimitSize); | 454 ASSERT(reinterpret_cast<uintptr_t>(&limit) > kLimitSize); |
| 610 real_jslimit_ = SimulatorStack::JsLimitFromCLimit(isolate, limit); | 455 real_jslimit_ = SimulatorStack::JsLimitFromCLimit(isolate, limit); |
| 611 jslimit_ = SimulatorStack::JsLimitFromCLimit(isolate, limit); | 456 jslimit_ = SimulatorStack::JsLimitFromCLimit(isolate, limit); |
| 612 real_climit_ = limit; | 457 real_climit_ = limit; |
| 613 climit_ = limit; | 458 climit_ = limit; |
| 614 should_set_stack_limits = true; | 459 should_set_stack_limits = true; |
| 615 } | 460 } |
| 616 nesting_ = 0; | 461 nesting_ = 0; |
| 617 postpone_interrupts_nesting_ = 0; | 462 postpone_interrupts_nesting_ = 0; |
| 618 interrupt_flags_ = 0; | 463 interrupt_flags_ = 0; |
| 619 interrupt_callback_ = NULL; | |
| 620 interrupt_callback_data_ = NULL; | |
| 621 return should_set_stack_limits; | 464 return should_set_stack_limits; |
| 622 } | 465 } |
| 623 | 466 |
| 624 | 467 |
| 625 void StackGuard::ClearThread(const ExecutionAccess& lock) { | 468 void StackGuard::ClearThread(const ExecutionAccess& lock) { |
| 626 thread_local_.Clear(); | 469 thread_local_.Clear(); |
| 627 isolate_->heap()->SetStackLimits(); | 470 isolate_->heap()->SetStackLimits(); |
| 628 } | 471 } |
| 629 | 472 |
| 630 | 473 |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 827 args); | 670 args); |
| 828 Handle<Object> result; | 671 Handle<Object> result; |
| 829 if (!maybe_result.ToHandle(&result) || !result->IsString()) { | 672 if (!maybe_result.ToHandle(&result) || !result->IsString()) { |
| 830 return isolate->factory()->empty_string(); | 673 return isolate->factory()->empty_string(); |
| 831 } | 674 } |
| 832 | 675 |
| 833 return Handle<String>::cast(result); | 676 return Handle<String>::cast(result); |
| 834 } | 677 } |
| 835 | 678 |
| 836 | 679 |
| 837 static Object* RuntimePreempt(Isolate* isolate) { | 680 void Execution::DebugBreakHelper(Isolate* isolate) { |
| 838 // Clear the preempt request flag. | |
| 839 isolate->stack_guard()->Continue(PREEMPT); | |
| 840 | |
| 841 if (isolate->debug()->InDebugger()) { | |
| 842 // If currently in the debugger don't do any actual preemption but record | |
| 843 // that preemption occoured while in the debugger. | |
| 844 isolate->debug()->PreemptionWhileInDebugger(); | |
| 845 } else { | |
| 846 // Perform preemption. | |
| 847 v8::Unlocker unlocker(reinterpret_cast<v8::Isolate*>(isolate)); | |
| 848 Thread::YieldCPU(); | |
| 849 } | |
| 850 | |
| 851 return isolate->heap()->undefined_value(); | |
| 852 } | |
| 853 | |
| 854 | |
| 855 Object* Execution::DebugBreakHelper(Isolate* isolate) { | |
| 856 // Just continue if breaks are disabled. | 681 // Just continue if breaks are disabled. |
| 857 if (isolate->debug()->disable_break()) { | 682 if (isolate->debug()->disable_break()) return; |
| 858 return isolate->heap()->undefined_value(); | |
| 859 } | |
| 860 | 683 |
| 861 // Ignore debug break during bootstrapping. | 684 // Ignore debug break during bootstrapping. |
| 862 if (isolate->bootstrapper()->IsActive()) { | 685 if (isolate->bootstrapper()->IsActive()) return; |
| 863 return isolate->heap()->undefined_value(); | |
| 864 } | |
| 865 | 686 |
| 866 // Ignore debug break if debugger is not active. | 687 // Ignore debug break if debugger is not active. |
| 867 if (!isolate->debugger()->IsDebuggerActive()) { | 688 if (!isolate->debugger()->IsDebuggerActive()) return; |
| 868 return isolate->heap()->undefined_value(); | |
| 869 } | |
| 870 | 689 |
| 871 StackLimitCheck check(isolate); | 690 StackLimitCheck check(isolate); |
| 872 if (check.HasOverflowed()) { | 691 if (check.HasOverflowed()) return; |
| 873 return isolate->heap()->undefined_value(); | |
| 874 } | |
| 875 | 692 |
| 876 { | 693 { JavaScriptFrameIterator it(isolate); |
| 877 JavaScriptFrameIterator it(isolate); | |
| 878 ASSERT(!it.done()); | 694 ASSERT(!it.done()); |
| 879 Object* fun = it.frame()->function(); | 695 Object* fun = it.frame()->function(); |
| 880 if (fun && fun->IsJSFunction()) { | 696 if (fun && fun->IsJSFunction()) { |
| 881 // Don't stop in builtin functions. | 697 // Don't stop in builtin functions. |
| 882 if (JSFunction::cast(fun)->IsBuiltin()) { | 698 if (JSFunction::cast(fun)->IsBuiltin()) return; |
| 883 return isolate->heap()->undefined_value(); | |
| 884 } | |
| 885 GlobalObject* global = JSFunction::cast(fun)->context()->global_object(); | 699 GlobalObject* global = JSFunction::cast(fun)->context()->global_object(); |
| 886 // Don't stop in debugger functions. | 700 // Don't stop in debugger functions. |
| 887 if (isolate->debug()->IsDebugGlobal(global)) { | 701 if (isolate->debug()->IsDebugGlobal(global)) return; |
| 888 return isolate->heap()->undefined_value(); | |
| 889 } | |
| 890 } | 702 } |
| 891 } | 703 } |
| 892 | 704 |
| 893 // Collect the break state before clearing the flags. | 705 // Collect the break state before clearing the flags. |
| 894 bool debug_command_only = | 706 bool debug_command_only = isolate->stack_guard()->CheckDebugCommand() && |
| 895 isolate->stack_guard()->IsDebugCommand() && | 707 !isolate->stack_guard()->CheckDebugBreak(); |
| 896 !isolate->stack_guard()->IsDebugBreak(); | |
| 897 | 708 |
| 898 // Clear the debug break request flag. | 709 isolate->stack_guard()->ClearDebugBreak(); |
| 899 isolate->stack_guard()->Continue(DEBUGBREAK); | |
| 900 | 710 |
| 901 ProcessDebugMessages(isolate, debug_command_only); | 711 Execution::ProcessDebugMessages(isolate, debug_command_only); |
| 902 | |
| 903 // Return to continue execution. | |
| 904 return isolate->heap()->undefined_value(); | |
| 905 } | 712 } |
| 906 | 713 |
| 907 | 714 |
| 908 void Execution::ProcessDebugMessages(Isolate* isolate, | 715 void Execution::ProcessDebugMessages(Isolate* isolate, |
| 909 bool debug_command_only) { | 716 bool debug_command_only) { |
| 910 // Clear the debug command request flag. | 717 isolate->stack_guard()->ClearDebugCommand(); |
| 911 isolate->stack_guard()->Continue(DEBUGCOMMAND); | |
| 912 | 718 |
| 913 StackLimitCheck check(isolate); | 719 StackLimitCheck check(isolate); |
| 914 if (check.HasOverflowed()) { | 720 if (check.HasOverflowed()) return; |
| 915 return; | |
| 916 } | |
| 917 | 721 |
| 918 HandleScope scope(isolate); | 722 HandleScope scope(isolate); |
| 919 // Enter the debugger. Just continue if we fail to enter the debugger. | 723 // Enter the debugger. Just continue if we fail to enter the debugger. |
| 920 EnterDebugger debugger(isolate); | 724 EnterDebugger debugger(isolate); |
| 921 if (debugger.FailedToEnter()) { | 725 if (debugger.FailedToEnter()) return; |
| 922 return; | |
| 923 } | |
| 924 | 726 |
| 925 // Notify the debug event listeners. Indicate auto continue if the break was | 727 // Notify the debug event listeners. Indicate auto continue if the break was |
| 926 // a debug command break. | 728 // a debug command break. |
| 927 isolate->debugger()->OnDebugBreak(isolate->factory()->undefined_value(), | 729 isolate->debugger()->OnDebugBreak(isolate->factory()->undefined_value(), |
| 928 debug_command_only); | 730 debug_command_only); |
| 929 } | 731 } |
| 930 | 732 |
| 931 | 733 |
| 932 Object* Execution::HandleStackGuardInterrupt(Isolate* isolate) { | 734 Object* StackGuard::HandleInterrupts() { |
| 933 StackGuard* stack_guard = isolate->stack_guard(); | 735 ExecutionAccess access(isolate_); |
|
yurys
2014/05/29 08:42:07
Scope of this lock seems too coarse. Do we really
| |
| 934 if (stack_guard->ShouldPostponeInterrupts()) { | 736 if (should_postpone_interrupts(access)) { |
| 935 return isolate->heap()->undefined_value(); | 737 return isolate_->heap()->undefined_value(); |
| 936 } | 738 } |
| 937 | 739 |
| 938 if (stack_guard->IsAPIInterrupt()) { | 740 if (CheckAndClearInterrupt(API_INTERRUPT, access)) { |
| 939 stack_guard->InvokeInterruptCallback(); | 741 isolate_->InvokeApiInterruptCallback(); |
| 940 stack_guard->Continue(API_INTERRUPT); | |
| 941 } | 742 } |
| 942 | 743 |
| 943 if (stack_guard->IsGCRequest()) { | 744 if (CheckAndClearInterrupt(GC_REQUEST, access)) { |
| 944 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 745 isolate_->heap()->CollectAllGarbage(Heap::kNoGCFlags, "GC interrupt"); |
| 945 "StackGuard GC request"); | |
| 946 stack_guard->Continue(GC_REQUEST); | |
| 947 } | 746 } |
| 948 | 747 |
| 949 isolate->counters()->stack_interrupts()->Increment(); | 748 if (CheckDebugBreak() || CheckDebugCommand()) { |
| 950 isolate->counters()->runtime_profiler_ticks()->Increment(); | 749 Execution::DebugBreakHelper(isolate_); |
| 951 if (stack_guard->IsDebugBreak() || stack_guard->IsDebugCommand()) { | |
| 952 DebugBreakHelper(isolate); | |
| 953 } | 750 } |
| 954 if (stack_guard->IsPreempted()) RuntimePreempt(isolate); | 751 |
| 955 if (stack_guard->IsTerminateExecution()) { | 752 if (CheckAndClearInterrupt(TERMINATE_EXECUTION, access)) { |
| 956 stack_guard->Continue(TERMINATE); | 753 return isolate_->TerminateExecution(); |
| 957 return isolate->TerminateExecution(); | |
| 958 } | 754 } |
| 959 if (stack_guard->IsInterrupted()) { | 755 |
| 960 stack_guard->Continue(INTERRUPT); | 756 if (CheckAndClearInterrupt(FULL_DEOPT, access)) { |
| 961 return isolate->StackOverflow(); | 757 Deoptimizer::DeoptimizeAll(isolate_); |
| 962 } | 758 } |
| 963 if (stack_guard->IsFullDeopt()) { | 759 |
| 964 stack_guard->Continue(FULL_DEOPT); | 760 if (CheckAndClearInterrupt(DEOPT_MARKED_ALLOCATION_SITES, access)) { |
| 965 Deoptimizer::DeoptimizeAll(isolate); | 761 isolate_->heap()->DeoptMarkedAllocationSites(); |
| 966 } | 762 } |
| 967 if (stack_guard->IsDeoptMarkedAllocationSites()) { | 763 |
| 968 stack_guard->Continue(DEOPT_MARKED_ALLOCATION_SITES); | 764 if (CheckAndClearInterrupt(INSTALL_CODE, access)) { |
| 969 isolate->heap()->DeoptMarkedAllocationSites(); | 765 ASSERT(isolate_->concurrent_recompilation_enabled()); |
| 766 isolate_->optimizing_compiler_thread()->InstallOptimizedFunctions(); | |
| 970 } | 767 } |
| 971 if (stack_guard->IsInstallCodeRequest()) { | 768 |
| 972 ASSERT(isolate->concurrent_recompilation_enabled()); | 769 isolate_->counters()->stack_interrupts()->Increment(); |
| 973 stack_guard->Continue(INSTALL_CODE); | 770 isolate_->counters()->runtime_profiler_ticks()->Increment(); |
| 974 isolate->optimizing_compiler_thread()->InstallOptimizedFunctions(); | 771 isolate_->runtime_profiler()->OptimizeNow(); |
| 975 } | 772 return isolate_->heap()->undefined_value(); |
| 976 isolate->runtime_profiler()->OptimizeNow(); | |
| 977 return isolate->heap()->undefined_value(); | |
| 978 } | 773 } |
| 979 | 774 |
| 980 } } // namespace v8::internal | 775 } } // namespace v8::internal |
| OLD | NEW |