| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium 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 /** | 5 /** |
| 6 * @fileoverview Provides communication interface to remote v8 debugger. See | 6 * @fileoverview Provides communication interface to remote v8 debugger. See |
| 7 * protocol decription at http://code.google.com/p/v8/wiki/DebuggerProtocol | 7 * protocol decription at http://code.google.com/p/v8/wiki/DebuggerProtocol |
| 8 */ | 8 */ |
| 9 goog.provide('devtools.DebuggerAgent'); | 9 goog.provide('devtools.DebuggerAgent'); |
| 10 | 10 |
| 11 | 11 |
| 12 /** | 12 /** |
| 13 * @constructor | 13 * @constructor |
| 14 */ | 14 */ |
| 15 devtools.DebuggerAgent = function() { | 15 devtools.DebuggerAgent = function() { |
| 16 RemoteDebuggerAgent.DebuggerOutput = | 16 RemoteDebuggerAgent.DebuggerOutput = |
| 17 goog.bind(this.handleDebuggerOutput_, this); | 17 goog.bind(this.handleDebuggerOutput_, this); |
| 18 RemoteDebuggerAgent.SetContextId = | 18 RemoteDebuggerAgent.SetContextId = |
| 19 goog.bind(this.setContextId_, this); | 19 goog.bind(this.setContextId_, this); |
| 20 RemoteDebuggerAgent.DidGetActiveProfilerModules = |
| 21 goog.bind(this.didGetActiveProfilerModules_, this); |
| 22 RemoteDebuggerAgent.DidGetNextLogLines = |
| 23 goog.bind(this.didGetNextLogLines_, this); |
| 20 | 24 |
| 21 /** | 25 /** |
| 22 * Id of the inspected page global context. It is used for filtering scripts. | 26 * Id of the inspected page global context. It is used for filtering scripts. |
| 23 * @type {number} | 27 * @type {number} |
| 24 */ | 28 */ |
| 25 this.contextId_ = null; | 29 this.contextId_ = null; |
| 26 | 30 |
| 27 /** | 31 /** |
| 28 * Mapping from script id to script info. | 32 * Mapping from script id to script info. |
| 29 * @type {Object} | 33 * @type {Object} |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 79 /** | 83 /** |
| 80 * If backtrace response is received when initial scripts response | 84 * If backtrace response is received when initial scripts response |
| 81 * is not yet processed the backtrace handling will be postponed until | 85 * is not yet processed the backtrace handling will be postponed until |
| 82 * after the scripts response processing. The handler bound to its arguments | 86 * after the scripts response processing. The handler bound to its arguments |
| 83 * and this agent will be stored in this field then. | 87 * and this agent will be stored in this field then. |
| 84 * @type {?function()} | 88 * @type {?function()} |
| 85 */ | 89 */ |
| 86 this.pendingBacktraceResponseHandler_ = null; | 90 this.pendingBacktraceResponseHandler_ = null; |
| 87 | 91 |
| 88 /** | 92 /** |
| 93 * Active profiler modules flags. |
| 94 * @type {number} |
| 95 */ |
| 96 this.activeProfilerModules_ = |
| 97 devtools.DebuggerAgent.ProfilerModules.PROFILER_MODULE_NONE; |
| 98 |
| 99 /** |
| 100 * Interval for polling profiler state. |
| 101 * @type {number} |
| 102 */ |
| 103 this.getActiveProfilerModulesInterval_ = null; |
| 104 |
| 105 /** |
| 106 * Whether log contents retrieval must be forced next time. |
| 107 * @type {boolean} |
| 108 */ |
| 109 this.forceGetLogLines_ = false; |
| 110 |
| 111 /** |
| 112 * Profiler processor instance. |
| 113 * @type {devtools.profiler.Processor} |
| 114 */ |
| 115 this.profilerProcessor_ = new devtools.profiler.Processor(); |
| 116 |
| 117 /** |
| 89 * Container of all breakpoints set using resource URL. These breakpoints | 118 * Container of all breakpoints set using resource URL. These breakpoints |
| 90 * survive page reload. Breakpoints set by script id(for scripts that don't | 119 * survive page reload. Breakpoints set by script id(for scripts that don't |
| 91 * have URLs) are stored in ScriptInfo objects. | 120 * have URLs) are stored in ScriptInfo objects. |
| 92 * @type {Object} | 121 * @type {Object} |
| 93 */ | 122 */ |
| 94 this.urlToBreakpoints_ = {}; | 123 this.urlToBreakpoints_ = {}; |
| 95 | 124 |
| 96 | 125 |
| 97 /** | 126 /** |
| 98 * Exception message that is shown to user while on exception break. | 127 * Exception message that is shown to user while on exception break. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 109 devtools.DebuggerAgent.ScopeType = { | 138 devtools.DebuggerAgent.ScopeType = { |
| 110 Global: 0, | 139 Global: 0, |
| 111 Local: 1, | 140 Local: 1, |
| 112 With: 2, | 141 With: 2, |
| 113 Closure: 3, | 142 Closure: 3, |
| 114 Catch: 4 | 143 Catch: 4 |
| 115 }; | 144 }; |
| 116 | 145 |
| 117 | 146 |
| 118 /** | 147 /** |
| 148 * A copy of enum from include/v8.h |
| 149 * @enum {number} |
| 150 */ |
| 151 devtools.DebuggerAgent.ProfilerModules = { |
| 152 PROFILER_MODULE_NONE: 0, |
| 153 PROFILER_MODULE_CPU: 1, |
| 154 PROFILER_MODULE_HEAP_STATS: 1 << 1, |
| 155 PROFILER_MODULE_JS_CONSTRUCTORS: 1 << 2, |
| 156 PROFILER_MODULE_HEAP_SNAPSHOT: 1 << 16 |
| 157 }; |
| 158 |
| 159 |
| 160 /** |
| 119 * Resets debugger agent to its initial state. | 161 * Resets debugger agent to its initial state. |
| 120 */ | 162 */ |
| 121 devtools.DebuggerAgent.prototype.reset = function() { | 163 devtools.DebuggerAgent.prototype.reset = function() { |
| 122 this.contextId_ = null; | 164 this.contextId_ = null; |
| 123 // No need to request scripts since they all will be pushed in AfterCompile | 165 // No need to request scripts since they all will be pushed in AfterCompile |
| 124 // events. | 166 // events. |
| 125 this.requestScriptsWhenContextIdSet_ = false; | 167 this.requestScriptsWhenContextIdSet_ = false; |
| 126 this.waitingForInitialScriptsResponse_ = false; | 168 this.waitingForInitialScriptsResponse_ = false; |
| 127 | 169 |
| 128 this.parsedScripts_ = {}; | 170 this.parsedScripts_ = {}; |
| 129 this.requestNumberToBreakpointInfo_ = {}; | 171 this.requestNumberToBreakpointInfo_ = {}; |
| 130 this.callFrames_ = []; | 172 this.callFrames_ = []; |
| 131 this.requestSeqToCallback_ = {}; | 173 this.requestSeqToCallback_ = {}; |
| 174 |
| 175 // Profiler isn't reset because it contains no data that is |
| 176 // specific for a particular V8 instance. All such data is |
| 177 // managed by an agent on the Render's side. |
| 132 }; | 178 }; |
| 133 | 179 |
| 134 | 180 |
| 135 /** | 181 /** |
| 136 * Initializes scripts UI. This method is called every time Scripts panel | 182 * Initializes scripts UI. This method is called every time Scripts panel |
| 137 * is shown. It will send request for context id if it's not set yet. | 183 * is shown. It will send request for context id if it's not set yet. |
| 138 */ | 184 */ |
| 139 devtools.DebuggerAgent.prototype.initUI = function() { | 185 devtools.DebuggerAgent.prototype.initUI = function() { |
| 140 // Initialize scripts cache when Scripts panel is shown first time. | 186 // Initialize scripts cache when Scripts panel is shown first time. |
| 141 if (this.scriptsPanelInitialized_) { | 187 if (this.scriptsPanelInitialized_) { |
| (...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 615 } else { | 661 } else { |
| 616 this.resolveFrameVariables_(callFrameId, | 662 this.resolveFrameVariables_(callFrameId, |
| 617 function(result) { | 663 function(result) { |
| 618 reportCompletions(result, false /* isException */); | 664 reportCompletions(result, false /* isException */); |
| 619 }); | 665 }); |
| 620 } | 666 } |
| 621 }; | 667 }; |
| 622 | 668 |
| 623 | 669 |
| 624 /** | 670 /** |
| 671 * Sets up callbacks that deal with profiles processing. |
| 672 */ |
| 673 devtools.DebuggerAgent.prototype.setupProfilerProcessorCallbacks = function() { |
| 674 // A temporary icon indicating that the profile is being processed. |
| 675 var processingIcon = new WebInspector.SidebarTreeElement( |
| 676 'profile-sidebar-tree-item', |
| 677 WebInspector.UIString('Processing...'), |
| 678 '', null, false); |
| 679 var profilesSidebar = WebInspector.panels.profiles.getProfileType( |
| 680 WebInspector.CPUProfileType.TypeId).treeElement; |
| 681 |
| 682 this.profilerProcessor_.setCallbacks( |
| 683 function onProfileProcessingStarted() { |
| 684 // Set visually empty string. Subtitle hiding is done via styles |
| 685 // manipulation which doesn't play well with dynamic append / removal. |
| 686 processingIcon.subtitle = ' '; |
| 687 profilesSidebar.appendChild(processingIcon); |
| 688 }, |
| 689 function onProfileProcessingStatus(ticksCount) { |
| 690 processingIcon.subtitle = |
| 691 WebInspector.UIString('%d ticks processed', ticksCount); |
| 692 }, |
| 693 function onProfileProcessingFinished(profile) { |
| 694 profilesSidebar.removeChild(processingIcon); |
| 695 profile.typeId = WebInspector.CPUProfileType.TypeId; |
| 696 InspectorBackend.addFullProfile(profile); |
| 697 WebInspector.addProfileHeader(profile); |
| 698 // If no profile is currently shown, show the new one. |
| 699 var profilesPanel = WebInspector.panels.profiles; |
| 700 if (!profilesPanel.visibleView) { |
| 701 profilesPanel.showProfile(profile); |
| 702 } |
| 703 } |
| 704 ); |
| 705 }; |
| 706 |
| 707 |
| 708 /** |
| 709 * Initializes profiling state. |
| 710 */ |
| 711 devtools.DebuggerAgent.prototype.initializeProfiling = function() { |
| 712 this.setupProfilerProcessorCallbacks(); |
| 713 this.forceGetLogLines_ = true; |
| 714 this.getActiveProfilerModulesInterval_ = setInterval( |
| 715 function() { RemoteDebuggerAgent.GetActiveProfilerModules(); }, 1000); |
| 716 }; |
| 717 |
| 718 |
| 719 /** |
| 720 * Starts profiling. |
| 721 * @param {number} modules List of modules to enable. |
| 722 */ |
| 723 devtools.DebuggerAgent.prototype.startProfiling = function(modules) { |
| 724 RemoteDebuggerAgent.StartProfiling(modules); |
| 725 if (modules & |
| 726 devtools.DebuggerAgent.ProfilerModules.PROFILER_MODULE_HEAP_SNAPSHOT) { |
| 727 // Active modules will not change, instead, a snapshot will be logged. |
| 728 RemoteDebuggerAgent.GetNextLogLines(); |
| 729 } |
| 730 }; |
| 731 |
| 732 |
| 733 /** |
| 734 * Stops profiling. |
| 735 */ |
| 736 devtools.DebuggerAgent.prototype.stopProfiling = function(modules) { |
| 737 RemoteDebuggerAgent.StopProfiling(modules); |
| 738 }; |
| 739 |
| 740 |
| 741 /** |
| 625 * @param{number} scriptId | 742 * @param{number} scriptId |
| 626 * @return {string} Type of the context of the script with specified id. | 743 * @return {string} Type of the context of the script with specified id. |
| 627 */ | 744 */ |
| 628 devtools.DebuggerAgent.prototype.getScriptContextType = function(scriptId) { | 745 devtools.DebuggerAgent.prototype.getScriptContextType = function(scriptId) { |
| 629 return this.parsedScripts_[scriptId].getContextType(); | 746 return this.parsedScripts_[scriptId].getContextType(); |
| 630 }; | 747 }; |
| 631 | 748 |
| 632 | 749 |
| 633 /** | 750 /** |
| 634 * Removes specified breakpoint from the v8 debugger. | 751 * Removes specified breakpoint from the v8 debugger. |
| (...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 917 | 1034 |
| 918 // Ignore scripts from other tabs. | 1035 // Ignore scripts from other tabs. |
| 919 if (!this.isScriptFromInspectedContext_(script, msg)) { | 1036 if (!this.isScriptFromInspectedContext_(script, msg)) { |
| 920 return; | 1037 return; |
| 921 } | 1038 } |
| 922 this.addScriptInfo_(script, msg); | 1039 this.addScriptInfo_(script, msg); |
| 923 }; | 1040 }; |
| 924 | 1041 |
| 925 | 1042 |
| 926 /** | 1043 /** |
| 1044 * Handles current profiler status. |
| 1045 * @param {number} modules List of active (started) modules. |
| 1046 */ |
| 1047 devtools.DebuggerAgent.prototype.didGetActiveProfilerModules_ = function( |
| 1048 modules) { |
| 1049 var profModules = devtools.DebuggerAgent.ProfilerModules; |
| 1050 var profModuleNone = profModules.PROFILER_MODULE_NONE; |
| 1051 if (this.forceGetLogLines_ || |
| 1052 (modules != profModuleNone && |
| 1053 this.activeProfilerModules_ == profModuleNone)) { |
| 1054 this.forceGetLogLines_ = false; |
| 1055 // Start to query log data. |
| 1056 RemoteDebuggerAgent.GetNextLogLines(); |
| 1057 } |
| 1058 this.activeProfilerModules_ = modules; |
| 1059 // Update buttons. |
| 1060 WebInspector.setRecordingProfile(modules & profModules.PROFILER_MODULE_CPU); |
| 1061 }; |
| 1062 |
| 1063 |
| 1064 /** |
| 1065 * Handles a portion of a profiler log retrieved by GetNextLogLines call. |
| 1066 * @param {string} log A portion of profiler log. |
| 1067 */ |
| 1068 devtools.DebuggerAgent.prototype.didGetNextLogLines_ = function(log) { |
| 1069 if (log.length > 0) { |
| 1070 this.profilerProcessor_.processLogChunk(log); |
| 1071 } else if (this.activeProfilerModules_ == |
| 1072 devtools.DebuggerAgent.ProfilerModules.PROFILER_MODULE_NONE) { |
| 1073 // No new data and profiling is stopped---suspend log reading. |
| 1074 return; |
| 1075 } |
| 1076 setTimeout(function() { RemoteDebuggerAgent.GetNextLogLines(); }, 500); |
| 1077 }; |
| 1078 |
| 1079 |
| 1080 /** |
| 927 * Adds the script info to the local cache. This method assumes that the script | 1081 * Adds the script info to the local cache. This method assumes that the script |
| 928 * is not in the cache yet. | 1082 * is not in the cache yet. |
| 929 * @param {Object} script Script json object from the debugger message. | 1083 * @param {Object} script Script json object from the debugger message. |
| 930 * @param {devtools.DebuggerMessage} msg Debugger message containing the script | 1084 * @param {devtools.DebuggerMessage} msg Debugger message containing the script |
| 931 * data. | 1085 * data. |
| 932 */ | 1086 */ |
| 933 devtools.DebuggerAgent.prototype.addScriptInfo_ = function(script, msg) { | 1087 devtools.DebuggerAgent.prototype.addScriptInfo_ = function(script, msg) { |
| 934 var context = msg.lookup(script.context.ref); | 1088 var context = msg.lookup(script.context.ref); |
| 935 var contextType; | 1089 var contextType; |
| 936 if (goog.isString(context.data)) { | 1090 if (goog.isString(context.data)) { |
| (...skipping 558 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1495 | 1649 |
| 1496 | 1650 |
| 1497 /** | 1651 /** |
| 1498 * @param {number} handle Object handle. | 1652 * @param {number} handle Object handle. |
| 1499 * @return {?Object} Returns the object with the handle if it was sent in this | 1653 * @return {?Object} Returns the object with the handle if it was sent in this |
| 1500 * message(some objects referenced by handles may be missing in the message). | 1654 * message(some objects referenced by handles may be missing in the message). |
| 1501 */ | 1655 */ |
| 1502 devtools.DebuggerMessage.prototype.lookup = function(handle) { | 1656 devtools.DebuggerMessage.prototype.lookup = function(handle) { |
| 1503 return this.refs_[handle]; | 1657 return this.refs_[handle]; |
| 1504 }; | 1658 }; |
| OLD | NEW |