| 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); | |
| 24 | 20 |
| 25 /** | 21 /** |
| 26 * Id of the inspected page global context. It is used for filtering scripts. | 22 * Id of the inspected page global context. It is used for filtering scripts. |
| 27 * @type {number} | 23 * @type {number} |
| 28 */ | 24 */ |
| 29 this.contextId_ = null; | 25 this.contextId_ = null; |
| 30 | 26 |
| 31 /** | 27 /** |
| 32 * Mapping from script id to script info. | 28 * Mapping from script id to script info. |
| 33 * @type {Object} | 29 * @type {Object} |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 /** | 79 /** |
| 84 * If backtrace response is received when initial scripts response | 80 * If backtrace response is received when initial scripts response |
| 85 * is not yet processed the backtrace handling will be postponed until | 81 * is not yet processed the backtrace handling will be postponed until |
| 86 * after the scripts response processing. The handler bound to its arguments | 82 * after the scripts response processing. The handler bound to its arguments |
| 87 * and this agent will be stored in this field then. | 83 * and this agent will be stored in this field then. |
| 88 * @type {?function()} | 84 * @type {?function()} |
| 89 */ | 85 */ |
| 90 this.pendingBacktraceResponseHandler_ = null; | 86 this.pendingBacktraceResponseHandler_ = null; |
| 91 | 87 |
| 92 /** | 88 /** |
| 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 /** | |
| 118 * Container of all breakpoints set using resource URL. These breakpoints | 89 * Container of all breakpoints set using resource URL. These breakpoints |
| 119 * survive page reload. Breakpoints set by script id(for scripts that don't | 90 * survive page reload. Breakpoints set by script id(for scripts that don't |
| 120 * have URLs) are stored in ScriptInfo objects. | 91 * have URLs) are stored in ScriptInfo objects. |
| 121 * @type {Object} | 92 * @type {Object} |
| 122 */ | 93 */ |
| 123 this.urlToBreakpoints_ = {}; | 94 this.urlToBreakpoints_ = {}; |
| 124 | 95 |
| 125 | 96 |
| 126 /** | 97 /** |
| 127 * Exception message that is shown to user while on exception break. | 98 * Exception message that is shown to user while on exception break. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 138 devtools.DebuggerAgent.ScopeType = { | 109 devtools.DebuggerAgent.ScopeType = { |
| 139 Global: 0, | 110 Global: 0, |
| 140 Local: 1, | 111 Local: 1, |
| 141 With: 2, | 112 With: 2, |
| 142 Closure: 3, | 113 Closure: 3, |
| 143 Catch: 4 | 114 Catch: 4 |
| 144 }; | 115 }; |
| 145 | 116 |
| 146 | 117 |
| 147 /** | 118 /** |
| 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 /** | |
| 161 * Resets debugger agent to its initial state. | 119 * Resets debugger agent to its initial state. |
| 162 */ | 120 */ |
| 163 devtools.DebuggerAgent.prototype.reset = function() { | 121 devtools.DebuggerAgent.prototype.reset = function() { |
| 164 this.contextId_ = null; | 122 this.contextId_ = null; |
| 165 // No need to request scripts since they all will be pushed in AfterCompile | 123 // No need to request scripts since they all will be pushed in AfterCompile |
| 166 // events. | 124 // events. |
| 167 this.requestScriptsWhenContextIdSet_ = false; | 125 this.requestScriptsWhenContextIdSet_ = false; |
| 168 this.waitingForInitialScriptsResponse_ = false; | 126 this.waitingForInitialScriptsResponse_ = false; |
| 169 | 127 |
| 170 this.parsedScripts_ = {}; | 128 this.parsedScripts_ = {}; |
| 171 this.requestNumberToBreakpointInfo_ = {}; | 129 this.requestNumberToBreakpointInfo_ = {}; |
| 172 this.callFrames_ = []; | 130 this.callFrames_ = []; |
| 173 this.requestSeqToCallback_ = {}; | 131 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. | |
| 178 }; | 132 }; |
| 179 | 133 |
| 180 | 134 |
| 181 /** | 135 /** |
| 182 * Initializes scripts UI. This method is called every time Scripts panel | 136 * Initializes scripts UI. This method is called every time Scripts panel |
| 183 * is shown. It will send request for context id if it's not set yet. | 137 * is shown. It will send request for context id if it's not set yet. |
| 184 */ | 138 */ |
| 185 devtools.DebuggerAgent.prototype.initUI = function() { | 139 devtools.DebuggerAgent.prototype.initUI = function() { |
| 186 // Initialize scripts cache when Scripts panel is shown first time. | 140 // Initialize scripts cache when Scripts panel is shown first time. |
| 187 if (this.scriptsPanelInitialized_) { | 141 if (this.scriptsPanelInitialized_) { |
| (...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 661 } else { | 615 } else { |
| 662 this.resolveFrameVariables_(callFrameId, | 616 this.resolveFrameVariables_(callFrameId, |
| 663 function(result) { | 617 function(result) { |
| 664 reportCompletions(result, false /* isException */); | 618 reportCompletions(result, false /* isException */); |
| 665 }); | 619 }); |
| 666 } | 620 } |
| 667 }; | 621 }; |
| 668 | 622 |
| 669 | 623 |
| 670 /** | 624 /** |
| 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 /** | |
| 742 * @param{number} scriptId | 625 * @param{number} scriptId |
| 743 * @return {string} Type of the context of the script with specified id. | 626 * @return {string} Type of the context of the script with specified id. |
| 744 */ | 627 */ |
| 745 devtools.DebuggerAgent.prototype.getScriptContextType = function(scriptId) { | 628 devtools.DebuggerAgent.prototype.getScriptContextType = function(scriptId) { |
| 746 return this.parsedScripts_[scriptId].getContextType(); | 629 return this.parsedScripts_[scriptId].getContextType(); |
| 747 }; | 630 }; |
| 748 | 631 |
| 749 | 632 |
| 750 /** | 633 /** |
| 751 * Removes specified breakpoint from the v8 debugger. | 634 * Removes specified breakpoint from the v8 debugger. |
| (...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1034 | 917 |
| 1035 // Ignore scripts from other tabs. | 918 // Ignore scripts from other tabs. |
| 1036 if (!this.isScriptFromInspectedContext_(script, msg)) { | 919 if (!this.isScriptFromInspectedContext_(script, msg)) { |
| 1037 return; | 920 return; |
| 1038 } | 921 } |
| 1039 this.addScriptInfo_(script, msg); | 922 this.addScriptInfo_(script, msg); |
| 1040 }; | 923 }; |
| 1041 | 924 |
| 1042 | 925 |
| 1043 /** | 926 /** |
| 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 /** | |
| 1081 * Adds the script info to the local cache. This method assumes that the script | 927 * Adds the script info to the local cache. This method assumes that the script |
| 1082 * is not in the cache yet. | 928 * is not in the cache yet. |
| 1083 * @param {Object} script Script json object from the debugger message. | 929 * @param {Object} script Script json object from the debugger message. |
| 1084 * @param {devtools.DebuggerMessage} msg Debugger message containing the script | 930 * @param {devtools.DebuggerMessage} msg Debugger message containing the script |
| 1085 * data. | 931 * data. |
| 1086 */ | 932 */ |
| 1087 devtools.DebuggerAgent.prototype.addScriptInfo_ = function(script, msg) { | 933 devtools.DebuggerAgent.prototype.addScriptInfo_ = function(script, msg) { |
| 1088 var context = msg.lookup(script.context.ref); | 934 var context = msg.lookup(script.context.ref); |
| 1089 var contextType; | 935 var contextType; |
| 1090 if (goog.isString(context.data)) { | 936 if (goog.isString(context.data)) { |
| (...skipping 558 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1649 | 1495 |
| 1650 | 1496 |
| 1651 /** | 1497 /** |
| 1652 * @param {number} handle Object handle. | 1498 * @param {number} handle Object handle. |
| 1653 * @return {?Object} Returns the object with the handle if it was sent in this | 1499 * @return {?Object} Returns the object with the handle if it was sent in this |
| 1654 * message(some objects referenced by handles may be missing in the message). | 1500 * message(some objects referenced by handles may be missing in the message). |
| 1655 */ | 1501 */ |
| 1656 devtools.DebuggerMessage.prototype.lookup = function(handle) { | 1502 devtools.DebuggerMessage.prototype.lookup = function(handle) { |
| 1657 return this.refs_[handle]; | 1503 return this.refs_[handle]; |
| 1658 }; | 1504 }; |
| OLD | NEW |