lib/third_party/tracing/model/global_memory_dump.js
function(dump) {
      // Completely skip dumps with undefined size. As a result, each dump will
      // have defined effective size if and only if it has defined size.
      if (!hasSize(dump)) {
        // The rest of the pipeline relies on effective size being either a
        // valid ScalarAttribute, or undefined.
        dump.attributes[EFFECTIVE_SIZE_ATTRIBUTE_NAME] = undefined;
        return;
      }

      var effectiveSize;
      if (dump.children === undefined || dump.children.length === 0) {
        // Leaf dump.
        effectiveSize = getSize(dump) * dump.cumulativeOwningCoefficient_ *
            dump.cumulativeOwnedCoefficient_;
      } else {
        // Non-leaf dump.
        effectiveSize = 0;
        dump.children.forEach(function(childDump) {
          if (!hasSize(childDump))
            return;
          effectiveSize +=
              childDump.attributes[EFFECTIVE_SIZE_ATTRIBUTE_NAME].value;
        });
      }
      var attribute = new tr.model.ScalarAttribute('bytes', effectiveSize);
      dump.attributes[EFFECTIVE_SIZE_ATTRIBUTE_NAME] = attribute;

      // Add attribute infos regarding ownership (if applicable).
      // TODO(petrcermak): This belongs to the corresponding analysis UI code.
      if (dump.ownedBy.length > 0) {
        var message = 'shared by:' +
            dump.ownedBy.map(function(ownershipLink) {
              return '\n  - ' + ownershipToUserFriendlyString(
                  ownershipLink.source, ownershipLink.importance);
            }).join();
        attribute.infos.push(new tr.model.AttributeInfo(
            tr.model.AttributeInfoType.MEMORY_OWNED, message));
      }
      if (dump.owns !== undefined) {
        var target = dump.owns.target;
        var message = 'shares ' +
            ownershipToUserFriendlyString(target, dump.owns.importance) +
            ' with';

        var otherOwnershipLinks = target.ownedBy.filter(
            function(ownershipLink) {
          return ownershipLink.source !== dump;
        });
        if (otherOwnershipLinks.length > 0) {
          message += ':';
          message += otherOwnershipLinks.map(function(ownershipLink) {
            return '\n  - ' + ownershipToUserFriendlyString(
                ownershipLink.source, ownershipLink.importance);
          }).join();
        } else {
          message += ' no other dumps';
        }

        attribute.infos.push(new tr.model.AttributeInfo(
            tr.model.AttributeInfoType.MEMORY_OWNER, message));
      }
    }
function(dump) {
      // Completely skip dumps with undefined size. As a result, each dump will
      // have defined effective size if and only if it has defined size.
      if (!hasSize(dump)) {
        // The rest of the pipeline relies on effective size being either a
        // valid ScalarAttribute, or undefined.
        dump.attributes[EFFECTIVE_SIZE_ATTRIBUTE_NAME] = undefined;
        return;
      }

      var effectiveSize;
      if (dump.children === undefined || dump.children.length === 0) {
        // Leaf dump.
        effectiveSize = getSize(dump) * dump.cumulativeOwningCoefficient_ *
            dump.cumulativeOwnedCoefficient_;
      } else {
        // Non-leaf dump.
        effectiveSize = 0;
        dump.children.forEach(function(childDump) {
          if (!hasSize(childDump))
            return;
          effectiveSize +=
              childDump.attributes[EFFECTIVE_SIZE_ATTRIBUTE_NAME].value;
        });
      }
      var attribute = new tr.model.ScalarAttribute('bytes', effectiveSize);
      dump.attributes[EFFECTIVE_SIZE_ATTRIBUTE_NAME] = attribute;

      // Add attribute infos regarding ownership (if applicable).
      // TODO(petrcermak): This belongs to the corresponding analysis UI code.
      if (dump.ownedBy.length > 0) {
        var message = 'shared by:' +
            dump.ownedBy.map(function(ownershipLink) {
              return '\n  - ' + ownershipToUserFriendlyString(
                  ownershipLink.source, ownershipLink.importance);
            }).join();
        attribute.infos.push(new tr.model.AttributeInfo(
            tr.model.AttributeInfoType.MEMORY_OWNED, message));
      }
      if (dump.owns !== undefined) {
        var target = dump.owns.target;
        var message = 'shares ' +
            ownershipToUserFriendlyString(target, dump.owns.importance) +
            ' with';

        var otherOwnershipLinks = target.ownedBy.filter(
            function(ownershipLink) {
          return ownershipLink.source !== dump;
        });
        if (otherOwnershipLinks.length > 0) {
          message += ':';
          message += otherOwnershipLinks.map(function(ownershipLink) {
            return '\n  - ' + ownershipToUserFriendlyString(
                ownershipLink.source, ownershipLink.importance);
          }).join();
        } else {
          message += ' no other dumps';
        }

        attribute.infos.push(new tr.model.AttributeInfo(
            tr.model.AttributeInfoType.MEMORY_OWNER, message));
      }
    }
function ( dump ) { // Completely skip dumps with undefined size. As a result, each dump will // have defined effective size if and only if it has defined size. if ( ! hasSize ( dump ) ) { // The rest of the pipeline relies on effective size being either a // valid ScalarAttribute, or undefined. dump . attributes [ EFFECTIVE_SIZE_ATTRIBUTE_NAME ] = undefined ; return ; } var effectiveSize ; if ( dump . children === undefined || dump . children . length === 0 ) { // Leaf dump. effectiveSize = getSize ( dump ) * dump . cumulativeOwningCoefficient_ * dump . cumulativeOwnedCoefficient_ ; } else { // Non-leaf dump. effectiveSize = 0 ; dump . children . forEach ( function ( childDump ) { if ( ! hasSize ( childDump ) ) return ; effectiveSize += childDump . attributes [ EFFECTIVE_SIZE_ATTRIBUTE_NAME ] . value ; } ) ; } var attribute = new tr . model . ScalarAttribute ( 'bytes' , effectiveSize ) ; dump . attributes [ EFFECTIVE_SIZE_ATTRIBUTE_NAME ] = attribute ; // Add attribute infos regarding ownership (if applicable). // TODO(petrcermak): This belongs to the corresponding analysis UI code. if ( dump . ownedBy . length > 0 ) { var message = 'shared by:' + dump . ownedBy . map ( function ( ownershipLink ) { return '\n  - ' + ownershipToUserFriendlyString ( ownershipLink . source , ownershipLink . importance ) ; } ) . join ( ) ; attribute . infos . push ( new tr . model . AttributeInfo ( tr . model . AttributeInfoType . MEMORY_OWNED , message ) ) ; } if ( dump . owns !== undefined ) { var target = dump . owns . target ; var message = 'shares ' + ownershipToUserFriendlyString ( target , dump . owns . importance ) + ' with' ; var otherOwnershipLinks = target . ownedBy . filter ( function ( ownershipLink ) { return ownershipLink . source !== dump ; } ) ; if ( otherOwnershipLinks . length > 0 ) { message += ':' ; message += otherOwnershipLinks . map ( function ( ownershipLink ) { return '\n  - ' + ownershipToUserFriendlyString ( ownershipLink . source , ownershipLink . importance ) ; } ) . join ( ) ; } else { message += ' no other dumps' ; } attribute . infos . push ( new tr . model . AttributeInfo ( tr . model . AttributeInfoType . MEMORY_OWNER , message ) ) ; } }
Calculate the effective size of a memory allocator dump.

In order to simplify the (already complex) calculation, we use the fact
that effective size is cumulative (unlike regular size), i.e. the
effective size of a non-leaf node is equal to the sum of effective sizes
of its children. The effective size of a leaf MAD is calculated as:

effectiveSize(M) = size(M) * cumulativeOwningC(M) * cumulativeOwnedC(M)

This method assumes that (1) the size of the dump and its children [see
calculateSizes()] and (2) the cumulative owning and owned coefficients
of the dump (if it's a leaf node) [see the third step of
calculateEffectiveSizes()] or the effective sizes of its children (if
it's a non-leaf node) [depth-first post-order traversal] have already
been calculated.
Calculate the effective size of a memory allocator dump .