Commit 8ae463d7 authored by yangguo's avatar yangguo Committed by Commit bot

[debugger] remove mirror cache and v8::Debug::GetMirror.

R=jgruber@chromium.org
BUG=v8:5530

Review-Url: https://codereview.chromium.org/2670823002
Cr-Commit-Position: refs/heads/master@{#42893}
parent eef855a1
...@@ -194,13 +194,6 @@ class V8_EXPORT Debug { ...@@ -194,13 +194,6 @@ class V8_EXPORT Debug {
v8::Local<v8::Function> fun, v8::Local<v8::Function> fun,
Local<Value> data = Local<Value>()); Local<Value> data = Local<Value>());
/**
* Returns a mirror object for the given object.
*/
V8_DEPRECATED("No longer supported",
static MaybeLocal<Value> GetMirror(Local<Context> context,
v8::Local<v8::Value> obj));
// This is now a no-op. // This is now a no-op.
V8_DEPRECATED("No longer supported", V8_DEPRECATED("No longer supported",
static void ProcessDebugMessages(Isolate* isolate)); static void ProcessDebugMessages(Isolate* isolate));
......
...@@ -8925,26 +8925,6 @@ MaybeLocal<Value> Debug::Call(Local<Context> context, ...@@ -8925,26 +8925,6 @@ MaybeLocal<Value> Debug::Call(Local<Context> context,
} }
MaybeLocal<Value> Debug::GetMirror(Local<Context> context,
v8::Local<v8::Value> obj) {
PREPARE_FOR_EXECUTION(context, Debug, GetMirror, Value);
i::Debug* isolate_debug = isolate->debug();
has_pending_exception = !isolate_debug->Load();
RETURN_ON_FAILED_EXECUTION(Value);
i::Handle<i::JSObject> debug(isolate_debug->debug_context()->global_object());
auto name = isolate->factory()->NewStringFromStaticChars("MakeMirror");
auto fun_obj = i::JSReceiver::GetProperty(debug, name).ToHandleChecked();
auto v8_fun = Utils::CallableToLocal(i::Handle<i::JSFunction>::cast(fun_obj));
const int kArgc = 1;
v8::Local<v8::Value> argv[kArgc] = {obj};
Local<Value> result;
has_pending_exception =
!v8_fun->Call(context, Utils::ToLocal(debug), kArgc, argv)
.ToLocal(&result);
RETURN_ON_FAILED_EXECUTION(Value);
RETURN_ESCAPED(result);
}
void Debug::ProcessDebugMessages(Isolate* isolate) {} void Debug::ProcessDebugMessages(Isolate* isolate) {}
Local<Context> Debug::GetDebugContext(Isolate* isolate) { Local<Context> Debug::GetDebugContext(Isolate* isolate) {
......
...@@ -1599,13 +1599,6 @@ bool Debug::IsDebugGlobal(JSGlobalObject* global) { ...@@ -1599,13 +1599,6 @@ bool Debug::IsDebugGlobal(JSGlobalObject* global) {
} }
void Debug::ClearMirrorCache() {
PostponeInterruptsScope postpone(isolate_);
HandleScope scope(isolate_);
CallFunction("ClearMirrorCache", 0, NULL);
}
Handle<FixedArray> Debug::GetLoadedScripts() { Handle<FixedArray> Debug::GetLoadedScripts() {
isolate_->heap()->CollectAllGarbage(Heap::kFinalizeIncrementalMarkingMask, isolate_->heap()->CollectAllGarbage(Heap::kFinalizeIncrementalMarkingMask,
GarbageCollectionReason::kDebugger); GarbageCollectionReason::kDebugger);
...@@ -2314,14 +2307,6 @@ DebugScope::DebugScope(Debug* debug) ...@@ -2314,14 +2307,6 @@ DebugScope::DebugScope(Debug* debug)
DebugScope::~DebugScope() { DebugScope::~DebugScope() {
if (!failed_ && prev_ == NULL) {
// Clear mirror cache when leaving the debugger. Skip this if there is a
// pending exception as clearing the mirror cache calls back into
// JavaScript. This can happen if the v8::Debug::Call is used in which
// case the exception should end up in the calling code.
if (!isolate()->has_pending_exception()) debug_->ClearMirrorCache();
}
// Leaving this debugger entry. // Leaving this debugger entry.
base::NoBarrier_Store(&debug_->thread_local_.current_debug_scope_, base::NoBarrier_Store(&debug_->thread_local_.current_debug_scope_,
reinterpret_cast<base::AtomicWord>(prev_)); reinterpret_cast<base::AtomicWord>(prev_));
......
...@@ -501,9 +501,6 @@ class Debug { ...@@ -501,9 +501,6 @@ class Debug {
MUST_USE_RESULT MaybeHandle<Object> MakeAsyncTaskEvent(Handle<Smi> type, MUST_USE_RESULT MaybeHandle<Object> MakeAsyncTaskEvent(Handle<Smi> type,
Handle<Smi> id); Handle<Smi> id);
// Mirror cache handling.
void ClearMirrorCache();
void ProcessCompileEvent(v8::DebugEvent event, Handle<Script> script); void ProcessCompileEvent(v8::DebugEvent event, Handle<Script> script);
void ProcessDebugEvent(v8::DebugEvent event, Handle<JSObject> event_data); void ProcessDebugEvent(v8::DebugEvent event, Handle<JSObject> event_data);
......
...@@ -12,18 +12,11 @@ var FrameMirror = global.FrameMirror; ...@@ -12,18 +12,11 @@ var FrameMirror = global.FrameMirror;
var GlobalArray = global.Array; var GlobalArray = global.Array;
var GlobalRegExp = global.RegExp; var GlobalRegExp = global.RegExp;
var IsNaN = global.isNaN; var IsNaN = global.isNaN;
var LookupMirror = global.LookupMirror;
var MakeMirror = global.MakeMirror; var MakeMirror = global.MakeMirror;
var MathMin = global.Math.min; var MathMin = global.Math.min;
var Mirror = global.Mirror; var Mirror = global.Mirror;
var MirrorType;
var ParseInt = global.parseInt;
var ValueMirror = global.ValueMirror; var ValueMirror = global.ValueMirror;
utils.Import(function(from) {
MirrorType = from.MirrorType;
});
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// Default number of frames to include in the response to backtrace request. // Default number of frames to include in the response to backtrace request.
......
...@@ -77,59 +77,15 @@ var MirrorType = { ...@@ -77,59 +77,15 @@ var MirrorType = {
GENERATOR_TYPE : 'generator', GENERATOR_TYPE : 'generator',
} }
// Handle id counters.
var next_handle_ = 0;
var next_transient_handle_ = -1;
// Mirror cache.
var mirror_cache_ = [];
var mirror_cache_enabled_ = true;
function MirrorCacheIsEmpty() {
return next_handle_ == 0 && mirror_cache_.length == 0;
}
function ToggleMirrorCache(value) {
mirror_cache_enabled_ = value;
ClearMirrorCache();
}
function ClearMirrorCache(value) {
next_handle_ = 0;
mirror_cache_ = [];
}
/** /**
* Returns the mirror for a specified value or object. * Returns the mirror for a specified value or object.
* *
* @param {value or Object} value the value or object to retrieve the mirror for * @param {value or Object} value the value or object to retrieve the mirror for
* @param {boolean} transient indicate whether this object is transient and
* should not be added to the mirror cache. The default is not transient.
* @returns {Mirror} the mirror reflects the passed value or object * @returns {Mirror} the mirror reflects the passed value or object
*/ */
function MakeMirror(value, opt_transient) { function MakeMirror(value) {
var mirror; var mirror;
// Look for non transient mirrors in the mirror cache.
if (!opt_transient && mirror_cache_enabled_) {
for (var id in mirror_cache_) {
mirror = mirror_cache_[id];
if (mirror.value() === value) {
return mirror;
}
// Special check for NaN as NaN == NaN is false.
if (mirror.isNumber() && IsNaN(mirror.value()) &&
typeof value == 'number' && IsNaN(value)) {
return mirror;
}
}
}
if (IS_UNDEFINED(value)) { if (IS_UNDEFINED(value)) {
mirror = new UndefinedMirror(); mirror = new UndefinedMirror();
} else if (IS_NULL(value)) { } else if (IS_NULL(value)) {
...@@ -165,29 +121,13 @@ function MakeMirror(value, opt_transient) { ...@@ -165,29 +121,13 @@ function MakeMirror(value, opt_transient) {
} else if (IS_GENERATOR(value)) { } else if (IS_GENERATOR(value)) {
mirror = new GeneratorMirror(value); mirror = new GeneratorMirror(value);
} else { } else {
mirror = new ObjectMirror(value, MirrorType.OBJECT_TYPE, opt_transient); mirror = new ObjectMirror(value, MirrorType.OBJECT_TYPE);
} }
if (mirror_cache_enabled_) mirror_cache_[mirror.handle()] = mirror;
return mirror; return mirror;
} }
/**
* Returns the mirror for a specified mirror handle.
*
* @param {number} handle the handle to find the mirror for
* @returns {Mirror or undefiend} the mirror with the requested handle or
* undefined if no mirror with the requested handle was found
*/
function LookupMirror(handle) {
if (!mirror_cache_enabled_) {
throw %make_error(kDebugger, "Mirror cache is disabled");
}
return mirror_cache_[handle];
}
/** /**
* Returns the mirror for the undefined value. * Returns the mirror for the undefined value.
* *
...@@ -491,23 +431,6 @@ Mirror.prototype.isIterator = function() { ...@@ -491,23 +431,6 @@ Mirror.prototype.isIterator = function() {
}; };
/**
* Allocate a handle id for this object.
*/
Mirror.prototype.allocateHandle_ = function() {
if (mirror_cache_enabled_) this.handle_ = next_handle_++;
};
/**
* Allocate a transient handle id for this object. Transient handles are
* negative.
*/
Mirror.prototype.allocateTransientHandle_ = function() {
this.handle_ = next_transient_handle_--;
};
Mirror.prototype.toText = function() { Mirror.prototype.toText = function() {
// Simpel to text which is used when on specialization in subclass. // Simpel to text which is used when on specialization in subclass.
return "#<" + this.constructor.name + ">"; return "#<" + this.constructor.name + ">";
...@@ -518,28 +441,16 @@ Mirror.prototype.toText = function() { ...@@ -518,28 +441,16 @@ Mirror.prototype.toText = function() {
* Base class for all value mirror objects. * Base class for all value mirror objects.
* @param {string} type The type of the mirror * @param {string} type The type of the mirror
* @param {value} value The value reflected by this mirror * @param {value} value The value reflected by this mirror
* @param {boolean} transient indicate whether this object is transient with a
* transient handle
* @constructor * @constructor
* @extends Mirror * @extends Mirror
*/ */
function ValueMirror(type, value, transient) { function ValueMirror(type, value) {
%_Call(Mirror, this, type); %_Call(Mirror, this, type);
this.value_ = value; this.value_ = value;
if (!transient) {
this.allocateHandle_();
} else {
this.allocateTransientHandle_();
}
} }
inherits(ValueMirror, Mirror); inherits(ValueMirror, Mirror);
Mirror.prototype.handle = function() {
return this.handle_;
};
/** /**
* Check whether this is a primitive value. * Check whether this is a primitive value.
* @return {boolean} True if the mirror reflects a primitive value * @return {boolean} True if the mirror reflects a primitive value
...@@ -684,14 +595,12 @@ SymbolMirror.prototype.toText = function() { ...@@ -684,14 +595,12 @@ SymbolMirror.prototype.toText = function() {
/** /**
* Mirror object for objects. * Mirror object for objects.
* @param {object} value The object reflected by this mirror * @param {object} value The object reflected by this mirror
* @param {boolean} transient indicate whether this object is transient with a
* transient handle
* @constructor * @constructor
* @extends ValueMirror * @extends ValueMirror
*/ */
function ObjectMirror(value, type, transient) { function ObjectMirror(value, type) {
type = type || MirrorType.OBJECT_TYPE; type = type || MirrorType.OBJECT_TYPE;
%_Call(ValueMirror, this, type, value, transient); %_Call(ValueMirror, this, type, value);
} }
inherits(ObjectMirror, ValueMirror); inherits(ObjectMirror, ValueMirror);
...@@ -2313,13 +2222,10 @@ ScopeMirror.prototype.scopeType = function() { ...@@ -2313,13 +2222,10 @@ ScopeMirror.prototype.scopeType = function() {
ScopeMirror.prototype.scopeObject = function() { ScopeMirror.prototype.scopeObject = function() {
// For local, closure and script scopes create a transient mirror // For local, closure and script scopes create a mirror
// as these objects are created on the fly materializing the local // as these objects are created on the fly materializing the local
// or closure scopes and therefore will not preserve identity. // or closure scopes and therefore will not preserve identity.
var transient = this.scopeType() == ScopeType.Local || return MakeMirror(this.details_.object());
this.scopeType() == ScopeType.Closure ||
this.scopeType() == ScopeType.Script;
return MakeMirror(this.details_.object(), transient);
}; };
...@@ -2338,7 +2244,6 @@ function ScriptMirror(script) { ...@@ -2338,7 +2244,6 @@ function ScriptMirror(script) {
%_Call(Mirror, this, MirrorType.SCRIPT_TYPE); %_Call(Mirror, this, MirrorType.SCRIPT_TYPE);
this.script_ = script; this.script_ = script;
this.context_ = new ContextMirror(script.context_data); this.context_ = new ContextMirror(script.context_data);
this.allocateHandle_();
} }
inherits(ScriptMirror, Mirror); inherits(ScriptMirror, Mirror);
...@@ -2454,7 +2359,6 @@ ScriptMirror.prototype.toText = function() { ...@@ -2454,7 +2359,6 @@ ScriptMirror.prototype.toText = function() {
function ContextMirror(data) { function ContextMirror(data) {
%_Call(Mirror, this, MirrorType.CONTEXT_TYPE); %_Call(Mirror, this, MirrorType.CONTEXT_TYPE);
this.data_ = data; this.data_ = data;
this.allocateHandle_();
} }
inherits(ContextMirror, Mirror); inherits(ContextMirror, Mirror);
...@@ -2468,9 +2372,6 @@ ContextMirror.prototype.data = function() { ...@@ -2468,9 +2372,6 @@ ContextMirror.prototype.data = function() {
utils.InstallFunctions(global, DONT_ENUM, [ utils.InstallFunctions(global, DONT_ENUM, [
"MakeMirror", MakeMirror, "MakeMirror", MakeMirror,
"LookupMirror", LookupMirror,
"ToggleMirrorCache", ToggleMirrorCache,
"MirrorCacheIsEmpty", MirrorCacheIsEmpty,
]); ]);
utils.InstallConstants(global, [ utils.InstallConstants(global, [
...@@ -2505,13 +2406,4 @@ utils.InstallConstants(global, [ ...@@ -2505,13 +2406,4 @@ utils.InstallConstants(global, [
"FrameDetails", FrameDetails, "FrameDetails", FrameDetails,
]); ]);
// Functions needed by the debugger runtime.
utils.InstallFunctions(utils, DONT_ENUM, [
"ClearMirrorCache", ClearMirrorCache
]);
// Export to debug.js
utils.Export(function(to) {
to.MirrorType = MirrorType;
});
}) })
...@@ -107,7 +107,7 @@ DebuggerScript.getGeneratorScopes = function(gen) ...@@ -107,7 +107,7 @@ DebuggerScript.getGeneratorScopes = function(gen)
*/ */
DebuggerScript.getGeneratorObjectLocation = function(object) DebuggerScript.getGeneratorObjectLocation = function(object)
{ {
var mirror = MakeMirror(object, true /* transient */); var mirror = MakeMirror(object);
if (!mirror.isGenerator()) if (!mirror.isGenerator())
return null; return null;
var generatorMirror = /** @type {!GeneratorMirror} */(mirror); var generatorMirror = /** @type {!GeneratorMirror} */(mirror);
...@@ -132,7 +132,7 @@ DebuggerScript.getGeneratorObjectLocation = function(object) ...@@ -132,7 +132,7 @@ DebuggerScript.getGeneratorObjectLocation = function(object)
*/ */
DebuggerScript.getCollectionEntries = function(object) DebuggerScript.getCollectionEntries = function(object)
{ {
var mirror = MakeMirror(object, true /* transient */); var mirror = MakeMirror(object);
if (mirror.isMap()) if (mirror.isMap())
return /** @type {!MapMirror} */(mirror).entries(); return /** @type {!MapMirror} */(mirror).entries();
if (mirror.isSet() || mirror.isIterator()) { if (mirror.isSet() || mirror.isIterator()) {
...@@ -548,7 +548,7 @@ DebuggerScript._buildScopeObject = function(scopeType, scopeObject) ...@@ -548,7 +548,7 @@ DebuggerScript._buildScopeObject = function(scopeType, scopeObject)
// the same properties. // the same properties.
// Reset scope object prototype to null so that the proto properties // Reset scope object prototype to null so that the proto properties
// don't appear in the local scope section. // don't appear in the local scope section.
var properties = /** @type {!ObjectMirror} */(MakeMirror(scopeObject, true /* transient */)).properties(); var properties = /** @type {!ObjectMirror} */(MakeMirror(scopeObject)).properties();
// Almost always Script scope will be empty, so just filter out that noise. // Almost always Script scope will be empty, so just filter out that noise.
// Also drop empty Block, Eval and Script scopes, should we get any. // Also drop empty Block, Eval and Script scopes, should we get any.
if (!properties.length && (scopeType === ScopeType.Script || if (!properties.length && (scopeType === ScopeType.Script ||
...@@ -573,8 +573,5 @@ DebuggerScript._buildScopeObject = function(scopeType, scopeObject) ...@@ -573,8 +573,5 @@ DebuggerScript._buildScopeObject = function(scopeType, scopeObject)
return result; return result;
} }
// We never resolve Mirror by its handle so to avoid memory leaks caused by Mirrors in the cache we disable it.
ToggleMirrorCache(false);
return DebuggerScript; return DebuggerScript;
})(); })();
...@@ -238,16 +238,11 @@ FrameDetails.prototype.returnValue = function() {} ...@@ -238,16 +238,11 @@ FrameDetails.prototype.returnValue = function() {}
/** @return {number} */ /** @return {number} */
FrameDetails.prototype.scopeCount = function() {} FrameDetails.prototype.scopeCount = function() {}
/** @param {boolean} value */
function ToggleMirrorCache(value) {}
/** /**
* @param {*} value * @param {*} value
* @param {boolean=} transient
* @return {!Mirror} * @return {!Mirror}
*/ */
function MakeMirror(value, transient) {} function MakeMirror(value) {}
/** @interface */ /** @interface */
......
...@@ -4422,7 +4422,7 @@ TEST(HiddenPrototypePropertyMirror) { ...@@ -4422,7 +4422,7 @@ TEST(HiddenPrototypePropertyMirror) {
.FromJust()); .FromJust());
// The prototype (__proto__) for o0 should be o3 as o1 and o2 are hidden. // The prototype (__proto__) for o0 should be o3 as o1 and o2 are hidden.
CHECK(CompileRun("o0_mirror.protoObject() == o3_mirror") CHECK(CompileRun("o0_mirror.protoObject().value() == o3_mirror.value()")
->BooleanValue(context) ->BooleanValue(context)
.FromJust()); .FromJust());
} }
......
...@@ -1238,7 +1238,6 @@ gc(); ...@@ -1238,7 +1238,6 @@ gc();
"use asm"; "use asm";
var __v_9 = new stdlib.Float32Array(heap); var __v_9 = new stdlib.Float32Array(heap);
var __v_13 = stdlib.Math.fround; var __v_13 = stdlib.Math.fround;
assertEquals("number", debug.LookupMirror(__v_112).type());
function __f_73() { function __f_73() {
var __v_23 = __v_13(1.0); var __v_23 = __v_13(1.0);
var __v_25 = __v_13(2.0); var __v_25 = __v_13(2.0);
...@@ -1433,38 +1432,3 @@ gc(); ...@@ -1433,38 +1432,3 @@ gc();
assertEquals(0x87654321, __v_30.__f_50()); assertEquals(0x87654321, __v_30.__f_50());
})(); })();
} catch(e) { print("Caught: " + e); } } catch(e) { print("Caught: " + e); }
try {
var __v_112 = debug.MakeMirror(123).handle();
assertEquals("number", debug.LookupMirror(__v_112).type());
debug.ToggleMirrorCache(false);
var __v_114 = debug.MakeMirror(123).handle();
gc();
assertEquals(undefined, __v_114);
assertThrows(function() { debug.LookupMirror(__v_114) });
debug.ToggleMirrorCache(true);
var __v_113 = debug.MakeMirror(123).handle();
assertEquals("number", debug.LookupMirror(__v_113).type());
} catch(e) { print("Caught: " + e); }
try {
var Debug = debug.Debug;
var __v_25 = null;
var __v_113 = true;
} catch(e) { print("Caught: " + e); }
function __f_112(event, exec_state, event_data, data) {
if (event != Debug.DebugEvent.Break) return;
try {
assertTrue(exec_state.frame(0).sourceLineText().indexOf("BREAK") > 0);
} catch (e) {
__v_0 = e;
}
}
function __f_113() {
return 1;
}
try {
Debug.setListener(__f_112);
nop();
__f_113();
Debug.setListener(null);
assertNull(__v_112);
} catch(e) { print("Caught: " + e); }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment