Revision: 18501
Author:   [email protected]
Date:     Wed Jan  8 20:25:08 2014 UTC
Log:      Minor Object.observe optimizations

This patch includes the follow two minor optimizations:

1) When Object.unobserve-ing, instead of deleting from changeObservers, set the index position to null, and null-check when iterating elsewhere
2) Isolate creation of null-proto objects inside a utility function

These former (deleting) was clearly showing up in d8 --prof traces and the later was preventing optimization of containing functions because of non-standard literal. Combined, on MDV construction/teardown benchmark, saves about 10%.

Note that this patch also cleans up retrieving objectInfo inside a utility function.

[email protected], rossberg
BUG=

Review URL: https://codereview.chromium.org/123523002
http://code.google.com/p/v8/source/detail?r=18501

Modified:
 /branches/bleeding_edge/src/object-observe.js

=======================================
--- /branches/bleeding_edge/src/object-observe.js Wed Nov 27 17:21:40 2013 UTC +++ /branches/bleeding_edge/src/object-observe.js Wed Jan 8 20:25:08 2014 UTC
@@ -91,9 +91,13 @@
 var notifierObjectInfoMap =
     new ObservationWeakMap(observationState.notifierObjectInfoMap);

-function TypeMapCreate() {
+function nullProtoObject() {
   return { __proto__: null };
 }
+
+function TypeMapCreate() {
+  return nullProtoObject();
+}

 function TypeMapAddType(typeMap, type, ignoreDuplicate) {
   typeMap[type] = ignoreDuplicate ? 1 : (typeMap[type] || 0) + 1;
@@ -142,11 +146,12 @@
// to the callback. An observer never changes its accept types and thus never
 // needs to "normalize".
 function ObserverCreate(callback, acceptList) {
-  return IS_UNDEFINED(acceptList) ? callback : {
-    __proto__: null,
-    callback: callback,
-    accept: TypeMapCreateFromList(acceptList)
-  };
+  if (IS_UNDEFINED(acceptList))
+    return callback;
+  var observer = nullProtoObject();
+  observer.callback = callback;
+  observer.accept = TypeMapCreateFromList(acceptList);
+  return observer;
 }

 function ObserverGetCallback(observer) {
@@ -162,8 +167,8 @@
                                ObserverGetAcceptTypes(observer));
 }

-function ObjectInfoGet(object) {
-  var objectInfo = objectInfoMap.get(object);
+function ObjectInfoGetOrCreate(object) {
+  var objectInfo = ObjectInfoGet(object);
   if (IS_UNDEFINED(objectInfo)) {
     if (!%IsJSProxy(object))
       %SetIsObserved(object);
@@ -179,6 +184,10 @@
   }
   return objectInfo;
 }
+
+function ObjectInfoGet(object) {
+  return objectInfoMap.get(object);
+}

 function ObjectInfoGetFromNotifier(notifier) {
   return notifierObjectInfoMap.get(notifier);
@@ -212,7 +221,7 @@
     var callback = ObserverGetCallback(observer);
     var callbackInfo = CallbackInfoGet(callback);
     var priority = CallbackInfoGetPriority(callbackInfo);
-    objectInfo.changeObservers = { __proto__: null };
+    objectInfo.changeObservers = nullProtoObject();
     objectInfo.changeObservers[priority] = observer;
   }
 }
@@ -243,7 +252,7 @@

   var callbackInfo = CallbackInfoGet(callback);
   var priority = CallbackInfoGetPriority(callbackInfo);
-  delete objectInfo.changeObservers[priority];
+  objectInfo.changeObservers[priority] = null;
 }

 function ObjectInfoHasActiveObservers(objectInfo) {
@@ -254,7 +263,8 @@
     return ObserverIsActive(objectInfo.changeObservers, objectInfo);

   for (var priority in objectInfo.changeObservers) {
-    if (ObserverIsActive(objectInfo.changeObservers[priority], objectInfo))
+    var observer = objectInfo.changeObservers[priority];
+    if (!IS_NULL(observer) && ObserverIsActive(observer, objectInfo))
       return true;
   }

@@ -333,7 +343,7 @@
   if (!AcceptArgIsValid(acceptList))
     throw MakeTypeError("observe_accept_invalid");

-  var objectInfo = ObjectInfoGet(object);
+  var objectInfo = ObjectInfoGetOrCreate(object);
   ObjectInfoAddObserver(objectInfo, callback, acceptList);
   return object;
 }
@@ -344,7 +354,7 @@
   if (!IS_SPEC_FUNCTION(callback))
     throw MakeTypeError("observe_non_function", ["unobserve"]);

-  var objectInfo = objectInfoMap.get(object);
+  var objectInfo = ObjectInfoGet(object);
   if (IS_UNDEFINED(objectInfo))
     return object;

@@ -381,7 +391,7 @@

   var callbackInfo = CallbackInfoNormalize(callback);
   if (!observationState.pendingObservers)
-    observationState.pendingObservers = { __proto__: null };
+    observationState.pendingObservers = nullProtoObject();
   observationState.pendingObservers[callbackInfo.priority] = callback;
   callbackInfo.push(changeRecord);
   %SetMicrotaskPending(true);
@@ -424,25 +434,27 @@

   for (var priority in objectInfo.changeObservers) {
     var observer = objectInfo.changeObservers[priority];
+    if (IS_NULL(observer))
+      continue;
     ObserverEnqueueIfActive(observer, objectInfo, changeRecord,
                             needsAccessCheck);
   }
 }

 function BeginPerformSplice(array) {
-  var objectInfo = objectInfoMap.get(array);
+  var objectInfo = ObjectInfoGet(array);
   if (!IS_UNDEFINED(objectInfo))
     ObjectInfoAddPerformingType(objectInfo, 'splice');
 }

 function EndPerformSplice(array) {
-  var objectInfo = objectInfoMap.get(array);
+  var objectInfo = ObjectInfoGet(array);
   if (!IS_UNDEFINED(objectInfo))
     ObjectInfoRemovePerformingType(objectInfo, 'splice');
 }

 function EnqueueSpliceRecord(array, index, removed, addedCount) {
-  var objectInfo = objectInfoMap.get(array);
+  var objectInfo = ObjectInfoGet(array);
   if (!ObjectInfoHasActiveObservers(objectInfo))
     return;

@@ -460,7 +472,7 @@
 }

 function NotifyChange(type, object, name, oldValue) {
-  var objectInfo = objectInfoMap.get(object);
+  var objectInfo = ObjectInfoGet(object);
   if (!ObjectInfoHasActiveObservers(objectInfo))
     return;

@@ -529,7 +541,7 @@

   if (ObjectIsFrozen(object)) return null;

-  var objectInfo = ObjectInfoGet(object);
+  var objectInfo = ObjectInfoGetOrCreate(object);
   return ObjectInfoGetNotifier(objectInfo);
 }

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to