OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/api.h" | 7 #include "src/api.h" |
8 #include "src/arguments.h" | 8 #include "src/arguments.h" |
9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 574 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
585 return storage + ArchiveSpacePerThread(); | 585 return storage + ArchiveSpacePerThread(); |
586 } | 586 } |
587 | 587 |
588 | 588 |
589 int Debug::ArchiveSpacePerThread() { | 589 int Debug::ArchiveSpacePerThread() { |
590 return sizeof(ThreadLocal); | 590 return sizeof(ThreadLocal); |
591 } | 591 } |
592 | 592 |
593 | 593 |
594 ScriptCache::ScriptCache(Isolate* isolate) : HashMap(HashMap::PointersMatch), | 594 ScriptCache::ScriptCache(Isolate* isolate) : HashMap(HashMap::PointersMatch), |
595 isolate_(isolate), | 595 isolate_(isolate) { |
596 collected_scripts_(10) { | |
597 Heap* heap = isolate_->heap(); | 596 Heap* heap = isolate_->heap(); |
598 HandleScope scope(isolate_); | 597 HandleScope scope(isolate_); |
599 | 598 |
600 // Perform two GCs to get rid of all unreferenced scripts. The first GC gets | 599 // Perform two GCs to get rid of all unreferenced scripts. The first GC gets |
601 // rid of all the cached script wrappers and the second gets rid of the | 600 // rid of all the cached script wrappers and the second gets rid of the |
602 // scripts which are no longer referenced. | 601 // scripts which are no longer referenced. |
603 heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "ScriptCache"); | 602 heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "ScriptCache"); |
604 heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "ScriptCache"); | 603 heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "ScriptCache"); |
605 | 604 |
606 // Scan heap for Script objects. | 605 // Scan heap for Script objects. |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
644 ASSERT(entry->value != NULL); | 643 ASSERT(entry->value != NULL); |
645 if (entry->value != NULL) { | 644 if (entry->value != NULL) { |
646 instances->set(count, *reinterpret_cast<Script**>(entry->value)); | 645 instances->set(count, *reinterpret_cast<Script**>(entry->value)); |
647 count++; | 646 count++; |
648 } | 647 } |
649 } | 648 } |
650 return instances; | 649 return instances; |
651 } | 650 } |
652 | 651 |
653 | 652 |
654 void ScriptCache::ProcessCollectedScripts() { | |
655 Debug* debug = isolate_->debug(); | |
656 for (int i = 0; i < collected_scripts_.length(); i++) { | |
657 debug->OnScriptCollected(collected_scripts_[i]); | |
658 } | |
659 collected_scripts_.Clear(); | |
660 } | |
661 | |
662 | |
663 void ScriptCache::Clear() { | 653 void ScriptCache::Clear() { |
664 // Iterate the script cache to get rid of all the weak handles. | 654 // Iterate the script cache to get rid of all the weak handles. |
665 for (HashMap::Entry* entry = Start(); entry != NULL; entry = Next(entry)) { | 655 for (HashMap::Entry* entry = Start(); entry != NULL; entry = Next(entry)) { |
666 ASSERT(entry != NULL); | 656 ASSERT(entry != NULL); |
667 Object** location = reinterpret_cast<Object**>(entry->value); | 657 Object** location = reinterpret_cast<Object**>(entry->value); |
668 ASSERT((*location)->IsScript()); | 658 ASSERT((*location)->IsScript()); |
669 GlobalHandles::ClearWeakness(location); | 659 GlobalHandles::ClearWeakness(location); |
670 GlobalHandles::Destroy(location); | 660 GlobalHandles::Destroy(location); |
671 } | 661 } |
672 // Clear the content of the hash map. | 662 // Clear the content of the hash map. |
673 HashMap::Clear(); | 663 HashMap::Clear(); |
674 } | 664 } |
675 | 665 |
676 | 666 |
677 void ScriptCache::HandleWeakScript( | 667 void ScriptCache::HandleWeakScript( |
678 const v8::WeakCallbackData<v8::Value, void>& data) { | 668 const v8::WeakCallbackData<v8::Value, void>& data) { |
679 // Retrieve the script identifier. | 669 // Retrieve the script identifier. |
680 Handle<Object> object = Utils::OpenHandle(*data.GetValue()); | 670 Handle<Object> object = Utils::OpenHandle(*data.GetValue()); |
681 int id = Handle<Script>::cast(object)->id()->value(); | 671 int id = Handle<Script>::cast(object)->id()->value(); |
682 void* key = reinterpret_cast<void*>(id); | 672 void* key = reinterpret_cast<void*>(id); |
683 uint32_t hash = Hash(id); | 673 uint32_t hash = Hash(id); |
684 | 674 |
685 // Remove the corresponding entry from the cache. | 675 // Remove the corresponding entry from the cache. |
686 ScriptCache* script_cache = | 676 ScriptCache* script_cache = |
687 reinterpret_cast<ScriptCache*>(data.GetParameter()); | 677 reinterpret_cast<ScriptCache*>(data.GetParameter()); |
688 HashMap::Entry* entry = script_cache->Lookup(key, hash, false); | 678 HashMap::Entry* entry = script_cache->Lookup(key, hash, false); |
689 Object** location = reinterpret_cast<Object**>(entry->value); | 679 Object** location = reinterpret_cast<Object**>(entry->value); |
690 script_cache->Remove(key, hash); | 680 script_cache->Remove(key, hash); |
691 script_cache->collected_scripts_.Add(id); | |
692 | 681 |
693 // Clear the weak handle. | 682 // Clear the weak handle. |
694 GlobalHandles::Destroy(location); | 683 GlobalHandles::Destroy(location); |
695 } | 684 } |
696 | 685 |
697 | 686 |
698 void Debug::HandleWeakDebugInfo( | 687 void Debug::HandleWeakDebugInfo( |
699 const v8::WeakCallbackData<v8::Value, void>& data) { | 688 const v8::WeakCallbackData<v8::Value, void>& data) { |
700 Debug* debug = reinterpret_cast<Isolate*>(data.GetIsolate())->debug(); | 689 Debug* debug = reinterpret_cast<Isolate*>(data.GetIsolate())->debug(); |
701 DebugInfoListNode* node = | 690 DebugInfoListNode* node = |
(...skipping 1791 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2493 if (!it.done()) { | 2482 if (!it.done()) { |
2494 script->set_eval_from_shared(it.frame()->function()->shared()); | 2483 script->set_eval_from_shared(it.frame()->function()->shared()); |
2495 Code* code = it.frame()->LookupCode(); | 2484 Code* code = it.frame()->LookupCode(); |
2496 int offset = static_cast<int>( | 2485 int offset = static_cast<int>( |
2497 it.frame()->pc() - code->instruction_start()); | 2486 it.frame()->pc() - code->instruction_start()); |
2498 script->set_eval_from_instructions_offset(Smi::FromInt(offset)); | 2487 script->set_eval_from_instructions_offset(Smi::FromInt(offset)); |
2499 } | 2488 } |
2500 } | 2489 } |
2501 | 2490 |
2502 | 2491 |
2503 void Debug::AfterGarbageCollection() { | |
2504 // Generate events for collected scripts. | |
2505 if (script_cache_ != NULL) { | |
2506 script_cache_->ProcessCollectedScripts(); | |
2507 } | |
2508 } | |
2509 | |
2510 | |
2511 MaybeHandle<Object> Debug::MakeJSObject(const char* constructor_name, | 2492 MaybeHandle<Object> Debug::MakeJSObject(const char* constructor_name, |
2512 int argc, | 2493 int argc, |
2513 Handle<Object> argv[]) { | 2494 Handle<Object> argv[]) { |
2514 AssertDebugContext(); | 2495 AssertDebugContext(); |
2515 // Create the execution state object. | 2496 // Create the execution state object. |
2516 Handle<Object> constructor = Object::GetProperty( | 2497 Handle<Object> constructor = Object::GetProperty( |
2517 isolate_, isolate_->global_object(), constructor_name).ToHandleChecked(); | 2498 isolate_, isolate_->global_object(), constructor_name).ToHandleChecked(); |
2518 ASSERT(constructor->IsJSFunction()); | 2499 ASSERT(constructor->IsJSFunction()); |
2519 if (!constructor->IsJSFunction()) return MaybeHandle<Object>(); | 2500 if (!constructor->IsJSFunction()) return MaybeHandle<Object>(); |
2520 // We do not handle interrupts here. In particular, termination interrupts. | 2501 // We do not handle interrupts here. In particular, termination interrupts. |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2556 MaybeHandle<Object> Debug::MakeCompileEvent(Handle<Script> script, | 2537 MaybeHandle<Object> Debug::MakeCompileEvent(Handle<Script> script, |
2557 v8::DebugEvent type) { | 2538 v8::DebugEvent type) { |
2558 // Create the compile event object. | 2539 // Create the compile event object. |
2559 Handle<Object> script_wrapper = Script::GetWrapper(script); | 2540 Handle<Object> script_wrapper = Script::GetWrapper(script); |
2560 Handle<Object> argv[] = { script_wrapper, | 2541 Handle<Object> argv[] = { script_wrapper, |
2561 isolate_->factory()->NewNumberFromInt(type) }; | 2542 isolate_->factory()->NewNumberFromInt(type) }; |
2562 return MakeJSObject("MakeCompileEvent", ARRAY_SIZE(argv), argv); | 2543 return MakeJSObject("MakeCompileEvent", ARRAY_SIZE(argv), argv); |
2563 } | 2544 } |
2564 | 2545 |
2565 | 2546 |
2566 MaybeHandle<Object> Debug::MakeScriptCollectedEvent(int id) { | |
2567 // Create the script collected event object. | |
2568 Handle<Object> id_object = Handle<Smi>(Smi::FromInt(id), isolate_); | |
2569 Handle<Object> argv[] = { id_object }; | |
2570 return MakeJSObject("MakeScriptCollectedEvent", ARRAY_SIZE(argv), argv); | |
2571 } | |
2572 | |
2573 | |
2574 void Debug::OnException(Handle<Object> exception, bool uncaught) { | 2547 void Debug::OnException(Handle<Object> exception, bool uncaught) { |
2575 if (in_debug_scope() || ignore_events()) return; | 2548 if (in_debug_scope() || ignore_events()) return; |
2576 | 2549 |
2577 HandleScope scope(isolate_); | 2550 HandleScope scope(isolate_); |
2578 Handle<Object> promise = GetPromiseForUncaughtException(); | 2551 Handle<Object> promise = GetPromiseForUncaughtException(); |
2579 uncaught |= !promise->IsUndefined(); | 2552 uncaught |= !promise->IsUndefined(); |
2580 | 2553 |
2581 // Bail out if exception breaks are not active | 2554 // Bail out if exception breaks are not active |
2582 if (uncaught) { | 2555 if (uncaught) { |
2583 // Uncaught exceptions are reported by either flags. | 2556 // Uncaught exceptions are reported by either flags. |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2709 // Create the compile state object. | 2682 // Create the compile state object. |
2710 Handle<Object> event_data; | 2683 Handle<Object> event_data; |
2711 // Bail out and don't call debugger if exception. | 2684 // Bail out and don't call debugger if exception. |
2712 if (!MakeCompileEvent(script, v8::AfterCompile).ToHandle(&event_data)) return; | 2685 if (!MakeCompileEvent(script, v8::AfterCompile).ToHandle(&event_data)) return; |
2713 | 2686 |
2714 // Process debug event. | 2687 // Process debug event. |
2715 ProcessDebugEvent(v8::AfterCompile, Handle<JSObject>::cast(event_data), true); | 2688 ProcessDebugEvent(v8::AfterCompile, Handle<JSObject>::cast(event_data), true); |
2716 } | 2689 } |
2717 | 2690 |
2718 | 2691 |
2719 void Debug::OnScriptCollected(int id) { | |
2720 if (in_debug_scope() || ignore_events()) return; | |
2721 | |
2722 HandleScope scope(isolate_); | |
2723 DebugScope debug_scope(this); | |
2724 if (debug_scope.failed()) return; | |
2725 | |
2726 // Create the script collected state object. | |
2727 Handle<Object> event_data; | |
2728 // Bail out and don't call debugger if exception. | |
2729 if (!MakeScriptCollectedEvent(id).ToHandle(&event_data)) return; | |
2730 | |
2731 // Process debug event. | |
2732 ProcessDebugEvent(v8::ScriptCollected, | |
2733 Handle<JSObject>::cast(event_data), | |
2734 true); | |
2735 } | |
2736 | |
2737 | |
2738 void Debug::ProcessDebugEvent(v8::DebugEvent event, | 2692 void Debug::ProcessDebugEvent(v8::DebugEvent event, |
2739 Handle<JSObject> event_data, | 2693 Handle<JSObject> event_data, |
2740 bool auto_continue) { | 2694 bool auto_continue) { |
2741 HandleScope scope(isolate_); | 2695 HandleScope scope(isolate_); |
2742 | 2696 |
2743 // Create the execution state. | 2697 // Create the execution state. |
2744 Handle<Object> exec_state; | 2698 Handle<Object> exec_state; |
2745 // Bail out and don't call debugger if exception. | 2699 // Bail out and don't call debugger if exception. |
2746 if (!MakeExecutionState().ToHandle(&exec_state)) return; | 2700 if (!MakeExecutionState().ToHandle(&exec_state)) return; |
2747 | 2701 |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2829 sendEventMessage = !auto_continue; | 2783 sendEventMessage = !auto_continue; |
2830 break; | 2784 break; |
2831 case v8::Exception: | 2785 case v8::Exception: |
2832 sendEventMessage = true; | 2786 sendEventMessage = true; |
2833 break; | 2787 break; |
2834 case v8::BeforeCompile: | 2788 case v8::BeforeCompile: |
2835 break; | 2789 break; |
2836 case v8::AfterCompile: | 2790 case v8::AfterCompile: |
2837 sendEventMessage = true; | 2791 sendEventMessage = true; |
2838 break; | 2792 break; |
2839 case v8::ScriptCollected: | |
2840 sendEventMessage = true; | |
2841 break; | |
2842 case v8::NewFunction: | 2793 case v8::NewFunction: |
2843 break; | 2794 break; |
2844 default: | 2795 default: |
2845 UNREACHABLE(); | 2796 UNREACHABLE(); |
2846 } | 2797 } |
2847 | 2798 |
2848 // The debug command interrupt flag might have been set when the command was | 2799 // The debug command interrupt flag might have been set when the command was |
2849 // added. It should be enough to clear the flag only once while we are in the | 2800 // added. It should be enough to clear the flag only once while we are in the |
2850 // debugger. | 2801 // debugger. |
2851 ASSERT(in_debug_scope()); | 2802 ASSERT(in_debug_scope()); |
2852 isolate_->stack_guard()->ClearDebugCommand(); | 2803 isolate_->stack_guard()->ClearDebugCommand(); |
2853 | 2804 |
2854 // Notify the debugger that a debug event has occurred unless auto continue is | 2805 // Notify the debugger that a debug event has occurred unless auto continue is |
2855 // active in which case no event is send. | 2806 // active in which case no event is send. |
2856 if (sendEventMessage) { | 2807 if (sendEventMessage) { |
2857 MessageImpl message = MessageImpl::NewEvent( | 2808 MessageImpl message = MessageImpl::NewEvent( |
2858 event, | 2809 event, |
2859 auto_continue, | 2810 auto_continue, |
2860 Handle<JSObject>::cast(exec_state), | 2811 Handle<JSObject>::cast(exec_state), |
2861 Handle<JSObject>::cast(event_data)); | 2812 Handle<JSObject>::cast(event_data)); |
2862 InvokeMessageHandler(message); | 2813 InvokeMessageHandler(message); |
2863 } | 2814 } |
2864 | 2815 |
2865 // If auto continue don't make the event cause a break, but process messages | 2816 // If auto continue don't make the event cause a break, but process messages |
2866 // in the queue if any. For script collected events don't even process | 2817 // in the queue if any. For script collected events don't even process |
2867 // messages in the queue as the execution state might not be what is expected | 2818 // messages in the queue as the execution state might not be what is expected |
2868 // by the client. | 2819 // by the client. |
2869 if ((auto_continue && !has_commands()) || event == v8::ScriptCollected) { | 2820 if (auto_continue && !has_commands()) return; |
2870 return; | |
2871 } | |
2872 | 2821 |
2873 // DebugCommandProcessor goes here. | 2822 // DebugCommandProcessor goes here. |
2874 bool running = auto_continue; | 2823 bool running = auto_continue; |
2875 | 2824 |
2876 Handle<Object> cmd_processor_ctor = Object::GetProperty( | 2825 Handle<Object> cmd_processor_ctor = Object::GetProperty( |
2877 isolate_, exec_state, "debugCommandProcessor").ToHandleChecked(); | 2826 isolate_, exec_state, "debugCommandProcessor").ToHandleChecked(); |
2878 Handle<Object> ctor_args[] = { isolate_->factory()->ToBoolean(running) }; | 2827 Handle<Object> ctor_args[] = { isolate_->factory()->ToBoolean(running) }; |
2879 Handle<Object> cmd_processor = Execution::Call( | 2828 Handle<Object> cmd_processor = Execution::Call( |
2880 isolate_, cmd_processor_ctor, exec_state, 1, ctor_args).ToHandleChecked(); | 2829 isolate_, cmd_processor_ctor, exec_state, 1, ctor_args).ToHandleChecked(); |
2881 Handle<JSFunction> process_debug_request = Handle<JSFunction>::cast( | 2830 Handle<JSFunction> process_debug_request = Handle<JSFunction>::cast( |
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3244 } else { | 3193 } else { |
3245 return v8::Utils::ToLocal(response_json_); | 3194 return v8::Utils::ToLocal(response_json_); |
3246 } | 3195 } |
3247 } | 3196 } |
3248 | 3197 |
3249 | 3198 |
3250 v8::Handle<v8::Context> MessageImpl::GetEventContext() const { | 3199 v8::Handle<v8::Context> MessageImpl::GetEventContext() const { |
3251 Isolate* isolate = event_data_->GetIsolate(); | 3200 Isolate* isolate = event_data_->GetIsolate(); |
3252 v8::Handle<v8::Context> context = GetDebugEventContext(isolate); | 3201 v8::Handle<v8::Context> context = GetDebugEventContext(isolate); |
3253 // Isolate::context() may be NULL when "script collected" event occures. | 3202 // Isolate::context() may be NULL when "script collected" event occures. |
3254 ASSERT(!context.IsEmpty() || event_ == v8::ScriptCollected); | 3203 ASSERT(!context.IsEmpty()); |
3255 return context; | 3204 return context; |
3256 } | 3205 } |
3257 | 3206 |
3258 | 3207 |
3259 v8::Debug::ClientData* MessageImpl::GetClientData() const { | 3208 v8::Debug::ClientData* MessageImpl::GetClientData() const { |
3260 return client_data_; | 3209 return client_data_; |
3261 } | 3210 } |
3262 | 3211 |
3263 | 3212 |
3264 EventDetailsImpl::EventDetailsImpl(DebugEvent event, | 3213 EventDetailsImpl::EventDetailsImpl(DebugEvent event, |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3395 logger_->DebugEvent("Put", message.text()); | 3344 logger_->DebugEvent("Put", message.text()); |
3396 } | 3345 } |
3397 | 3346 |
3398 | 3347 |
3399 void LockingCommandMessageQueue::Clear() { | 3348 void LockingCommandMessageQueue::Clear() { |
3400 LockGuard<Mutex> lock_guard(&mutex_); | 3349 LockGuard<Mutex> lock_guard(&mutex_); |
3401 queue_.Clear(); | 3350 queue_.Clear(); |
3402 } | 3351 } |
3403 | 3352 |
3404 } } // namespace v8::internal | 3353 } } // namespace v8::internal |
OLD | NEW |