Various cleanup/simplification in object-observe.js
authoradamk@chromium.org <adamk@chromium.org>
Wed, 29 Oct 2014 10:32:24 +0000 (10:32 +0000)
committeradamk@chromium.org <adamk@chromium.org>
Wed, 29 Oct 2014 10:32:39 +0000 (10:32 +0000)
The biggest change is the removal of the map wrapper objects: we now operate
directly on the observation weak map, since there are already Get/GetOrCreate/Set
functions for each info map. Various other small cleanups as well, including the
deletion of unnecessary forwarding functions and making use of standard macros.

R=arv@chromium.org, rossberg@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#24972}
git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24972 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/object-observe.js

index b598e685b436a40c80c5b540666dff770aed6caf..3f9af641f882e5a540f49f24c31147e49bf1de37 100644 (file)
 // implementation of (1) and (2) have "optimized" states which represent
 // common cases which can be handled more efficiently.
 
-var observationState;
-
-function GetObservationStateJS() {
-  if (IS_UNDEFINED(observationState))
-    observationState = %GetObservationState();
-
-  if (IS_UNDEFINED(observationState.callbackInfoMap)) {
-    observationState.callbackInfoMap = %ObservationWeakMapCreate();
-    observationState.objectInfoMap = %ObservationWeakMapCreate();
-    observationState.notifierObjectInfoMap = %ObservationWeakMapCreate();
-    observationState.pendingObservers = null;
-    observationState.nextCallbackPriority = 0;
-    observationState.lastMicrotaskId = 0;
-  }
-
-  return observationState;
-}
-
-function GetWeakMapWrapper() {
-  function MapWrapper(map) {
-    this.map_ = map;
-  };
-
-  MapWrapper.prototype = {
-    __proto__: null,
-    get: function(key) {
-      return %WeakCollectionGet(this.map_, key);
-    },
-    set: function(key, value) {
-      %WeakCollectionSet(this.map_, key, value);
-    },
-    has: function(key) {
-      return !IS_UNDEFINED(this.get(key));
-    }
-  };
-
-  return MapWrapper;
-}
-
-var contextMaps;
-
-function GetContextMaps() {
-  if (IS_UNDEFINED(contextMaps)) {
-    var map = GetWeakMapWrapper();
-    var observationState = GetObservationStateJS();
-    contextMaps = {
-      callbackInfoMap: new map(observationState.callbackInfoMap),
-      objectInfoMap: new map(observationState.objectInfoMap),
-      notifierObjectInfoMap: new map(observationState.notifierObjectInfoMap)
-    };
-  }
+var observationState = %GetObservationState();
 
-  return contextMaps;
-}
-
-function GetCallbackInfoMap() {
-  return GetContextMaps().callbackInfoMap;
-}
-
-function GetObjectInfoMap() {
-  return GetContextMaps().objectInfoMap;
-}
-
-function GetNotifierObjectInfoMap() {
-  return GetContextMaps().notifierObjectInfoMap;
+// This is run during the first context creation in an isolate.
+if (IS_UNDEFINED(observationState.callbackInfoMap)) {
+  observationState.callbackInfoMap = %ObservationWeakMapCreate();
+  observationState.objectInfoMap = %ObservationWeakMapCreate();
+  observationState.notifierObjectInfoMap = %ObservationWeakMapCreate();
+  observationState.pendingObservers = null;
+  observationState.nextCallbackPriority = 0;
+  observationState.lastMicrotaskId = 0;
 }
 
 function GetPendingObservers() {
-  return GetObservationStateJS().pendingObservers;
+  return observationState.pendingObservers;
 }
 
 function SetPendingObservers(pendingObservers) {
-  GetObservationStateJS().pendingObservers = pendingObservers;
+  observationState.pendingObservers = pendingObservers;
 }
 
 function GetNextCallbackPriority() {
-  return GetObservationStateJS().nextCallbackPriority++;
+  return observationState.nextCallbackPriority++;
 }
 
 function nullProtoObject() {
@@ -204,35 +149,32 @@ function ObjectInfoGetOrCreate(object) {
       performing: null,
       performingCount: 0,
     };
-    GetObjectInfoMap().set(object, objectInfo);
+    %WeakCollectionSet(observationState.objectInfoMap, object, objectInfo);
   }
   return objectInfo;
 }
 
 function ObjectInfoGet(object) {
-  return GetObjectInfoMap().get(object);
+  return %WeakCollectionGet(observationState.objectInfoMap, object);
 }
 
 function ObjectInfoGetFromNotifier(notifier) {
-  return GetNotifierObjectInfoMap().get(notifier);
+  return %WeakCollectionGet(observationState.notifierObjectInfoMap, notifier);
 }
 
 function ObjectInfoGetNotifier(objectInfo) {
   if (IS_NULL(objectInfo.notifier)) {
     objectInfo.notifier = { __proto__: notifierPrototype };
-    GetNotifierObjectInfoMap().set(objectInfo.notifier, objectInfo);
+    %WeakCollectionSet(observationState.notifierObjectInfoMap,
+                       objectInfo.notifier, objectInfo);
   }
 
   return objectInfo.notifier;
 }
 
-function ObjectInfoGetObject(objectInfo) {
-  return objectInfo.object;
-}
-
 function ChangeObserversIsOptimized(changeObservers) {
-  return typeof changeObservers === 'function' ||
-         typeof changeObservers.callback === 'function';
+  return IS_SPEC_FUNCTION(changeObservers) ||
+         IS_SPEC_FUNCTION(changeObservers.callback);
 }
 
 // The set of observers on an object is called 'changeObservers'. The first
@@ -328,16 +270,20 @@ function ConvertAcceptListToTypeMap(arg) {
 // priority. When a change record must be enqueued for the callback, it
 // normalizes. When delivery clears any pending change records, it re-optimizes.
 function CallbackInfoGet(callback) {
-  return GetCallbackInfoMap().get(callback);
+  return %WeakCollectionGet(observationState.callbackInfoMap, callback);
+}
+
+function CallbackInfoSet(callback, callbackInfo) {
+  %WeakCollectionSet(observationState.callbackInfoMap, callback, callbackInfo);
 }
 
 function CallbackInfoGetOrCreate(callback) {
-  var callbackInfo = GetCallbackInfoMap().get(callback);
+  var callbackInfo = CallbackInfoGet(callback);
   if (!IS_UNDEFINED(callbackInfo))
     return callbackInfo;
 
-  var priority =  GetNextCallbackPriority();
-  GetCallbackInfoMap().set(callback, priority);
+  var priority = GetNextCallbackPriority();
+  CallbackInfoSet(callback, priority);
   return priority;
 }
 
@@ -349,12 +295,12 @@ function CallbackInfoGetPriority(callbackInfo) {
 }
 
 function CallbackInfoNormalize(callback) {
-  var callbackInfo = GetCallbackInfoMap().get(callback);
+  var callbackInfo = CallbackInfoGet(callback);
   if (IS_NUMBER(callbackInfo)) {
     var priority = callbackInfo;
     callbackInfo = new InternalArray;
     callbackInfo.priority = priority;
-    GetCallbackInfoMap().set(callback, callbackInfo);
+    CallbackInfoSet(callback, callbackInfo);
   }
   return callbackInfo;
 }
@@ -423,7 +369,7 @@ function ObserverEnqueueIfActive(observer, objectInfo, changeRecord) {
   if (IS_NULL(GetPendingObservers())) {
     SetPendingObservers(nullProtoObject());
     if (DEBUG_IS_ACTIVE) {
-      var id = ++GetObservationStateJS().lastMicrotaskId;
+      var id = ++observationState.lastMicrotaskId;
       var name = "Object.observe";
       %EnqueueMicrotask(function() {
         %DebugAsyncTaskEvent({ type: "willHandle", id: id, name: name });
@@ -445,8 +391,8 @@ function ObjectInfoEnqueueExternalChangeRecord(objectInfo, changeRecord, type) {
 
   var hasType = !IS_UNDEFINED(type);
   var newRecord = hasType ?
-      { object: ObjectInfoGetObject(objectInfo), type: type } :
-      { object: ObjectInfoGetObject(objectInfo) };
+      { object: objectInfo.object, type: type } :
+      { object: objectInfo.object };
 
   for (var prop in changeRecord) {
     if (prop === 'object' || (hasType && prop === 'type')) continue;
@@ -594,17 +540,18 @@ function NativeObjectGetNotifier(object) {
 }
 
 function CallbackDeliverPending(callback) {
-  var callbackInfo = GetCallbackInfoMap().get(callback);
+  var callbackInfo = CallbackInfoGet(callback);
   if (IS_UNDEFINED(callbackInfo) || IS_NUMBER(callbackInfo))
     return false;
 
   // Clear the pending change records from callback and return it to its
   // "optimized" state.
   var priority = callbackInfo.priority;
-  GetCallbackInfoMap().set(callback, priority);
+  CallbackInfoSet(callback, priority);
 
-  if (GetPendingObservers())
-    delete GetPendingObservers()[priority];
+  var pendingObservers = GetPendingObservers();
+  if (!IS_NULL(pendingObservers))
+    delete pendingObservers[priority];
 
   var delivered = [];
   %MoveArrayContents(callbackInfo, delivered);
@@ -624,7 +571,7 @@ function ObjectDeliverChangeRecords(callback) {
 
 function ObserveMicrotaskRunner() {
   var pendingObservers = GetPendingObservers();
-  if (pendingObservers) {
+  if (!IS_NULL(pendingObservers)) {
     SetPendingObservers(null);
     for (var i in pendingObservers) {
       CallbackDeliverPending(pendingObservers[i]);