# Global Metrics

path: .metrics.loc.cloc
old: 8.0
new: 125.0
path: .metrics.loc.ploc
old: 120.0
new: 40.0
path: .metrics.loc.lloc
old: 35.0
new: 5.0
path: .metrics.loc.sloc
old: 155.0
new: 183.0
path: .metrics.loc.blank
old: 27.0
new: 18.0
path: .metrics.cyclomatic.average
old: 1.3448275862068966
new: 1.0
path: .metrics.cyclomatic.sum
old: 39.0
new: 7.0
path: .metrics.cognitive.average
old: 0.07692307692307693
new: 0.0
path: .metrics.cognitive.sum
old: 2.0
new: 0.0
path: .metrics.mi.mi_visual_studio
old: 21.66091843896252
new: 28.400203559541048
path: .metrics.mi.mi_original
old: 37.040170530625915
new: 48.56434808681519
path: .metrics.mi.mi_sei
old: -1.0556162047710025
new: 42.9815079482954
path: .metrics.nargs.sum
old: 18.0
new: 0.0
path: .metrics.nargs.average
old: 0.6923076923076923
new: 0.0
path: .metrics.nexits.average
old: 0.7307692307692307
new: 1.25
path: .metrics.nexits.sum
old: 19.0
new: 5.0
path: .metrics.nom.total
old: 26.0
new: 4.0
path: .metrics.nom.functions
old: 26.0
new: 4.0
path: .metrics.halstead.n2
old: 74.0
new: 40.0
path: .metrics.halstead.vocabulary
old: 94.0
new: 56.0
path: .metrics.halstead.bugs
old: 0.94282446175728
new: 0.21067276088326445
path: .metrics.halstead.difficulty
old: 36.48648648648648
new: 14.4
path: .metrics.halstead.estimated_program_length
old: 545.9381109542895
new: 276.8771237954945
path: .metrics.halstead.level
old: 0.027407407407407408
new: 0.06944444444444445
path: .metrics.halstead.N1
old: 359.0
new: 118.0
path: .metrics.halstead.N2
old: 270.0
new: 72.0
path: .metrics.halstead.n1
old: 20.0
new: 16.0
path: .metrics.halstead.time
old: 8357.100785888988
new: 882.7179481527558
path: .metrics.halstead.volume
old: 4122.836387705234
new: 1103.3974351909446
path: .metrics.halstead.effort
old: 150427.8141460018
new: 15888.923066749603
path: .metrics.halstead.length
old: 629.0
new: 190.0
path: .metrics.halstead.purity_ratio
old: 0.8679461223438625
new: 1.457248019976287

# Spaces Data

## Minimal test - lines (14, 14)

path: .spaces[0].metrics.nexits.sum
old: 14.0
new: 0.0
path: .spaces[0].metrics.nexits.average
old: 0.875
new: null
path: .spaces[0].metrics.mi.mi_sei
old: 9.028832232369844
new: null
path: .spaces[0].metrics.mi.mi_original
old: 51.158900524412914
new: null
path: .spaces[0].metrics.mi.mi_visual_studio
old: 29.917485686791174
new: null
path: .spaces[0].metrics.nargs.average
old: 0.75
new: null
path: .spaces[0].metrics.nargs.sum
old: 12.0
new: 0.0
path: .spaces[0].metrics.cyclomatic.sum
old: 27.0
new: 1.0
path: .spaces[0].metrics.cyclomatic.average
old: 1.588235294117647
new: 1.0
path: .spaces[0].metrics.nom.functions
old: 16.0
new: 0.0
path: .spaces[0].metrics.nom.total
old: 16.0
new: 0.0
path: .spaces[0].metrics.cognitive.sum
old: 2.0
new: 0.0
path: .spaces[0].metrics.cognitive.average
old: 0.125
new: null
path: .spaces[0].metrics.halstead.level
old: 0.02842639593908629
new: null
path: .spaces[0].metrics.halstead.n2
old: 42.0
new: 1.0
path: .spaces[0].metrics.halstead.volume
old: 2613.134726345804
new: 0.0
path: .spaces[0].metrics.halstead.time
old: 5107.019256846463
new: 0.0
path: .spaces[0].metrics.halstead.length
old: 448.0
new: 1.0
path: .spaces[0].metrics.halstead.vocabulary
old: 57.0
new: 1.0
path: .spaces[0].metrics.halstead.effort
old: 91926.34662323631
new: 0.0
path: .spaces[0].metrics.halstead.purity_ratio
old: 0.6363408274349011
new: null
path: .spaces[0].metrics.halstead.difficulty
old: 35.17857142857143
new: 0.0
path: .spaces[0].metrics.halstead.N2
old: 197.0
new: 1.0
path: .spaces[0].metrics.halstead.estimated_program_length
old: 285.0806906908357
new: null
path: .spaces[0].metrics.halstead.n1
old: 15.0
new: 0.0
path: .spaces[0].metrics.halstead.N1
old: 251.0
new: 0.0
path: .spaces[0].metrics.halstead.bugs
old: 0.6789514898415978
new: 0.0
path: .spaces[0].metrics.loc.ploc
old: 79.0
new: 1.0
path: .spaces[0].metrics.loc.cloc
old: 1.0
new: 0.0
path: .spaces[0].metrics.loc.blank
old: 9.0
new: 0.0
path: .spaces[0].metrics.loc.sloc
old: 89.0
new: 1.0
path: .spaces[0].metrics.loc.lloc
old: 26.0
new: 0.0

### Code

    struct already_AddRefed;

## Minimal test - lines (25, 181)

path: .spaces[1].metrics.mi.mi_visual_studio
old: 73.26698838756
new: 30.31040945619261
path: .spaces[1].metrics.mi.mi_original
old: 125.2865501427276
new: 51.83080017008936
path: .spaces[1].metrics.mi.mi_sei
old: 105.15125244839123
new: 47.71830558267147
path: .spaces[1].metrics.cyclomatic.sum
old: 1.0
new: 5.0
path: .spaces[1].metrics.nargs.sum
old: 2.0
new: 0.0
path: .spaces[1].metrics.nargs.average
old: 2.0
new: 0.0
path: .spaces[1].metrics.nom.functions
old: 1.0
new: 4.0
path: .spaces[1].metrics.nom.total
old: 1.0
new: 4.0
path: .spaces[1].metrics.halstead.purity_ratio
old: 1.8244984312462555
new: 1.4185070415926582
path: .spaces[1].metrics.halstead.N1
old: 13.0
new: 114.0
path: .spaces[1].metrics.halstead.effort
old: 678.470647110665
new: 15018.917049186572
path: .spaces[1].metrics.halstead.length
old: 22.0
new: 181.0
path: .spaces[1].metrics.halstead.level
old: 0.1234567901234568
new: 0.06902985074626866
path: .spaces[1].metrics.halstead.n2
old: 5.0
new: 37.0
path: .spaces[1].metrics.halstead.N2
old: 9.0
new: 67.0
path: .spaces[1].metrics.halstead.estimated_program_length
old: 40.13896548741762
new: 256.74977452827113
path: .spaces[1].metrics.halstead.vocabulary
old: 14.0
new: 53.0
path: .spaces[1].metrics.halstead.n1
old: 9.0
new: 16.0
path: .spaces[1].metrics.halstead.difficulty
old: 8.1
new: 14.486486486486486
path: .spaces[1].metrics.halstead.time
old: 37.69281372837028
new: 834.3842805103652
path: .spaces[1].metrics.halstead.volume
old: 83.76180828526729
new: 1036.7536022759389
path: .spaces[1].metrics.halstead.bugs
old: 0.025737485850602416
new: 0.20291048599174463
path: .spaces[1].metrics.nexits.average
old: 1.0
new: 1.25
path: .spaces[1].metrics.nexits.sum
old: 1.0
new: 5.0
path: .spaces[1].metrics.loc.cloc
old: 0.0
new: 110.0
path: .spaces[1].metrics.loc.ploc
old: 4.0
new: 33.0
path: .spaces[1].metrics.loc.blank
old: 0.0
new: 14.0
path: .spaces[1].metrics.loc.lloc
old: 1.0
new: 5.0
path: .spaces[1].metrics.loc.sloc
old: 4.0
new: 157.0

### Code

    class nsStringBuffer {
     private:
      friend class CheckStaticAtomSizes;

      std::atomic mRefCount;
      uint32_t mStorageSize;

     public:
      /**
       * Allocates a new string buffer, with given size in bytes and a
       * reference count of one.  When the string buffer is no longer needed,
       * it should be released via Release.
       *
       * It is up to the caller to set the bytes corresponding to the string
       * buffer by calling the Data method to fetch the raw data pointer.  Care
       * must be taken to properly null terminate the character array.  The
       * storage size can be greater than the length of the actual string
       * (i.e., it is not required that the null terminator appear in the last
       * storage unit of the string buffer's data).
       *
       * @return new string buffer or null if out of memory.
       */
      static already_AddRefed Alloc(size_t aStorageSize);

      /**
       * Resizes the given string buffer to the specified storage size.  This
       * method must not be called on a readonly string buffer.  Use this API
       * carefully!!
       *
       * This method behaves like the ANSI-C realloc function.  (i.e., If the
       * allocation fails, null will be returned and the given string buffer
       * will remain unmodified.)
       *
       * @see IsReadonly
       */
      static nsStringBuffer* Realloc(nsStringBuffer* aBuf, size_t aStorageSize);

      /**
       * Increment the reference count on this string buffer.
       */
      void NS_FASTCALL AddRef();

      /**
       * Decrement the reference count on this string buffer.  The string
       * buffer will be destroyed when its reference count reaches zero.
       */
      void NS_FASTCALL Release();

      /**
       * This method returns the string buffer corresponding to the given data
       * pointer.  The data pointer must have been returned previously by a
       * call to the nsStringBuffer::Data method.
       */
      static nsStringBuffer* FromData(void* aData) {
        return reinterpret_cast(aData) - 1;
      }

      /**
       * This method returns the data pointer for this string buffer.
       */
      void* Data() const {
        return const_cast(reinterpret_cast(this + 1));
      }

      /**
       * This function returns the storage size of a string buffer in bytes.
       * This value is the same value that was originally passed to Alloc (or
       * Realloc).
       */
      uint32_t StorageSize() const { return mStorageSize; }

      /**
       * If this method returns false, then the caller can be sure that their
       * reference to the string buffer is the only reference to the string
       * buffer, and therefore it has exclusive access to the string buffer and
       * associated data.  However, if this function returns true, then other
       * consumers may rely on the data in this buffer being immutable and
       * other threads may access this buffer simultaneously.
       */
      bool IsReadonly() const {
        // This doesn't lead to the destruction of the buffer, so we don't
        // need to perform acquire memory synchronization for the normal
        // reason that a reference count needs acquire synchronization
        // (ensuring that all writes to the object made on other threads are
        // visible to the thread destroying the object).
        //
        // We then need to consider the possibility that there were prior
        // writes to the buffer on a different thread:  one that has either
        // since released its reference count, or one that also has access
        // to this buffer through the same reference.  There are two ways
        // for that to happen: either the buffer pointer or a data structure
        // (e.g., string object) pointing to the buffer was transferred from
        // one thread to another, or the data structure pointing to the
        // buffer was already visible on both threads.  In the first case
        // (transfer), the transfer of data from one thread to another would
        // have handled the memory synchronization.  In the latter case
        // (data structure visible on both threads), the caller needed some
        // sort of higher level memory synchronization to protect against
        // the string object being mutated at the same time on multiple
        // threads.

        // See bug 1603504. TSan might complain about a race when using
        // memory_order_relaxed, so use memory_order_acquire for making TSan
        // happy.
    #if defined(MOZ_TSAN)
        return mRefCount.load(std::memory_order_acquire) > 1;
    #else
        return mRefCount.load(std::memory_order_relaxed) > 1;
    #endif
      }

      /**
       * The FromString methods return a string buffer for the given string
       * object or null if the string object does not have a string buffer.
       * The reference count of the string buffer is NOT incremented by these
       * methods.  If the caller wishes to hold onto the returned value, then
       * the returned string buffer must have its reference count incremented
       * via a call to the AddRef method.
       */
      static nsStringBuffer* FromString(const nsAString& aStr);
      static nsStringBuffer* FromString(const nsACString& aStr);

      /**
       * The ToString methods assign this string buffer to a given string
       * object.  If the string object does not support sharable string
       * buffers, then its value will be set to a copy of the given string
       * buffer.  Otherwise, these methods increment the reference count of the
       * given string buffer.  It is important to specify the length (in
       * storage units) of the string contained in the string buffer since the
       * length of the string may be less than its storage size.  The string
       * must have a null terminator at the offset specified by |len|.
       *
       * NOTE: storage size is measured in bytes even for wide strings;
       *       however, string length is always measured in storage units
       *       (2-byte units for wide strings).
       */
      void ToString(uint32_t aLen, nsAString& aStr, bool aMoveOwnership = false);
      void ToString(uint32_t aLen, nsACString& aStr, bool aMoveOwnership = false);

      /**
       * This measures the size only if the StringBuffer is unshared.
       */
      size_t SizeOfIncludingThisIfUnshared(
          mozilla::MallocSizeOf aMallocSizeOf) const;

      /**
       * This measures the size regardless of whether the StringBuffer is
       * unshared.
       *
       * WARNING: Only use this if you really know what you are doing, because
       * it can easily lead to double-counting strings.  If you do use them,
       * please explain clearly in a comment why it's safe and won't lead to
       * double-counting.
       */
      size_t SizeOfIncludingThisEvenIfShared(
          mozilla::MallocSizeOf aMallocSizeOf) const;
    };