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

Side by Side Diff: src/object-observe.js

Issue 190853007: Revert "Enable Object.observe by default" (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 9 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ic.cc ('k') | src/objects.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 // 3) observationState.pendingObservers. This is the set of observers which 49 // 3) observationState.pendingObservers. This is the set of observers which
50 // have change records which must be delivered. During "normal" delivery 50 // have change records which must be delivered. During "normal" delivery
51 // (i.e. not Object.deliverChangeRecords), this is the mechanism by which 51 // (i.e. not Object.deliverChangeRecords), this is the mechanism by which
52 // callbacks are invoked in the proper order until there are no more 52 // callbacks are invoked in the proper order until there are no more
53 // change records pending to a callback. 53 // change records pending to a callback.
54 // 54 //
55 // Note that in order to reduce allocation and processing costs, the 55 // Note that in order to reduce allocation and processing costs, the
56 // implementation of (1) and (2) have "optimized" states which represent 56 // implementation of (1) and (2) have "optimized" states which represent
57 // common cases which can be handled more efficiently. 57 // common cases which can be handled more efficiently.
58 58
59 var observationState; 59 var observationState = %GetObservationState();
60 60 if (IS_UNDEFINED(observationState.callbackInfoMap)) {
61 function GetObservationState() { 61 observationState.callbackInfoMap = %ObservationWeakMapCreate();
62 if (IS_UNDEFINED(observationState)) 62 observationState.objectInfoMap = %ObservationWeakMapCreate();
63 observationState = %GetObservationState(); 63 observationState.notifierObjectInfoMap = %ObservationWeakMapCreate();
64 64 observationState.pendingObservers = null;
65 if (IS_UNDEFINED(observationState.callbackInfoMap)) { 65 observationState.nextCallbackPriority = 0;
66 observationState.callbackInfoMap = %ObservationWeakMapCreate();
67 observationState.objectInfoMap = %ObservationWeakMapCreate();
68 observationState.notifierObjectInfoMap = %ObservationWeakMapCreate();
69 observationState.pendingObservers = null;
70 observationState.nextCallbackPriority = 0;
71 }
72
73 return observationState;
74 } 66 }
75 67
76 function GetWeakMapWrapper() { 68 function ObservationWeakMap(map) {
77 function MapWrapper(map) { 69 this.map_ = map;
78 this.map_ = map;
79 };
80
81 MapWrapper.prototype = {
82 get: function(key) {
83 key = %UnwrapGlobalProxy(key);
84 if (!IS_SPEC_OBJECT(key)) return UNDEFINED;
85 return %WeakCollectionGet(this.map_, key);
86 },
87 set: function(key, value) {
88 key = %UnwrapGlobalProxy(key);
89 if (!IS_SPEC_OBJECT(key)) return UNDEFINED;
90 %WeakCollectionSet(this.map_, key, value);
91 },
92 has: function(key) {
93 return !IS_UNDEFINED(this.get(key));
94 }
95 };
96
97 return MapWrapper;
98 } 70 }
99 71
100 var contextMaps; 72 ObservationWeakMap.prototype = {
73 get: function(key) {
74 key = %UnwrapGlobalProxy(key);
75 if (!IS_SPEC_OBJECT(key)) return UNDEFINED;
76 return %WeakCollectionGet(this.map_, key);
77 },
78 set: function(key, value) {
79 key = %UnwrapGlobalProxy(key);
80 if (!IS_SPEC_OBJECT(key)) return UNDEFINED;
81 %WeakCollectionSet(this.map_, key, value);
82 },
83 has: function(key) {
84 return !IS_UNDEFINED(this.get(key));
85 }
86 };
101 87
102 function GetContextMaps() { 88 var callbackInfoMap =
103 if (IS_UNDEFINED(contextMaps)) { 89 new ObservationWeakMap(observationState.callbackInfoMap);
104 var map = GetWeakMapWrapper(); 90 var objectInfoMap = new ObservationWeakMap(observationState.objectInfoMap);
105 var observationState = GetObservationState(); 91 var notifierObjectInfoMap =
106 contextMaps = { 92 new ObservationWeakMap(observationState.notifierObjectInfoMap);
107 callbackInfoMap: new map(observationState.callbackInfoMap),
108 objectInfoMap: new map(observationState.objectInfoMap),
109 notifierObjectInfoMap: new map(observationState.notifierObjectInfoMap)
110 };
111 }
112
113 return contextMaps;
114 }
115
116 function GetCallbackInfoMap() {
117 return GetContextMaps().callbackInfoMap;
118 }
119
120 function GetObjectInfoMap() {
121 return GetContextMaps().objectInfoMap;
122 }
123
124 function GetNotifierObjectInfoMap() {
125 return GetContextMaps().notifierObjectInfoMap;
126 }
127
128 function GetPendingObservers() {
129 return GetObservationState().pendingObservers;
130 }
131
132 function SetPendingObservers(pendingObservers) {
133 GetObservationState().pendingObservers = pendingObservers;
134 }
135
136 function GetNextCallbackPriority() {
137 return GetObservationState().nextCallbackPriority++;
138 }
139 93
140 function nullProtoObject() { 94 function nullProtoObject() {
141 return { __proto__: null }; 95 return { __proto__: null };
142 } 96 }
143 97
144 function TypeMapCreate() { 98 function TypeMapCreate() {
145 return nullProtoObject(); 99 return nullProtoObject();
146 } 100 }
147 101
148 function TypeMapAddType(typeMap, type, ignoreDuplicate) { 102 function TypeMapAddType(typeMap, type, ignoreDuplicate) {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 if (!%IsJSProxy(object)) 173 if (!%IsJSProxy(object))
220 %SetIsObserved(object); 174 %SetIsObserved(object);
221 175
222 objectInfo = { 176 objectInfo = {
223 object: object, 177 object: object,
224 changeObservers: null, 178 changeObservers: null,
225 notifier: null, 179 notifier: null,
226 performing: null, 180 performing: null,
227 performingCount: 0, 181 performingCount: 0,
228 }; 182 };
229 GetObjectInfoMap().set(object, objectInfo); 183 objectInfoMap.set(object, objectInfo);
230 } 184 }
231 return objectInfo; 185 return objectInfo;
232 } 186 }
233 187
234 function ObjectInfoGet(object) { 188 function ObjectInfoGet(object) {
235 return GetObjectInfoMap().get(object); 189 return objectInfoMap.get(object);
236 } 190 }
237 191
238 function ObjectInfoGetFromNotifier(notifier) { 192 function ObjectInfoGetFromNotifier(notifier) {
239 return GetNotifierObjectInfoMap().get(notifier); 193 return notifierObjectInfoMap.get(notifier);
240 } 194 }
241 195
242 function ObjectInfoGetNotifier(objectInfo) { 196 function ObjectInfoGetNotifier(objectInfo) {
243 if (IS_NULL(objectInfo.notifier)) { 197 if (IS_NULL(objectInfo.notifier)) {
244 objectInfo.notifier = { __proto__: notifierPrototype }; 198 objectInfo.notifier = { __proto__: notifierPrototype };
245 GetNotifierObjectInfoMap().set(objectInfo.notifier, objectInfo); 199 notifierObjectInfoMap.set(objectInfo.notifier, objectInfo);
246 } 200 }
247 201
248 return objectInfo.notifier; 202 return objectInfo.notifier;
249 } 203 }
250 204
251 function ObjectInfoGetObject(objectInfo) { 205 function ObjectInfoGetObject(objectInfo) {
252 return objectInfo.object; 206 return objectInfo.object;
253 } 207 }
254 208
255 function ChangeObserversIsOptimized(changeObservers) { 209 function ChangeObserversIsOptimized(changeObservers) {
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 arg.length < 0) 295 arg.length < 0)
342 return false; 296 return false;
343 297
344 return true; 298 return true;
345 } 299 }
346 300
347 // CallbackInfo's optimized state is just a number which represents its global 301 // CallbackInfo's optimized state is just a number which represents its global
348 // priority. When a change record must be enqueued for the callback, it 302 // priority. When a change record must be enqueued for the callback, it
349 // normalizes. When delivery clears any pending change records, it re-optimizes. 303 // normalizes. When delivery clears any pending change records, it re-optimizes.
350 function CallbackInfoGet(callback) { 304 function CallbackInfoGet(callback) {
351 return GetCallbackInfoMap().get(callback); 305 return callbackInfoMap.get(callback);
352 } 306 }
353 307
354 function CallbackInfoGetOrCreate(callback) { 308 function CallbackInfoGetOrCreate(callback) {
355 var callbackInfo = GetCallbackInfoMap().get(callback); 309 var callbackInfo = callbackInfoMap.get(callback);
356 if (!IS_UNDEFINED(callbackInfo)) 310 if (!IS_UNDEFINED(callbackInfo))
357 return callbackInfo; 311 return callbackInfo;
358 312
359 var priority = GetNextCallbackPriority(); 313 var priority = observationState.nextCallbackPriority++
360 GetCallbackInfoMap().set(callback, priority); 314 callbackInfoMap.set(callback, priority);
361 return priority; 315 return priority;
362 } 316 }
363 317
364 function CallbackInfoGetPriority(callbackInfo) { 318 function CallbackInfoGetPriority(callbackInfo) {
365 if (IS_NUMBER(callbackInfo)) 319 if (IS_NUMBER(callbackInfo))
366 return callbackInfo; 320 return callbackInfo;
367 else 321 else
368 return callbackInfo.priority; 322 return callbackInfo.priority;
369 } 323 }
370 324
371 function CallbackInfoNormalize(callback) { 325 function CallbackInfoNormalize(callback) {
372 var callbackInfo = GetCallbackInfoMap().get(callback); 326 var callbackInfo = callbackInfoMap.get(callback);
373 if (IS_NUMBER(callbackInfo)) { 327 if (IS_NUMBER(callbackInfo)) {
374 var priority = callbackInfo; 328 var priority = callbackInfo;
375 callbackInfo = new InternalArray; 329 callbackInfo = new InternalArray;
376 callbackInfo.priority = priority; 330 callbackInfo.priority = priority;
377 GetCallbackInfoMap().set(callback, callbackInfo); 331 callbackInfoMap.set(callback, callbackInfo);
378 } 332 }
379 return callbackInfo; 333 return callbackInfo;
380 } 334 }
381 335
382 function ObjectObserve(object, callback, acceptList) { 336 function ObjectObserve(object, callback, acceptList) {
383 if (!IS_SPEC_OBJECT(object)) 337 if (!IS_SPEC_OBJECT(object))
384 throw MakeTypeError("observe_non_object", ["observe"]); 338 throw MakeTypeError("observe_non_object", ["observe"]);
385 if (!IS_SPEC_FUNCTION(callback)) 339 if (!IS_SPEC_FUNCTION(callback))
386 throw MakeTypeError("observe_non_function", ["observe"]); 340 throw MakeTypeError("observe_non_function", ["observe"]);
387 if (ObjectIsFrozen(callback)) 341 if (ObjectIsFrozen(callback))
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
429 var callback = ObserverGetCallback(observer); 383 var callback = ObserverGetCallback(observer);
430 if (needsAccessCheck && 384 if (needsAccessCheck &&
431 // Drop all splice records on the floor for access-checked objects 385 // Drop all splice records on the floor for access-checked objects
432 (changeRecord.type == 'splice' || 386 (changeRecord.type == 'splice' ||
433 !%IsAccessAllowedForObserver( 387 !%IsAccessAllowedForObserver(
434 callback, changeRecord.object, changeRecord.name))) { 388 callback, changeRecord.object, changeRecord.name))) {
435 return; 389 return;
436 } 390 }
437 391
438 var callbackInfo = CallbackInfoNormalize(callback); 392 var callbackInfo = CallbackInfoNormalize(callback);
439 if (IS_NULL(GetPendingObservers())) { 393 if (IS_NULL(observationState.pendingObservers)) {
440 SetPendingObservers(nullProtoObject()) 394 observationState.pendingObservers = nullProtoObject();
441 GetMicrotaskQueue().push(ObserveMicrotaskRunner); 395 GetMicrotaskQueue().push(ObserveMicrotaskRunner);
442 %SetMicrotaskPending(true); 396 %SetMicrotaskPending(true);
443 } 397 }
444 GetPendingObservers()[callbackInfo.priority] = callback; 398 observationState.pendingObservers[callbackInfo.priority] = callback;
445 callbackInfo.push(changeRecord); 399 callbackInfo.push(changeRecord);
446 } 400 }
447 401
448 function ObjectInfoEnqueueExternalChangeRecord(objectInfo, changeRecord, type) { 402 function ObjectInfoEnqueueExternalChangeRecord(objectInfo, changeRecord, type) {
449 if (!ObjectInfoHasActiveObservers(objectInfo)) 403 if (!ObjectInfoHasActiveObservers(objectInfo))
450 return; 404 return;
451 405
452 var hasType = !IS_UNDEFINED(type); 406 var hasType = !IS_UNDEFINED(type);
453 var newRecord = hasType ? 407 var newRecord = hasType ?
454 { object: ObjectInfoGetObject(objectInfo), type: type } : 408 { object: ObjectInfoGetObject(objectInfo), type: type } :
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
587 if (!IS_SPEC_OBJECT(object)) 541 if (!IS_SPEC_OBJECT(object))
588 throw MakeTypeError("observe_non_object", ["getNotifier"]); 542 throw MakeTypeError("observe_non_object", ["getNotifier"]);
589 543
590 if (ObjectIsFrozen(object)) return null; 544 if (ObjectIsFrozen(object)) return null;
591 545
592 var objectInfo = ObjectInfoGetOrCreate(object); 546 var objectInfo = ObjectInfoGetOrCreate(object);
593 return ObjectInfoGetNotifier(objectInfo); 547 return ObjectInfoGetNotifier(objectInfo);
594 } 548 }
595 549
596 function CallbackDeliverPending(callback) { 550 function CallbackDeliverPending(callback) {
597 var callbackInfo = GetCallbackInfoMap().get(callback); 551 var callbackInfo = callbackInfoMap.get(callback);
598 if (IS_UNDEFINED(callbackInfo) || IS_NUMBER(callbackInfo)) 552 if (IS_UNDEFINED(callbackInfo) || IS_NUMBER(callbackInfo))
599 return false; 553 return false;
600 554
601 // Clear the pending change records from callback and return it to its 555 // Clear the pending change records from callback and return it to its
602 // "optimized" state. 556 // "optimized" state.
603 var priority = callbackInfo.priority; 557 var priority = callbackInfo.priority;
604 GetCallbackInfoMap().set(callback, priority); 558 callbackInfoMap.set(callback, priority);
605 559
606 if (GetPendingObservers()) 560 if (observationState.pendingObservers)
607 delete GetPendingObservers()[priority]; 561 delete observationState.pendingObservers[priority];
608 562
609 var delivered = []; 563 var delivered = [];
610 %MoveArrayContents(callbackInfo, delivered); 564 %MoveArrayContents(callbackInfo, delivered);
611 565
612 try { 566 try {
613 %_CallFunction(UNDEFINED, delivered, callback); 567 %_CallFunction(UNDEFINED, delivered, callback);
614 } catch (ex) {} // TODO(rossberg): perhaps log uncaught exceptions. 568 } catch (ex) {} // TODO(rossberg): perhaps log uncaught exceptions.
615 return true; 569 return true;
616 } 570 }
617 571
618 function ObjectDeliverChangeRecords(callback) { 572 function ObjectDeliverChangeRecords(callback) {
619 if (!IS_SPEC_FUNCTION(callback)) 573 if (!IS_SPEC_FUNCTION(callback))
620 throw MakeTypeError("observe_non_function", ["deliverChangeRecords"]); 574 throw MakeTypeError("observe_non_function", ["deliverChangeRecords"]);
621 575
622 while (CallbackDeliverPending(callback)) {} 576 while (CallbackDeliverPending(callback)) {}
623 } 577 }
624 578
625 function ObserveMicrotaskRunner() { 579 function ObserveMicrotaskRunner() {
626 var pendingObservers = GetPendingObservers(); 580 var pendingObservers = observationState.pendingObservers;
627 if (pendingObservers) { 581 if (pendingObservers) {
628 SetPendingObservers(null); 582 observationState.pendingObservers = null;
629 for (var i in pendingObservers) { 583 for (var i in pendingObservers) {
630 CallbackDeliverPending(pendingObservers[i]); 584 CallbackDeliverPending(pendingObservers[i]);
631 } 585 }
632 } 586 }
633 } 587 }
634 588
635 function SetupObjectObserve() { 589 function SetupObjectObserve() {
636 %CheckIsBootstrapping(); 590 %CheckIsBootstrapping();
637 InstallFunctions($Object, DONT_ENUM, $Array( 591 InstallFunctions($Object, DONT_ENUM, $Array(
638 "deliverChangeRecords", ObjectDeliverChangeRecords, 592 "deliverChangeRecords", ObjectDeliverChangeRecords,
639 "getNotifier", ObjectGetNotifier, 593 "getNotifier", ObjectGetNotifier,
640 "observe", ObjectObserve, 594 "observe", ObjectObserve,
641 "unobserve", ObjectUnobserve 595 "unobserve", ObjectUnobserve
642 )); 596 ));
643 InstallFunctions($Array, DONT_ENUM, $Array( 597 InstallFunctions($Array, DONT_ENUM, $Array(
644 "observe", ArrayObserve, 598 "observe", ArrayObserve,
645 "unobserve", ArrayUnobserve 599 "unobserve", ArrayUnobserve
646 )); 600 ));
647 InstallFunctions(notifierPrototype, DONT_ENUM, $Array( 601 InstallFunctions(notifierPrototype, DONT_ENUM, $Array(
648 "notify", ObjectNotifierNotify, 602 "notify", ObjectNotifierNotify,
649 "performChange", ObjectNotifierPerformChange 603 "performChange", ObjectNotifierPerformChange
650 )); 604 ));
651 } 605 }
652 606
653 SetupObjectObserve(); 607 SetupObjectObserve();
OLDNEW
« no previous file with comments | « src/ic.cc ('k') | src/objects.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698