# Global Metrics

path: .metrics.nexits.average
old: 0.6666666666666666
new: 0.625
path: .metrics.nexits.sum
old: 2.0
new: 10.0
path: .metrics.mi.mi_original
old: 47.36758446757308
new: 34.47695963612769
path: .metrics.mi.mi_sei
old: 29.53892801721436
new: 14.120119608881318
path: .metrics.mi.mi_visual_studio
old: 27.700341793902385
new: 20.16196469948988
path: .metrics.nargs.sum
old: 9.0
new: 4.0
path: .metrics.nargs.average
old: 3.0
new: 0.25
path: .metrics.cognitive.sum
old: 16.0
new: 8.0
path: .metrics.cognitive.average
old: 5.333333333333333
new: 0.5
path: .metrics.halstead.bugs
old: 1.1770127325598896
new: 1.1121853057972957
path: .metrics.halstead.level
old: 0.013403880070546737
new: 0.01908957415565345
path: .metrics.halstead.purity_ratio
old: 0.7019340643881582
new: 0.9618939744912592
path: .metrics.halstead.N1
old: 257.0
new: 333.0
path: .metrics.halstead.difficulty
old: 74.60526315789474
new: 52.38461538461539
path: .metrics.halstead.length
old: 467.0
new: 560.0
path: .metrics.halstead.n1
old: 27.0
new: 30.0
path: .metrics.halstead.n2
old: 38.0
new: 65.0
path: .metrics.halstead.effort
old: 209823.2566899989
new: 192729.24113793
path: .metrics.halstead.estimated_program_length
old: 327.8032080692699
new: 538.6606257151051
path: .metrics.halstead.time
old: 11656.847593888828
new: 10707.180063218337
path: .metrics.halstead.N2
old: 210.0
new: 227.0
path: .metrics.halstead.volume
old: 2812.4457686842884
new: 3679.11914066533
path: .metrics.halstead.vocabulary
old: 65.0
new: 95.0
path: .metrics.loc.lloc
old: 49.0
new: 36.0
path: .metrics.loc.blank
old: 6.0
new: 33.0
path: .metrics.loc.cloc
old: 35.0
new: 62.0
path: .metrics.loc.sloc
old: 134.0
new: 214.0
path: .metrics.loc.ploc
old: 93.0
new: 119.0
path: .metrics.cyclomatic.average
old: 3.25
new: 1.4285714285714286
path: .metrics.cyclomatic.sum
old: 13.0
new: 30.0
path: .metrics.nom.functions
old: 3.0
new: 16.0
path: .metrics.nom.total
old: 3.0
new: 16.0

# Spaces Data

## Minimal test - lines (23, 212)

path: .spaces[0].metrics.loc.ploc
old: 6.0
new: 105.0
path: .spaces[0].metrics.loc.sloc
old: 6.0
new: 190.0
path: .spaces[0].metrics.loc.blank
old: 0.0
new: 30.0
path: .spaces[0].metrics.loc.lloc
old: 2.0
new: 36.0
path: .spaces[0].metrics.loc.cloc
old: 0.0
new: 55.0
path: .spaces[0].metrics.nom.functions
old: 1.0
new: 16.0
path: .spaces[0].metrics.nom.total
old: 1.0
new: 16.0
path: .spaces[0].metrics.cyclomatic.average
old: 1.0
new: 1.45
path: .spaces[0].metrics.cyclomatic.sum
old: 1.0
new: 29.0
path: .spaces[0].metrics.mi.mi_original
old: 115.7111656028849
new: 36.8657240421452
path: .spaces[0].metrics.mi.mi_sei
old: 91.33689265815536
new: 17.45266100771967
path: .spaces[0].metrics.mi.mi_visual_studio
old: 67.66734830578065
new: 21.55890294862293
path: .spaces[0].metrics.nexits.sum
old: 1.0
new: 10.0
path: .spaces[0].metrics.nexits.average
old: 1.0
new: 0.625
path: .spaces[0].metrics.cognitive.sum
old: 0.0
new: 8.0
path: .spaces[0].metrics.cognitive.average
old: 0.0
new: 0.5
path: .spaces[0].metrics.halstead.time
old: 56.56772438427192
new: 11515.927496529594
path: .spaces[0].metrics.halstead.n1
old: 10.0
new: 30.0
path: .spaces[0].metrics.halstead.level
old: 0.14666666666666667
new: 0.016975308641975308
path: .spaces[0].metrics.halstead.estimated_program_length
old: 71.27302875388389
new: 465.18150211211184
path: .spaces[0].metrics.halstead.N1
old: 19.0
new: 333.0
path: .spaces[0].metrics.halstead.purity_ratio
old: 2.0962655515848203
new: 0.8473251404592201
path: .spaces[0].metrics.halstead.n2
old: 11.0
new: 55.0
path: .spaces[0].metrics.halstead.effort
old: 1018.2190389168944
new: 207286.69493753268
path: .spaces[0].metrics.halstead.N2
old: 15.0
new: 216.0
path: .spaces[0].metrics.halstead.bugs
old: 0.033736981332150334
new: 1.167507547056946
path: .spaces[0].metrics.halstead.difficulty
old: 6.818181818181818
new: 58.90909090909091
path: .spaces[0].metrics.halstead.vocabulary
old: 21.0
new: 85.0
path: .spaces[0].metrics.halstead.volume
old: 149.33879237447786
new: 3518.755623939598
path: .spaces[0].metrics.halstead.length
old: 34.0
new: 549.0
path: .spaces[0].metrics.nargs.average
old: 2.0
new: 0.25
path: .spaces[0].metrics.nargs.sum
old: 2.0
new: 4.0

### Code

    namespace mozilla {

    /**
     * A very simple arena allocator based on NSPR's PLArena.
     *
     * The arena allocator only provides for allocation, all memory is retained
     * until the allocator is destroyed. It's useful for situations where a large
     * amount of small transient allocations are expected.
     *
     * Example usage:
     *
     * // Define an allocator that is page sized and returns allocations that are
     * // 8-byte aligned.
     * ArenaAllocator<4096, 8> a;
     * for (int i = 0; i < 1000; i++) {
     *   DoSomething(a.Allocate(i));
     * }
     */
    template
    class ArenaAllocator {
     public:
      constexpr ArenaAllocator() : mHead(), mCurrent(nullptr) {
        static_assert(mozilla::tl::FloorLog2::value ==
                          mozilla::tl::CeilingLog2::value,
                      "ArenaAllocator alignment must be a power of two");
      }

      ArenaAllocator(const ArenaAllocator&) = delete;
      ArenaAllocator& operator=(const ArenaAllocator&) = delete;

      /**
       * Frees all internal arenas but does not call destructors for objects
       * allocated out of the arena.
       */
      ~ArenaAllocator() { Clear(); }

      /**
       * Fallibly allocates a chunk of memory with the given size from the internal
       * arenas. If the allocation size is larger than the chosen arena a size an
       * entire arena is allocated and used.
       */
      MOZ_ALWAYS_INLINE void* Allocate(size_t aSize, const fallible_t&) {
        MOZ_RELEASE_ASSERT(aSize, "Allocation size must be non-zero");
        return InternalAllocate(AlignedSize(aSize));
      }

      void* Allocate(size_t aSize) {
        void* p = Allocate(aSize, fallible);
        if (MOZ_UNLIKELY(!p)) {
          NS_ABORT_OOM(std::max(aSize, ArenaSize));
        }

        return p;
      }

      /**
       * Frees all entries. The allocator can be reused after this is called.
       *
       * NB: This will not run destructors of any objects that were allocated from
       * the arena.
       */
      void Clear() {
        // Free all chunks.
        auto a = mHead.next;
        while (a) {
          auto tmp = a;
          a = a->next;
          free(tmp);
        }

        // Reset the list head.
        mHead.next = nullptr;
        mCurrent = nullptr;
      }

      /**
       * Adjusts the given size to the required alignment.
       */
      static constexpr size_t AlignedSize(size_t aSize) {
        return (aSize + (Alignment - 1)) & ~(Alignment - 1);
      }

      size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const {
        size_t s = 0;
        for (auto arena = mHead.next; arena; arena = arena->next) {
          s += aMallocSizeOf(arena);
        }

        return s;
      }

      void Check() {
        if (mCurrent) {
          mCurrent->canary.Check();
        }
      }

     private:
      struct ArenaHeader {
        /**
         * The location in memory of the data portion of the arena.
         */
        uintptr_t offset;
        /**
         * The location in memory of the end of the data portion of the arena.
         */
        uintptr_t tail;
      };

      struct ArenaChunk {
        constexpr ArenaChunk() : header{0, 0}, next(nullptr) {}

        explicit ArenaChunk(size_t aSize)
            : header{AlignedSize(uintptr_t(this + 1)), uintptr_t(this) + aSize},
              next(nullptr) {}

        CorruptionCanary canary;
        ArenaHeader header;
        ArenaChunk* next;

        /**
         * Allocates a chunk of memory out of the arena and advances the offset.
         */
        void* Allocate(size_t aSize) {
          MOZ_ASSERT(aSize <= Available());
          char* p = reinterpret_cast(header.offset);
          MOZ_RELEASE_ASSERT(p);
          header.offset += aSize;
          canary.Check();
          MOZ_MAKE_MEM_UNDEFINED(p, aSize);
          return p;
        }

        /**
         * Calculates the amount of space available for allocation in this chunk.
         */
        size_t Available() const { return header.tail - header.offset; }
      };

      /**
       * Allocates an arena chunk of the given size and initializes its header.
       */
      ArenaChunk* AllocateChunk(size_t aSize) {
        static const size_t kOffset = AlignedSize(sizeof(ArenaChunk));
        MOZ_ASSERT(kOffset < aSize);

        const size_t chunkSize = aSize + kOffset;
        void* p = malloc(chunkSize);
        if (!p) {
          return nullptr;
        }

        ArenaChunk* arena = new (KnownNotNull, p) ArenaChunk(chunkSize);
        MOZ_MAKE_MEM_NOACCESS((void*)arena->header.offset,
                              arena->header.tail - arena->header.offset);

        // Insert into the head of the list.
        arena->next = mHead.next;
        mHead.next = arena;

        // Only update |mCurrent| if this is a standard allocation, large
        // allocations will always end up full so there's no point in updating
        // |mCurrent| in that case.
        if (aSize == ArenaSize - kOffset) {
          mCurrent = arena;
        }

        return arena;
      }

      MOZ_ALWAYS_INLINE void* InternalAllocate(size_t aSize) {
        static_assert(ArenaSize > AlignedSize(sizeof(ArenaChunk)),
                      "Arena size must be greater than the header size");

        static const size_t kMaxArenaCapacity =
            ArenaSize - AlignedSize(sizeof(ArenaChunk));

        if (mCurrent && aSize <= mCurrent->Available()) {
          return mCurrent->Allocate(aSize);
        }

        ArenaChunk* arena = AllocateChunk(std::max(kMaxArenaCapacity, aSize));
        return arena ? arena->Allocate(aSize) : nullptr;
      }

      ArenaChunk mHead;
      ArenaChunk* mCurrent;
    };

    }  // namespace mozilla