Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(200)

Unified Diff: src/object-observe.js

Issue 19132002: [Object.observe] Lazily allocate callbackInfo structure (Closed) Base URL: https://github.com/v8/v8.git@bleeding_edge
Patch Set: cr comments Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | test/cctest/test-object-observe.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/object-observe.js
diff --git a/src/object-observe.js b/src/object-observe.js
index 90c9a699e0569281ca3d415f880e04c21423600e..1c147d95e30f9e82d45797d500b2d32bb198b064 100644
--- a/src/object-observe.js
+++ b/src/object-observe.js
@@ -28,12 +28,12 @@
"use strict";
var observationState = %GetObservationState();
-if (IS_UNDEFINED(observationState.observerInfoMap)) {
- observationState.observerInfoMap = %ObservationWeakMapCreate();
+if (IS_UNDEFINED(observationState.callbackInfoMap)) {
+ observationState.callbackInfoMap = %ObservationWeakMapCreate();
observationState.objectInfoMap = %ObservationWeakMapCreate();
observationState.notifierTargetMap = %ObservationWeakMapCreate();
observationState.pendingObservers = new InternalArray;
- observationState.observerPriority = 0;
+ observationState.nextCallbackPriority = 0;
}
function ObservationWeakMap(map) {
@@ -56,8 +56,8 @@ ObservationWeakMap.prototype = {
}
};
-var observerInfoMap =
- new ObservationWeakMap(observationState.observerInfoMap);
+var callbackInfoMap =
+ new ObservationWeakMap(observationState.callbackInfoMap);
var objectInfoMap = new ObservationWeakMap(observationState.objectInfoMap);
var notifierTargetMap =
new ObservationWeakMap(observationState.notifierTargetMap);
@@ -198,6 +198,22 @@ function AcceptArgIsValid(arg) {
return true;
}
+function EnsureCallbackPriority(callback) {
+ if (!callbackInfoMap.has(callback))
+ callbackInfoMap.set(callback, observationState.nextCallbackPriority++);
+}
+
+function NormalizeCallbackInfo(callback) {
+ var callbackInfo = callbackInfoMap.get(callback);
+ if (IS_NUMBER(callbackInfo)) {
+ var priority = callbackInfo;
+ callbackInfo = new InternalArray;
+ callbackInfo.priority = priority;
+ callbackInfoMap.set(callback, callbackInfo);
+ }
+ return callbackInfo;
+}
+
function ObjectObserve(object, callback, accept) {
if (!IS_SPEC_OBJECT(object))
throw MakeTypeError("observe_non_object", ["observe"]);
@@ -208,12 +224,7 @@ function ObjectObserve(object, callback, accept) {
if (!AcceptArgIsValid(accept))
throw MakeTypeError("observe_accept_invalid");
- if (!observerInfoMap.has(callback)) {
- observerInfoMap.set(callback, {
- pendingChangeRecords: null,
- priority: observationState.observerPriority++,
- });
- }
+ EnsureCallbackPriority(callback);
var objectInfo = objectInfoMap.get(object);
if (IS_UNDEFINED(objectInfo)) {
@@ -257,6 +268,13 @@ function ArrayUnobserve(object, callback) {
return ObjectUnobserve(object, callback);
}
+function EnqueueToCallback(callback, changeRecord) {
+ var callbackInfo = NormalizeCallbackInfo(callback);
+ observationState.pendingObservers[callbackInfo.priority] = callback;
+ callbackInfo.push(changeRecord);
+ %SetObserverDeliveryPending();
+}
+
function EnqueueChangeRecord(changeRecord, observers) {
// TODO(rossberg): adjust once there is a story for symbols vs proxies.
if (IS_SYMBOL(changeRecord.name)) return;
@@ -266,15 +284,7 @@ function EnqueueChangeRecord(changeRecord, observers) {
if (IS_UNDEFINED(observer.accept[changeRecord.type]))
continue;
- var callback = observer.callback;
- var observerInfo = observerInfoMap.get(callback);
- observationState.pendingObservers[observerInfo.priority] = callback;
- %SetObserverDeliveryPending();
- if (IS_NULL(observerInfo.pendingChangeRecords)) {
- observerInfo.pendingChangeRecords = new InternalArray(changeRecord);
- } else {
- observerInfo.pendingChangeRecords.push(changeRecord);
- }
+ EnqueueToCallback(observer.callback, changeRecord);
}
}
@@ -394,21 +404,22 @@ function ObjectGetNotifier(object) {
return objectInfo.notifier;
}
-function DeliverChangeRecordsForObserver(observer) {
- var observerInfo = observerInfoMap.get(observer);
- if (IS_UNDEFINED(observerInfo))
+function CallbackDeliverPending(callback) {
+ var callbackInfo = callbackInfoMap.get(callback);
+ if (IS_UNDEFINED(callbackInfo) || IS_NUMBER(callbackInfo))
return false;
- var pendingChangeRecords = observerInfo.pendingChangeRecords;
- if (IS_NULL(pendingChangeRecords))
- return false;
+ // Clear the pending change records from callback and return it to its
+ // "optimized" state.
+ var priority = callbackInfo.priority;
+ callbackInfoMap.set(callback, priority);
- observerInfo.pendingChangeRecords = null;
- delete observationState.pendingObservers[observerInfo.priority];
+ delete observationState.pendingObservers[priority];
var delivered = [];
- %MoveArrayContents(pendingChangeRecords, delivered);
+ %MoveArrayContents(callbackInfo, delivered);
+
try {
- %Call(void 0, delivered, observer);
+ %Call(void 0, delivered, callback);
} catch (ex) {}
return true;
}
@@ -417,7 +428,7 @@ function ObjectDeliverChangeRecords(callback) {
if (!IS_SPEC_FUNCTION(callback))
throw MakeTypeError("observe_non_function", ["deliverChangeRecords"]);
- while (DeliverChangeRecordsForObserver(callback)) {}
+ while (CallbackDeliverPending(callback)) {}
}
function DeliverChangeRecords() {
@@ -425,7 +436,7 @@ function DeliverChangeRecords() {
var pendingObservers = observationState.pendingObservers;
observationState.pendingObservers = new InternalArray;
for (var i in pendingObservers) {
- DeliverChangeRecordsForObserver(pendingObservers[i]);
+ CallbackDeliverPending(pendingObservers[i]);
}
}
}
« no previous file with comments | « no previous file | test/cctest/test-object-observe.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698