//===-- compute_size_class_config.cpp -------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <algorithm>
#include <vector>

struct Alloc {
  size_t size, count;
};

size_t measureWastage(const std::vector<Alloc> &allocs,
                      const std::vector<size_t> &classes, size_t pageSize,
                      size_t headerSize) {
  size_t totalWastage = 0;
  for (auto &a : allocs) {
    size_t sizePlusHeader = a.size + headerSize;
    size_t wastage = -1ull;
    for (auto c : classes)
      if (c >= sizePlusHeader && c - sizePlusHeader < wastage)
        wastage = c - sizePlusHeader;
    if (wastage == -1ull)
      continue;
    if (wastage > 2 * pageSize)
      wastage = 2 * pageSize;
    totalWastage += wastage * a.count;
  }
  return totalWastage;
}

void readAllocs(std::vector<Alloc> &allocs, const char *path) {
  FILE *f = fopen(path, "r");
  if (!f) {
    fprintf(stderr, "compute_size_class_config: could not open %s: %s\n", path,
            strerror(errno));
    exit(1);
  }

  const char header[] = "<malloc version=\"scudo-1\">\n";
  char buf[sizeof(header) - 1];
  if (fread(buf, 1, sizeof(header) - 1, f) != sizeof(header) - 1 ||
      memcmp(buf, header, sizeof(header) - 1) != 0) {
    fprintf(stderr, "compute_size_class_config: invalid input format\n");
    exit(1);
  }

  Alloc a;
  while (fscanf(f, "<alloc size=\"%zu\" count=\"%zu\"/>\n", &a.size,
                &a.count) == 2)
    allocs.push_back(a);
  fclose(f);
}

size_t log2Floor(size_t x) { return sizeof(long) * 8 - 1 - __builtin_clzl(x); }

void usage() {
  fprintf(stderr,
          "usage: compute_size_class_config [-p pageSize] [-c largestClass] "
          "[-h headerSize] [-n numClasses] [-b numBits] profile...\n");
  exit(1);
}

int main(int argc, char **argv) {
  size_t pageSize = 4096;
  size_t largestClass = 65552;
  size_t headerSize = 16;
  size_t numClasses = 32;
  size_t numBits = 5;

  std::vector<Alloc> allocs;
  for (size_t i = 1; i != argc;) {
    auto matchArg = [&](size_t &arg, const char *name) {
      if (strcmp(argv[i], name) == 0) {
        if (i + 1 != argc) {
          arg = atoi(argv[i + 1]);
          i += 2;
        } else {
          usage();
        }
        return true;
      }
      return false;
    };
    if (matchArg(pageSize, "-p") || matchArg(largestClass, "-c") ||
        matchArg(headerSize, "-h") || matchArg(numClasses, "-n") ||
        matchArg(numBits, "-b"))
      continue;
    readAllocs(allocs, argv[i]);
    ++i;
  }

  if (allocs.empty())
    usage();

  std::vector<size_t> classes;
  classes.push_back(largestClass);
  for (size_t i = 1; i != numClasses; ++i) {
    size_t minWastage = -1ull;
    size_t minWastageClass;
    for (size_t newClass = 16; newClass != largestClass; newClass += 16) {
      // Skip classes with more than numBits bits, ignoring leading or trailing
      // zero bits.
      if (__builtin_ctzl(newClass - headerSize) +
              __builtin_clzl(newClass - headerSize) <
          sizeof(long) * 8 - numBits)
        continue;

      classes.push_back(newClass);
      size_t newWastage = measureWastage(allocs, classes, pageSize, headerSize);
      classes.pop_back();
      if (newWastage < minWastage) {
        minWastage = newWastage;
        minWastageClass = newClass;
      }
    }
    classes.push_back(minWastageClass);
  }

  std::sort(classes.begin(), classes.end());
  size_t minSizeLog = log2Floor(headerSize);
  size_t midSizeIndex = 0;
  while (classes[midSizeIndex + 1] - classes[midSizeIndex] == (1 << minSizeLog))
    midSizeIndex++;
  size_t midSizeLog = log2Floor(classes[midSizeIndex] - headerSize);
  size_t maxSizeLog = log2Floor(classes.back() - headerSize - 1) + 1;

  printf(R"(// wastage = %zu

struct MySizeClassConfig {
  static const uptr NumBits = %zu;
  static const uptr MinSizeLog = %zu;
  static const uptr MidSizeLog = %zu;
  static const uptr MaxSizeLog = %zu;
  static const u32 MaxNumCachedHint = 14;
  static const uptr MaxBytesCachedLog = 14;

  static constexpr u32 Classes[] = {)",
         measureWastage(allocs, classes, pageSize, headerSize), numBits,
         minSizeLog, midSizeLog, maxSizeLog);
  for (size_t i = 0; i != classes.size(); ++i) {
    if ((i % 8) == 0)
      printf("\n      ");
    else
      printf(" ");
    printf("0x%05zx,", classes[i]);
  }
  printf(R"(
  };
  static const uptr SizeDelta = %zu;
};
)",
         headerSize);
}
