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

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

Issue 270763003: Object.observe: avoid accessing acceptList properties more than once (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 7 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 | « no previous file | src/runtime.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 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 "use strict"; 5 "use strict";
6 6
7 // Overview: 7 // Overview:
8 // 8 //
9 // This file contains all of the routing and accounting for Object.observe. 9 // This file contains all of the routing and accounting for Object.observe.
10 // User code will interact with these mechanisms via the Object.observe APIs 10 // User code will interact with these mechanisms via the Object.observe APIs
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
120 } 120 }
121 121
122 function TypeMapAddType(typeMap, type, ignoreDuplicate) { 122 function TypeMapAddType(typeMap, type, ignoreDuplicate) {
123 typeMap[type] = ignoreDuplicate ? 1 : (typeMap[type] || 0) + 1; 123 typeMap[type] = ignoreDuplicate ? 1 : (typeMap[type] || 0) + 1;
124 } 124 }
125 125
126 function TypeMapRemoveType(typeMap, type) { 126 function TypeMapRemoveType(typeMap, type) {
127 typeMap[type]--; 127 typeMap[type]--;
128 } 128 }
129 129
130 function TypeMapCreateFromList(typeList) { 130 function TypeMapCreateFromList(typeList, length) {
131 var typeMap = TypeMapCreate(); 131 var typeMap = TypeMapCreate();
132 for (var i = 0; i < typeList.length; i++) { 132 for (var i = 0; i < length; i++) {
133 TypeMapAddType(typeMap, typeList[i], true); 133 TypeMapAddType(typeMap, typeList[i], true);
134 } 134 }
135 return typeMap; 135 return typeMap;
136 } 136 }
137 137
138 function TypeMapHasType(typeMap, type) { 138 function TypeMapHasType(typeMap, type) {
139 return !!typeMap[type]; 139 return !!typeMap[type];
140 } 140 }
141 141
142 function TypeMapIsDisjointFrom(typeMap1, typeMap2) { 142 function TypeMapIsDisjointFrom(typeMap1, typeMap2) {
143 if (!typeMap1 || !typeMap2) 143 if (!typeMap1 || !typeMap2)
144 return true; 144 return true;
145 145
146 for (var type in typeMap1) { 146 for (var type in typeMap1) {
147 if (TypeMapHasType(typeMap1, type) && TypeMapHasType(typeMap2, type)) 147 if (TypeMapHasType(typeMap1, type) && TypeMapHasType(typeMap2, type))
148 return false; 148 return false;
149 } 149 }
150 150
151 return true; 151 return true;
152 } 152 }
153 153
154 var defaultAcceptTypes = TypeMapCreateFromList([ 154 var defaultAcceptTypes = (function() {
155 'add', 155 var defaultTypes = [
156 'update', 156 'add',
157 'delete', 157 'update',
158 'setPrototype', 158 'delete',
159 'reconfigure', 159 'setPrototype',
160 'preventExtensions' 160 'reconfigure',
161 ]); 161 'preventExtensions'
162 ];
163 return TypeMapCreateFromList(defaultTypes, defaultTypes.length);
164 })();
162 165
163 // An Observer is a registration to observe an object by a callback with 166 // An Observer is a registration to observe an object by a callback with
164 // a given set of accept types. If the set of accept types is the default 167 // a given set of accept types. If the set of accept types is the default
165 // set for Object.observe, the observer is represented as a direct reference 168 // set for Object.observe, the observer is represented as a direct reference
166 // to the callback. An observer never changes its accept types and thus never 169 // to the callback. An observer never changes its accept types and thus never
167 // needs to "normalize". 170 // needs to "normalize".
168 function ObserverCreate(callback, acceptList) { 171 function ObserverCreate(callback, acceptList) {
169 if (IS_UNDEFINED(acceptList)) 172 if (IS_UNDEFINED(acceptList))
170 return callback; 173 return callback;
171 var observer = nullProtoObject(); 174 var observer = nullProtoObject();
172 observer.callback = callback; 175 observer.callback = callback;
173 observer.accept = TypeMapCreateFromList(acceptList); 176 observer.accept = acceptList;
174 return observer; 177 return observer;
175 } 178 }
176 179
177 function ObserverGetCallback(observer) { 180 function ObserverGetCallback(observer) {
178 return IS_SPEC_FUNCTION(observer) ? observer : observer.callback; 181 return IS_SPEC_FUNCTION(observer) ? observer : observer.callback;
179 } 182 }
180 183
181 function ObserverGetAcceptTypes(observer) { 184 function ObserverGetAcceptTypes(observer) {
182 return IS_SPEC_FUNCTION(observer) ? defaultAcceptTypes : observer.accept; 185 return IS_SPEC_FUNCTION(observer) ? defaultAcceptTypes : observer.accept;
183 } 186 }
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
299 302
300 function ObjectInfoRemovePerformingType(objectInfo, type) { 303 function ObjectInfoRemovePerformingType(objectInfo, type) {
301 objectInfo.performingCount--; 304 objectInfo.performingCount--;
302 TypeMapRemoveType(objectInfo.performing, type); 305 TypeMapRemoveType(objectInfo.performing, type);
303 } 306 }
304 307
305 function ObjectInfoGetPerformingTypes(objectInfo) { 308 function ObjectInfoGetPerformingTypes(objectInfo) {
306 return objectInfo.performingCount > 0 ? objectInfo.performing : null; 309 return objectInfo.performingCount > 0 ? objectInfo.performing : null;
307 } 310 }
308 311
309 function AcceptArgIsValid(arg) { 312 function ConvertAcceptListToTypeMap(arg) {
313 // We use undefined as a sentinel for the default accept list.
310 if (IS_UNDEFINED(arg)) 314 if (IS_UNDEFINED(arg))
311 return true; 315 return arg;
312 316
313 if (!IS_SPEC_OBJECT(arg) || 317 if (!IS_SPEC_OBJECT(arg))
314 !IS_NUMBER(arg.length) || 318 throw MakeTypeError("observe_accept_invalid");
315 arg.length < 0)
316 return false;
317 319
318 return true; 320 var len = ToInteger(arg.length);
321 if (len < 0) len = 0;
322
323 return TypeMapCreateFromList(arg, len);
319 } 324 }
320 325
321 // CallbackInfo's optimized state is just a number which represents its global 326 // CallbackInfo's optimized state is just a number which represents its global
322 // priority. When a change record must be enqueued for the callback, it 327 // priority. When a change record must be enqueued for the callback, it
323 // normalizes. When delivery clears any pending change records, it re-optimizes. 328 // normalizes. When delivery clears any pending change records, it re-optimizes.
324 function CallbackInfoGet(callback) { 329 function CallbackInfoGet(callback) {
325 return GetCallbackInfoMap().get(callback); 330 return GetCallbackInfoMap().get(callback);
326 } 331 }
327 332
328 function CallbackInfoGetOrCreate(callback) { 333 function CallbackInfoGetOrCreate(callback) {
(...skipping 26 matching lines...) Expand all
355 360
356 function ObjectObserve(object, callback, acceptList) { 361 function ObjectObserve(object, callback, acceptList) {
357 if (!IS_SPEC_OBJECT(object)) 362 if (!IS_SPEC_OBJECT(object))
358 throw MakeTypeError("observe_non_object", ["observe"]); 363 throw MakeTypeError("observe_non_object", ["observe"]);
359 if (%IsJSGlobalProxy(object)) 364 if (%IsJSGlobalProxy(object))
360 throw MakeTypeError("observe_global_proxy", ["observe"]); 365 throw MakeTypeError("observe_global_proxy", ["observe"]);
361 if (!IS_SPEC_FUNCTION(callback)) 366 if (!IS_SPEC_FUNCTION(callback))
362 throw MakeTypeError("observe_non_function", ["observe"]); 367 throw MakeTypeError("observe_non_function", ["observe"]);
363 if (ObjectIsFrozen(callback)) 368 if (ObjectIsFrozen(callback))
364 throw MakeTypeError("observe_callback_frozen"); 369 throw MakeTypeError("observe_callback_frozen");
365 if (!AcceptArgIsValid(acceptList))
366 throw MakeTypeError("observe_accept_invalid");
367 370
368 return %ObjectObserveInObjectContext(object, callback, acceptList); 371 return %ObjectObserveInObjectContext(object, callback, acceptList);
369 } 372 }
370 373
371 function NativeObjectObserve(object, callback, acceptList) { 374 function NativeObjectObserve(object, callback, acceptList) {
372 var objectInfo = ObjectInfoGetOrCreate(object); 375 var objectInfo = ObjectInfoGetOrCreate(object);
373 ObjectInfoAddObserver(objectInfo, callback, acceptList); 376 var typeList = ConvertAcceptListToTypeMap(acceptList);
377 ObjectInfoAddObserver(objectInfo, callback, typeList);
374 return object; 378 return object;
375 } 379 }
376 380
377 function ObjectUnobserve(object, callback) { 381 function ObjectUnobserve(object, callback) {
378 if (!IS_SPEC_OBJECT(object)) 382 if (!IS_SPEC_OBJECT(object))
379 throw MakeTypeError("observe_non_object", ["unobserve"]); 383 throw MakeTypeError("observe_non_object", ["unobserve"]);
380 if (%IsJSGlobalProxy(object)) 384 if (%IsJSGlobalProxy(object))
381 throw MakeTypeError("observe_global_proxy", ["unobserve"]); 385 throw MakeTypeError("observe_global_proxy", ["unobserve"]);
382 if (!IS_SPEC_FUNCTION(callback)) 386 if (!IS_SPEC_FUNCTION(callback))
383 throw MakeTypeError("observe_non_function", ["unobserve"]); 387 throw MakeTypeError("observe_non_function", ["unobserve"]);
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
626 "observe", ArrayObserve, 630 "observe", ArrayObserve,
627 "unobserve", ArrayUnobserve 631 "unobserve", ArrayUnobserve
628 )); 632 ));
629 InstallFunctions(notifierPrototype, DONT_ENUM, $Array( 633 InstallFunctions(notifierPrototype, DONT_ENUM, $Array(
630 "notify", ObjectNotifierNotify, 634 "notify", ObjectNotifierNotify,
631 "performChange", ObjectNotifierPerformChange 635 "performChange", ObjectNotifierPerformChange
632 )); 636 ));
633 } 637 }
634 638
635 SetupObjectObserve(); 639 SetupObjectObserve();
OLDNEW
« no previous file with comments | « no previous file | src/runtime.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698