Debugger: use a Map to cache mirrors.

This makes mirror cache lookup O(1) instead of O(n).
The downside is that the lookup via handle is O(n). This
is fine because handles are only used in the JSON api,
which is not used by Chrome and on death row.

Review URL: https://codereview.chromium.org/1287243002

Cr-Commit-Position: refs/heads/master@{#30150}
This commit is contained in:
yangguo 2015-08-13 03:49:04 -07:00 committed by Commit bot
parent f9a3e6a6aa
commit 890b1dfca8
2 changed files with 21 additions and 28 deletions

View File

@ -1802,6 +1802,9 @@ Data* SetBuiltinTypedArray(Isolate* isolate, Handle<JSBuiltinsObject> builtins,
void Genesis::InitializeBuiltinTypedArrays() {
// The serializer cannot serialize typed arrays. Reset those typed arrays
// for each new context.
DCHECK(!isolate()->serializer_enabled());
Handle<JSBuiltinsObject> builtins(native_context()->builtins());
{ // Initially seed the per-context random number generator using the
// per-isolate random number generator.
@ -3230,25 +3233,21 @@ Genesis::Genesis(Isolate* isolate,
// Install experimental and extra natives. Do not include them into the
// snapshot as we should be able to turn them off at runtime. Re-installing
// them after they have already been deserialized would also fail.
if (context_type == FULL_CONTEXT) {
if (!isolate->serializer_enabled()) {
InitializeExperimentalGlobal();
if (!isolate->serializer_enabled() && context_type != THIN_CONTEXT) {
InitializeExperimentalGlobal();
InitializeBuiltinTypedArrays();
if (context_type == FULL_CONTEXT) {
if (!InstallExperimentalNatives()) return;
if (!InstallExtraNatives()) return;
// By now the utils object is useless and can be removed.
native_context()->set_natives_utils_object(
isolate->heap()->undefined_value());
InitializeBuiltinTypedArrays();
} else {
DCHECK_EQ(DEBUG_CONTEXT, context_type);
if (!InstallDebuggerNatives()) return;
}
// The serializer cannot serialize typed arrays. Reset those typed arrays
// for each new context.
InitializeBuiltinTypedArrays();
} else if (context_type == DEBUG_CONTEXT) {
DCHECK(!isolate->serializer_enabled());
InitializeExperimentalGlobal();
if (!InstallDebuggerNatives()) return;
}
result_ = native_context();
}

View File

@ -11,6 +11,7 @@
var GlobalArray = global.Array;
var IsNaN = global.isNaN;
var JSONStringify = global.JSON.stringify;
var GlobalMap = global.Map;
var MathMin = global.Math.min;
// ----------------------------------------------------------------------------
@ -73,12 +74,12 @@ var next_handle_ = 0;
var next_transient_handle_ = -1;
// Mirror cache.
var mirror_cache_ = [];
var mirror_cache_ = new GlobalMap();
var mirror_cache_enabled_ = true;
function MirrorCacheIsEmpty() {
return next_handle_ == 0 && mirror_cache_.length == 0;
return mirror_cache_.size === 0;
}
@ -90,7 +91,7 @@ function ToggleMirrorCache(value) {
function ClearMirrorCache(value) {
next_handle_ = 0;
mirror_cache_ = [];
mirror_cache_.clear();
}
@ -120,17 +121,7 @@ function MakeMirror(value, opt_transient) {
// 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 (mirror_cache_.has(value)) return mirror_cache_.get(value);
}
if (IS_UNDEFINED(value)) {
@ -171,7 +162,7 @@ function MakeMirror(value, opt_transient) {
mirror = new ObjectMirror(value, MirrorType.OBJECT_TYPE, opt_transient);
}
if (mirror_cache_enabled_) mirror_cache_[mirror.handle()] = mirror;
if (mirror_cache_enabled_) mirror_cache_.set(value, mirror);
return mirror;
}
@ -187,7 +178,10 @@ function LookupMirror(handle) {
if (!mirror_cache_enabled_) {
throw MakeError(kDebugger, "Mirror cache is disabled");
}
return mirror_cache_[handle];
for (var value of mirror_cache_.values()) {
if (value.handle() == handle) return value;
}
return UNDEFINED;
}