diff --git a/toolkit/devtools/debugger/dbg-client.jsm b/toolkit/devtools/debugger/dbg-client.jsm index 8c5ab00308f4..0c0e219e940e 100644 --- a/toolkit/devtools/debugger/dbg-client.jsm +++ b/toolkit/devtools/debugger/dbg-client.jsm @@ -487,6 +487,7 @@ function ThreadClient(aClient, aActor) { this._frameCache = []; this._scriptCache = {}; this._pauseGrips = {}; + this._threadGrips = {}; } ThreadClient.prototype = { @@ -861,30 +862,74 @@ ThreadClient.prototype = { }, /** - * Return an instance of LongStringClient for the given long string grip. + * Get or create a long string client, checking the grip client cache if it + * already exists. + * + * @param aGrip Object + * The long string grip returned by the protocol. + * @param aGripCacheName String + * The property name of the grip client cache to check for existing + * clients in. + */ + _longString: function TC__longString(aGrip, aGripCacheName) { + if (aGrip.actor in this[aGripCacheName]) { + return this[aGripCacheName][aGrip.actor]; + } + + let client = new LongStringClient(this._client, aGrip); + this[aGripCacheName][aGrip.actor] = client; + return client; + }, + + /** + * Return an instance of LongStringClient for the given long string grip that + * is scoped to the current pause. * * @param aGrip Object * The long string grip returned by the protocol. */ - longString: function TC_longString(aGrip) { - if (aGrip.actor in this._pauseGrips) { - return this._pauseGrips[aGrip.actor]; - } + pauseLongString: function TC_pauseLongString(aGrip) { + return this._longString(aGrip, "_pauseGrips"); + }, - let client = new LongStringClient(this._client, aGrip); - this._pauseGrips[aGrip.actor] = client; - return client; + /** + * Return an instance of LongStringClient for the given long string grip that + * is scoped to the thread lifetime. + * + * @param aGrip Object + * The long string grip returned by the protocol. + */ + threadLongString: function TC_threadLongString(aGrip) { + return this._longString(aGrip, "_threadGrips"); + }, + + /** + * Clear and invalidate all the grip clients from the given cache. + * + * @param aGripCacheName + * The property name of the grip cache we want to clear. + */ + _clearGripClients: function TC_clearGrips(aGripCacheName) { + for each (let grip in this[aGripCacheName]) { + grip.valid = false; + } + this[aGripCacheName] = {}; }, /** * Invalidate pause-lifetime grip clients and clear the list of * current grip clients. */ - _clearPauseGrips: function TC_clearPauseGrips(aPacket) { - for each (let grip in this._pauseGrips) { - grip.valid = false; - } - this._pauseGrips = {}; + _clearPauseGrips: function TC_clearPauseGrips() { + this._clearGripClients("_pauseGrips"); + }, + + /** + * Invalidate pause-lifetime grip clients and clear the list of + * current grip clients. + */ + _clearThreadGrips: function TC_clearPauseGrips() { + this._clearGripClients("_threadGrips"); }, /** @@ -895,6 +940,7 @@ ThreadClient.prototype = { this._state = ThreadStateTypes[aPacket.type]; this._clearFrames(); this._clearPauseGrips(); + aPacket.type === ThreadStateTypes.detached && this._clearThreadGrips(); this._client._eventsEnabled && this.notify(aPacket.type, aPacket); }, }; diff --git a/toolkit/devtools/debugger/server/dbg-script-actors.js b/toolkit/devtools/debugger/server/dbg-script-actors.js index e8a8598c8c24..51955dd27e79 100644 --- a/toolkit/devtools/debugger/server/dbg-script-actors.js +++ b/toolkit/devtools/debugger/server/dbg-script-actors.js @@ -787,7 +787,7 @@ ThreadActor.prototype = { let type = typeof(aValue); if (type === "string" && this._stringIsLong(aValue)) { - return this.longStringGrip(aValue); + return this.longStringGrip(aValue, this._pausePool); } if (type === "boolean" || type === "string" || type === "number") { @@ -881,26 +881,44 @@ ThreadActor.prototype = { * * @param aString String * The string we are creating a grip for. + * @param aPool ActorPool + * The actor pool where the new actor will be added. */ - longStringGrip: function TA_longStringGrip(aString) { - if (!this._pausePool) { - throw new Error("LongString grip requested while not paused."); + longStringGrip: function TA_longStringGrip(aString, aPool) { + if (!aPool.longStringActors) { + aPool.longStringActors = {}; } - if (!this._pausePool.longStringActors) { - this._pausePool.longStringActors = {}; - } - - if (this._pausePool.longStringActors.hasOwnProperty(aString)) { - return this._pausePool.longStringActors[aString].grip(); + if (aPool.longStringActors.hasOwnProperty(aString)) { + return aPool.longStringActors[aString].grip(); } let actor = new LongStringActor(aString, this); - this._pausePool.addActor(actor); - this._pausePool.longStringActors[aString] = actor; + aPool.addActor(actor); + aPool.longStringActors[aString] = actor; return actor.grip(); }, + /** + * Create a long string grip that is scoped to a pause. + * + * @param aString String + * The string we are creating a grip for. + */ + pauseLongStringGrip: function TA_pauseLongStringGrip (aString) { + return this.longStringGrip(aString, this._pausePool); + }, + + /** + * Create a long string grip that is scoped to a thread. + * + * @param aString String + * The string we are creating a grip for. + */ + threadLongStringGrip: function TA_pauseLongStringGrip (aString) { + return this.longStringGrip(aString, this._threadLifetimePool); + }, + /** * Returns true if the string is long enough to use a LongStringActor instead * of passing the value directly over the protocol. diff --git a/toolkit/devtools/debugger/tests/unit/test_longstringgrips-01.js b/toolkit/devtools/debugger/tests/unit/test_longstringgrips-01.js index bdebd8578bf1..1e93aad24e57 100644 --- a/toolkit/devtools/debugger/tests/unit/test_longstringgrips-01.js +++ b/toolkit/devtools/debugger/tests/unit/test_longstringgrips-01.js @@ -48,7 +48,7 @@ function test_longstring_grip() do_check_eq(grip.length, longString.length); do_check_eq(grip.initial, longString.substr(0, DebuggerServer.LONG_STRING_INITIAL_LENGTH)); - let longStringClient = gThreadClient.longString(grip); + let longStringClient = gThreadClient.pauseLongString(grip); longStringClient.substring(22, 28, function (aResponse) { try { do_check_eq(aResponse.substring, "monkey"); diff --git a/toolkit/devtools/debugger/tests/unit/test_longstringgrips-02.js b/toolkit/devtools/debugger/tests/unit/test_longstringgrips-02.js index 5c49ce059f3f..1bb7271406d6 100644 --- a/toolkit/devtools/debugger/tests/unit/test_longstringgrips-02.js +++ b/toolkit/devtools/debugger/tests/unit/test_longstringgrips-02.js @@ -36,7 +36,7 @@ function test_longstring_grip() actor: "123fakeActor123", initial: "" }; - let longStringClient = gThreadClient.longString(fakeLongStringGrip); + let longStringClient = gThreadClient.pauseLongString(fakeLongStringGrip); longStringClient.substring(22, 28, function (aResponse) { try { do_check_true(!!aResponse.error,