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;
};