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.