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 |