From 39404aedc0b6f98a11dd8401bb66462a4a330bb7 Mon Sep 17 00:00:00 2001 From: Erik Bryn Date: Tue, 3 Feb 2015 18:35:10 -0800 Subject: [PATCH] Make meta.cache & meta.cacheMeta lazy --- packages/ember-metal/lib/chains.js | 4 ++-- packages/ember-metal/lib/computed.js | 23 +++++++++++++------ packages/ember-metal/lib/utils.js | 8 +++---- .../lib/computed/reduce_computed.js | 17 ++++++++++---- .../ember-runtime/lib/system/core_object.js | 2 +- 5 files changed, 36 insertions(+), 18 deletions(-) diff --git a/packages/ember-metal/lib/chains.js b/packages/ember-metal/lib/chains.js index 7eaf1411421..ce54a68b149 100644 --- a/packages/ember-metal/lib/chains.js +++ b/packages/ember-metal/lib/chains.js @@ -36,7 +36,7 @@ function addChainWatcher(obj, keyName, node) { var m = metaFor(obj); var nodes = m.chainWatchers; - if (!m.hasOwnProperty('chainWatchers')) { + if (!m.hasOwnProperty('chainWatchers')) { // FIXME?! nodes = m.chainWatchers = {}; } @@ -122,7 +122,7 @@ function lazyGet(obj, key) { var possibleDesc = obj[key]; var desc = (possibleDesc !== null && typeof possibleDesc === 'object' && possibleDesc.isDescriptor) ? possibleDesc : undefined; if (desc && desc._cacheable) { - if (key in meta.cache) { + if (meta.cache && key in meta.cache) { return meta.cache[key]; } else { return undefined; diff --git a/packages/ember-metal/lib/computed.js b/packages/ember-metal/lib/computed.js index 3d4743fabc4..386daca5d67 100644 --- a/packages/ember-metal/lib/computed.js +++ b/packages/ember-metal/lib/computed.js @@ -303,7 +303,7 @@ ComputedPropertyPrototype.didChange = function(obj, keyName) { // the cached value set by the setter if (this._cacheable && this._suspended !== obj) { var meta = metaFor(obj); - if (meta.cache[keyName] !== undefined) { + if (meta.cache && meta.cache[keyName] !== undefined) { meta.cache[keyName] = undefined; removeDependentKeys(this, obj, keyName, meta); } @@ -348,7 +348,7 @@ ComputedPropertyPrototype.get = function(obj, keyName) { meta = metaFor(obj); cache = meta.cache; - var result = cache[keyName]; + var result = cache && cache[keyName]; if (result === UNDEFINED) { return undefined; @@ -357,6 +357,10 @@ ComputedPropertyPrototype.get = function(obj, keyName) { } ret = this._getter.call(obj, keyName); + cache = meta.cache; + if (!cache) { + cache = meta.cache = {}; + } if (ret === undefined) { cache[keyName] = UNDEFINED; } else { @@ -447,7 +451,7 @@ ComputedPropertyPrototype._set = function computedPropertySet(obj, keyName, valu throw new EmberError('Cannot set read-only property "' + keyName + '" on object: ' + inspect(obj)); } - if (cacheable && cache[keyName] !== undefined) { + if (cacheable && cache && cache[keyName] !== undefined) { if (cache[keyName] !== UNDEFINED) { cachedValue = cache[keyName]; } @@ -482,6 +486,9 @@ ComputedPropertyPrototype._set = function computedPropertySet(obj, keyName, valu if (!hadCachedValue) { addDependentKeys(this, obj, keyName, meta); } + if (!cache) { + cache = meta.cache = {}; + } if (ret === undefined) { cache[keyName] = UNDEFINED; } else { @@ -500,11 +507,13 @@ ComputedPropertyPrototype._set = function computedPropertySet(obj, keyName, valu ComputedPropertyPrototype.teardown = function(obj, keyName) { var meta = metaFor(obj); - if (keyName in meta.cache) { - removeDependentKeys(this, obj, keyName, meta); - } + if (meta.cache) { + if (keyName in meta.cache) { + removeDependentKeys(this, obj, keyName, meta); + } - if (this._cacheable) { delete meta.cache[keyName]; } + if (this._cacheable) { delete meta.cache[keyName]; } + } return null; // no value to restore }; diff --git a/packages/ember-metal/lib/utils.js b/packages/ember-metal/lib/utils.js index 72c7b965e84..d7baa15dca4 100644 --- a/packages/ember-metal/lib/utils.js +++ b/packages/ember-metal/lib/utils.js @@ -289,8 +289,8 @@ export function guidFor(obj) { // function Meta(obj) { this.watching = {}; - this.cache = {}; - this.cacheMeta = {}; + this.cache = undefined; + this.cacheMeta = undefined; this.source = obj; this.deps = undefined; this.listeners = undefined; @@ -377,8 +377,8 @@ function meta(obj, writable) { ret = o_create(ret); ret.watching = o_create(ret.watching); - ret.cache = {}; - ret.cacheMeta = {}; + ret.cache = undefined; + ret.cacheMeta = undefined; ret.source = obj; if (Ember.FEATURES.isEnabled('mandatory-setter')) { diff --git a/packages/ember-runtime/lib/computed/reduce_computed.js b/packages/ember-runtime/lib/computed/reduce_computed.js index f15a9f9b9a4..0b9ba5d69f9 100644 --- a/packages/ember-runtime/lib/computed/reduce_computed.js +++ b/packages/ember-runtime/lib/computed/reduce_computed.js @@ -419,7 +419,10 @@ function partiallyRecomputeFor(obj, dependentKey) { function ReduceComputedPropertyInstanceMeta(context, propertyName, initialValue) { this.context = context; this.propertyName = propertyName; - this.cache = metaFor(context).cache; + var contextMeta = metaFor(context); + var contextCache = contextMeta.cache; + if (!contextCache) { contextCache = contextMeta.cache = {}; } + this.cache = contextCache; this.dependentArrays = {}; this.sugarMeta = {}; this.initialValue = initialValue; @@ -574,13 +577,19 @@ ReduceComputedProperty.prototype._callbacks = function () { }; ReduceComputedProperty.prototype._hasInstanceMeta = function (context, propertyName) { - return !!metaFor(context).cacheMeta[propertyName]; + var contextMeta = context.__ember_meta__; + var cacheMeta = contextMeta && contextMeta.cacheMeta; + return !!(cacheMeta && cacheMeta[propertyName]); }; ReduceComputedProperty.prototype._instanceMeta = function (context, propertyName) { - var cacheMeta = metaFor(context).cacheMeta; - var meta = cacheMeta[propertyName]; + var contextMeta = context.__ember_meta__; + var cacheMeta = contextMeta.cacheMeta; + var meta = cacheMeta && cacheMeta[propertyName]; + if (!cacheMeta) { + cacheMeta = contextMeta.cacheMeta = {}; + } if (!meta) { meta = cacheMeta[propertyName] = new ReduceComputedPropertyInstanceMeta(context, propertyName, this.initialValue()); meta.dependentArraysObserver = new DependentArraysObserver(this._callbacks(), this, meta, context, propertyName, meta.sugarMeta); diff --git a/packages/ember-runtime/lib/system/core_object.js b/packages/ember-runtime/lib/system/core_object.js index 14b0e0d65fa..eba6a9a9e73 100644 --- a/packages/ember-runtime/lib/system/core_object.js +++ b/packages/ember-runtime/lib/system/core_object.js @@ -910,7 +910,7 @@ CoreObject.reopen({ if (value instanceof Ember.ComputedProperty) { var cache = Ember.meta(this.constructor).cache; - if (cache._computedProperties !== undefined) { + if (cache && cache._computedProperties !== undefined) { cache._computedProperties = undefined; } }