Reviewers: rossberg,

Description:
Object.deliverChangeRecords should remove the observer from activeObservers

To preserve ordering guarantees during end-of-turn delivery,
Object.deliverChangeRecords needs to remove the delivered-to observer from the
list of active observers.

The added test demonstrates this behavior.


Please review this at https://codereview.chromium.org/11410046/

SVN Base: http://v8.googlecode.com/svn/branches/bleeding_edge

Affected files:
  M src/object-observe.js
  M test/cctest/test-object-observe.cc


Index: src/object-observe.js
diff --git a/src/object-observe.js b/src/object-observe.js
index 28aa1f4e4e988caf624efcfd72df9c5d83325e30..a2c837368315c5f1ea3ee186aa03e8b92b5ea83f 100644
--- a/src/object-observe.js
+++ b/src/object-observe.js
@@ -200,6 +200,7 @@ function DeliverChangeRecordsForObserver(observer) {
     return;

   observerInfo.pendingChangeRecords = null;
+  delete observationState.activeObservers[observerInfo.priority];
   var delivered = [];
   %MoveArrayContents(pendingChangeRecords, delivered);
   try {
Index: test/cctest/test-object-observe.cc
diff --git a/test/cctest/test-object-observe.cc b/test/cctest/test-object-observe.cc index 374dca43474cbe701855749e96cac8cdee53b683..9decf1768f30904c1a9c5f03cdd977e39af68c62 100644
--- a/test/cctest/test-object-observe.cc
+++ b/test/cctest/test-object-observe.cc
@@ -166,6 +166,30 @@ TEST(DeliveryOrderingReentrant) {
   CHECK_EQ(2, CompileRun("ordering[1]")->Int32Value());
 }

+TEST(DeliveryOrderingDeliverChangeRecords) {
+  HarmonyIsolate isolate;
+  HandleScope scope;
+  LocalContext context;
+  CompileRun(
+      "var obj = {};"
+      "var ordering = [];"
+ "function observer1() { ordering.push(1); if (!obj.b) obj.b = true };"
+      "function observer2() { ordering.push(2); };"
+      "Object.observe(obj, observer1);"
+      "Object.observe(obj, observer2);"
+      "obj.a = 1;"
+      "Object.deliverChangeRecords(observer2);");
+  CHECK_EQ(4, CompileRun("ordering.length")->Int32Value());
+  // First, observer2 is called due to deliverChangeRecords
+  CHECK_EQ(2, CompileRun("ordering[0]")->Int32Value());
+  // Then, observer1 is called when the stack unwinds
+  CHECK_EQ(1, CompileRun("ordering[1]")->Int32Value());
+  // observer1's mutation causes both 1 and 2 to be reactivated,
+  // with 1 having priority.
+  CHECK_EQ(1, CompileRun("ordering[2]")->Int32Value());
+  CHECK_EQ(2, CompileRun("ordering[3]")->Int32Value());
+}
+
 TEST(ObjectHashTableGrowth) {
   HarmonyIsolate isolate;
   HandleScope scope;


--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to