From 9d17b0d4c82ce3477c014044f6914fdbf6692f69 Mon Sep 17 00:00:00 2001 From: "sgjesse@chromium.org" Date: Tue, 10 Mar 2009 08:10:50 +0000 Subject: [PATCH] Whenever a script object is created it is assigned a unique id. Currently this id is assigned from an 32 bit integer counter. Changed the script break points to be able to handle both break points based on script names and script ids. When break points are set through a script id the position is relative to the script itself. This is different from the script break points set through script names where the line/coulmn offset is taken into account. This has the side effect that function break points are not converted into script break points for named scripts. Show the script id in the D8 shell debugger when listing all scripts using the 'scripts' command. Review URL: http://codereview.chromium.org/40317 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@1468 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- include/v8.h | 5 + src/accessors.cc | 18 +++ src/accessors.h | 2 + src/api.cc | 16 +++ src/bootstrapper.cc | 11 +- src/d8.js | 21 ++-- src/debug-delay.js | 130 ++++++++++++++------ src/factory.cc | 8 ++ src/factory.h | 1 + src/mirror-delay.js | 8 +- src/objects-inl.h | 1 + src/objects.h | 6 +- test/cctest/test-debug.cc | 200 ++++++++++++++++++++++++------- test/mjsunit/debug-script-breakpoints.js | 55 +++++++-- test/mjsunit/debug-setbreakpoint.js | 68 ++++++++--- 15 files changed, 436 insertions(+), 114 deletions(-) diff --git a/include/v8.h b/include/v8.h index a048acd..44d0307 100644 --- a/include/v8.h +++ b/include/v8.h @@ -524,6 +524,11 @@ class EXPORT Script { * Runs the script returning the resulting value. */ Local Run(); + + /** + * Returns the script id value. + */ + Local Id(); }; diff --git a/src/accessors.cc b/src/accessors.cc index 901dc07..cc89808 100644 --- a/src/accessors.cc +++ b/src/accessors.cc @@ -198,6 +198,24 @@ const AccessorDescriptor Accessors::ScriptName = { // +// Accessors::ScriptId +// + + +Object* Accessors::ScriptGetId(Object* object, void*) { + Object* script = JSValue::cast(object)->value(); + return Script::cast(script)->id(); +} + + +const AccessorDescriptor Accessors::ScriptId = { + ScriptGetId, + IllegalSetter, + 0 +}; + + +// // Accessors::ScriptLineOffset // diff --git a/src/accessors.h b/src/accessors.h index 0175c9a..938b014 100644 --- a/src/accessors.h +++ b/src/accessors.h @@ -42,6 +42,7 @@ namespace v8 { namespace internal { V(StringLength) \ V(ScriptSource) \ V(ScriptName) \ + V(ScriptId) \ V(ScriptLineOffset) \ V(ScriptColumnOffset) \ V(ScriptType) \ @@ -79,6 +80,7 @@ class Accessors : public AllStatic { static Object* ArrayGetLength(Object* object, void*); static Object* StringGetLength(Object* object, void*); static Object* ScriptGetName(Object* object, void*); + static Object* ScriptGetId(Object* object, void*); static Object* ScriptGetSource(Object* object, void*); static Object* ScriptGetLineOffset(Object* object, void*); static Object* ScriptGetColumnOffset(Object* object, void*); diff --git a/src/api.cc b/src/api.cc index dfdab9f..804557f 100644 --- a/src/api.cc +++ b/src/api.cc @@ -1054,6 +1054,22 @@ Local Script::Run() { } +Local Script::Id() { + ON_BAILOUT("v8::Script::Id()", return Local()); + LOG_API("Script::Id"); + i::Object* raw_id = NULL; + { + HandleScope scope; + i::Handle fun = Utils::OpenHandle(this); + i::Handle script(i::Script::cast(fun->shared()->script())); + i::Handle id(script->id()); + raw_id = *id; + } + i::Handle id(raw_id); + return Utils::ToLocal(id); +} + + // --- E x c e p t i o n s --- diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc index f59f081..0a0ed83 100644 --- a/src/bootstrapper.cc +++ b/src/bootstrapper.cc @@ -985,12 +985,19 @@ bool Genesis::InstallNatives() { Factory::LookupAsciiSymbol("source"), proxy_source, common_attributes); - Handle proxy_data = Factory::NewProxy(&Accessors::ScriptName); + Handle proxy_name = Factory::NewProxy(&Accessors::ScriptName); script_descriptors = Factory::CopyAppendProxyDescriptor( script_descriptors, Factory::LookupAsciiSymbol("name"), - proxy_data, + proxy_name, + common_attributes); + Handle proxy_id = Factory::NewProxy(&Accessors::ScriptId); + script_descriptors = + Factory::CopyAppendProxyDescriptor( + script_descriptors, + Factory::LookupAsciiSymbol("id"), + proxy_id, common_attributes); Handle proxy_line_offset = Factory::NewProxy(&Accessors::ScriptLineOffset); diff --git a/src/d8.js b/src/d8.js index 27c2492..04b90fe 100644 --- a/src/d8.js +++ b/src/d8.js @@ -888,18 +888,19 @@ function DebugResponseDetails(response) { var result = ''; for (i = 0; i < body.length; i++) { if (i != 0) result += '\n'; + if (body[i].id) { + result += body[i].id; + } else { + result += '[no id]'; + } + result += ', '; if (body[i].name) { result += body[i].name; } else { result += '[unnamed] '; - var sourceStart = body[i].sourceStart; - if (sourceStart.length > 40) { - sourceStart = sourceStart.substring(0, 37) + '...'; - } - result += sourceStart; } result += ' (lines: '; - result += body[i].sourceLines; + result += body[i].lineCount; result += ', length: '; result += body[i].sourceLength; if (body[i].type == Debug.ScriptType.Native) { @@ -907,7 +908,13 @@ function DebugResponseDetails(response) { } else if (body[i].type == Debug.ScriptType.Extension) { result += ', extension'; } - result += ')'; + result += '), ['; + var sourceStart = body[i].sourceStart; + if (sourceStart.length > 40) { + sourceStart = sourceStart.substring(0, 37) + '...'; + } + result += sourceStart; + result += ']'; } details.text = result; break; diff --git a/src/debug-delay.js b/src/debug-delay.js index b84fe2b..11796ad 100644 --- a/src/debug-delay.js +++ b/src/debug-delay.js @@ -61,6 +61,10 @@ Debug.ScriptType = { Native: 0, Extension: 1, Normal: 2 }; +// The different script break point types. +Debug.ScriptBreakPointType = { ScriptId: 0, + ScriptName: 1 }; + function ScriptTypeFlag(type) { return (1 << type); } @@ -210,9 +214,15 @@ function IsBreakPointTriggered(break_id, break_point) { // Object representing a script break point. The script is referenced by its -// script name and the break point is represented as line and column. -function ScriptBreakPoint(script_name, opt_line, opt_column) { - this.script_name_ = script_name; +// script name or script id and the break point is represented as line and +// column. +function ScriptBreakPoint(type, script_id_or_name, opt_line, opt_column) { + this.type_ = type; + if (type == Debug.ScriptBreakPointType.ScriptId) { + this.script_id_ = script_id_or_name; + } else { // type == Debug.ScriptBreakPointType.ScriptName + this.script_name_ = script_id_or_name; + } this.line_ = opt_line || 0; this.column_ = opt_column; this.hit_count_ = 0; @@ -227,6 +237,16 @@ ScriptBreakPoint.prototype.number = function() { }; +ScriptBreakPoint.prototype.type = function() { + return this.type_; +}; + + +ScriptBreakPoint.prototype.script_id = function() { + return this.script_id_; +}; + + ScriptBreakPoint.prototype.script_name = function() { return this.script_name_; }; @@ -292,9 +312,13 @@ ScriptBreakPoint.prototype.setIgnoreCount = function(ignoreCount) { // Check whether a script matches this script break point. Currently this is // only based on script name. ScriptBreakPoint.prototype.matchesScript = function(script) { - return this.script_name_ == script.name && - script.line_offset <= this.line_ && - this.line_ < script.line_offset + script.lineCount(); + if (this.type_ == Debug.ScriptBreakPointType.ScriptId) { + return this.script_id_ == script.id; + } else { // this.type_ == Debug.ScriptBreakPointType.ScriptName + return this.script_name_ == script.name && + script.line_offset <= this.line_ && + this.line_ < script.line_offset + script.lineCount(); + } }; @@ -356,7 +380,8 @@ ScriptBreakPoint.prototype.clear = function () { // break points set in this script. function UpdateScriptBreakPoints(script) { for (var i = 0; i < script_break_points.length; i++) { - if (script_break_points[i].script_name() == script.name) { + if (script_break_points[i].type() == Debug.ScriptBreakPointType.ScriptName && + script_break_points[i].script_name() == script.name) { script_break_points[i].set(script); } } @@ -491,15 +516,15 @@ Debug.setBreakPoint = function(func, opt_line, opt_column, opt_condition) { } // If the script for the function has a name convert this to a script break // point. - if (script && script.name) { + if (script && script.id) { // Adjust the source position to be script relative. source_position += %FunctionGetScriptSourcePosition(func); // Find line and column for the position in the script and set a script // break point from that. var location = script.locationFromPosition(source_position); - return this.setScriptBreakPoint(script.name, - location.line, location.column, - opt_condition); + return this.setScriptBreakPointById(script.id, + location.line, location.column, + opt_condition); } else { // Set a break point directly on the function. var break_point = MakeBreakPoint(source_position, opt_line, opt_column); @@ -576,18 +601,20 @@ Debug.findScriptBreakPoint = function(break_point_number, remove) { } -// Sets a breakpoint in a script identified through script name at the +// Sets a breakpoint in a script identified through id or name at the // specified source line and column within that line. -Debug.setScriptBreakPoint = function(script_name, opt_line, opt_column, opt_condition) { +Debug.setScriptBreakPoint = function(type, script_id_or_name, + opt_line, opt_column, opt_condition) { // Create script break point object. - var script_break_point = new ScriptBreakPoint(script_name, opt_line, opt_column); + var script_break_point = + new ScriptBreakPoint(type, script_id_or_name, opt_line, opt_column); // Assign number to the new script break point and add it. script_break_point.number_ = next_break_point_number++; script_break_point.setCondition(opt_condition); script_break_points.push(script_break_point); - // Run through all scripts to see it this script break point matches any + // Run through all scripts to see if this script break point matches any // loaded scripts. var scripts = this.scripts(); for (var i = 0; i < scripts.length; i++) { @@ -600,6 +627,24 @@ Debug.setScriptBreakPoint = function(script_name, opt_line, opt_column, opt_cond } +Debug.setScriptBreakPointById = function(script_id, + opt_line, opt_column, + opt_condition) { + return this.setScriptBreakPoint(Debug.ScriptBreakPointType.ScriptId, + script_id, opt_line, opt_column, + opt_condition) +} + + +Debug.setScriptBreakPointByName = function(script_name, + opt_line, opt_column, + opt_condition) { + return this.setScriptBreakPoint(Debug.ScriptBreakPointType.ScriptName, + script_name, opt_line, opt_column, + opt_condition) +} + + Debug.enableScriptBreakPoint = function(break_point_number) { var script_break_point = this.findScriptBreakPoint(break_point_number, false); script_break_point.enable(); @@ -792,11 +837,7 @@ BreakEvent.prototype.toJSONProtocol = function() { o.body.sourceLine = this.sourceLine(), o.body.sourceColumn = this.sourceColumn(), o.body.sourceLineText = this.sourceLineText(), - o.body.script = { name: script.name(), - lineOffset: script.lineOffset(), - columnOffset: script.columnOffset(), - lineCount: script.lineCount() - }; + o.body.script = MakeScriptObject_(script, false); } // Add an Array of break points hit if any. @@ -889,11 +930,7 @@ ExceptionEvent.prototype.toJSONProtocol = function() { // Add script information to the event if available. var script = this.func().script(); if (script) { - o.body.script = { name: script.name(), - lineOffset: script.lineOffset(), - columnOffset: script.columnOffset(), - lineCount: script.lineCount() - }; + o.body.script = MakeScriptObject_(script, false); } } else { o.body.sourceLine = -1; @@ -942,12 +979,7 @@ CompileEvent.prototype.toJSONProtocol = function() { o.event = "afterCompile"; } o.body = {}; - o.body.script = { name: this.script_.name(), - lineOffset: this.script_.lineOffset(), - columnOffset: this.script_.columnOffset(), - lineCount: this.script_.lineCount(), - source: this.script_.source() - }; + o.body.script = MakeScriptObject_(this.script_, true); return o.toJSONProtocol(); } @@ -978,6 +1010,20 @@ NewFunctionEvent.prototype.setBreakPoint = function(p) { }; +function MakeScriptObject_(script, include_source) { + var o = { id: script.id(), + name: script.name(), + lineOffset: script.lineOffset(), + columnOffset: script.columnOffset(), + lineCount: script.lineCount(), + }; + if (include_source) { + o.source = script.source(); + } + return o; +}; + + function DebugCommandProcessor(exec_state) { this.exec_state_ = exec_state; this.running_ = false; @@ -1222,7 +1268,7 @@ DebugCommandProcessor.prototype.setBreakPointRequest_ = response.failed('Missing argument "type" or "target"'); return; } - if (type != 'function' && type != 'script') { + if (type != 'function' && type != 'script' && type != 'scriptId') { response.failed('Illegal type "' + type + '"'); return; } @@ -1251,11 +1297,13 @@ DebugCommandProcessor.prototype.setBreakPointRequest_ = // Set function break point. break_point_number = Debug.setBreakPoint(f, line, column, condition); - } else { + } else if (type == 'script') { // set script break point. - break_point_number = Debug.setScriptBreakPoint(target, - line, column, - condition); + break_point_number = + Debug.setScriptBreakPointByName(target, line, column, condition); + } else { // type == 'scriptId. + break_point_number = + Debug.setScriptBreakPointById(target, line, column, condition); } // Set additional break point properties. @@ -1273,8 +1321,13 @@ DebugCommandProcessor.prototype.setBreakPointRequest_ = // Add break point information to the response. if (break_point instanceof ScriptBreakPoint) { - response.body.type = 'script'; - response.body.script_name = break_point.script_name(); + if (break_point.type() == Debug.ScriptBreakPointType.ScriptId) { + response.body.type = 'scriptId'; + response.body.script_id = break_point.script_id(); + } else { + response.body.type = 'scriptName'; + response.body.script_name = break_point.script_name(); + } response.body.line = break_point.line(); response.body.column = break_point.column(); } else { @@ -1607,6 +1660,7 @@ DebugCommandProcessor.prototype.scriptsRequest_ = function(request, response) { if (scripts[i].name) { script.name = scripts[i].name; } + script.id = scripts[i].id; script.lineOffset = scripts[i].line_offset; script.columnOffset = scripts[i].column_offset; script.lineCount = scripts[i].lineCount(); diff --git a/src/factory.cc b/src/factory.cc index 98b7619..a9cdd43 100644 --- a/src/factory.cc +++ b/src/factory.cc @@ -153,9 +153,12 @@ Handle Factory::NewAccessorInfo() { Handle