Debugger: use a Map to cache mirrors.
authoryangguo <yangguo@chromium.org>
Thu, 13 Aug 2015 10:49:04 +0000 (03:49 -0700)
committerCommit bot <commit-bot@chromium.org>
Thu, 13 Aug 2015 10:49:20 +0000 (10:49 +0000)
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}

src/bootstrapper.cc
src/debug/mirrors.js

index 5fee783..1952e02 100644 (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();
 }
 
index 85ff2b2..31387ab 100644 (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;
 }