<commit_before>#include "builtin/contexts.hpp"
#include "objectmemory.hpp"
#include "builtin/block_environment.hpp"

#define CountContextCaches 2

/* These numbers were taken from Squeak */
#define SmallContextSize   16
#define SmallContextCache  0
#define LargeContextSize   56
#define LargeContextCache  1

namespace rubinius {

  /* Implements a simple context cache based on having context of a couple
   * sizes only. This implementation also support 'huge' contexts by
   * always just heap allocating them. */
  class ContextCache {
  public:
    /* A stack depth, indicates how many more contexts we can recycle.
     * This is reset to 0 if it's determined that context recycle needs
     * to be disabled for all current contexts. */
    int reclaim;

    /* A simple array of MethodContext's. The contexts are treated like
     * linked lists, chaining to the next context off their home field.
     * This lets us store any number of contexts quickly in a couple
     * of different caches. Each cache contains context of all the same
     * size. */
    MethodContext* caches[CountContextCaches];

    /* Reset all state to empty. */
    void reset() {
      reclaim = 0;
      for(size_t i = 0; i < CountContextCaches; i++) {
        caches[i] = (MethodContext*)Qnil;
      }
    }

    /* Retrieve a context from +which+ cache. Return NULL if the cache
     * was empty. */
    MethodContext* get(size_t which) {
      MethodContext* ctx;
      if((ctx = caches[which]) != Qnil) {
        /* We chain off ->home */
        caches[which] = ctx->home;
        return ctx;
      }

      return NULL;
    }

    /* Add context +ctx+ to cache +which+. */
    void add(size_t which, MethodContext* ctx) {
      ctx->home = caches[which];
      caches[which] = ctx;

      reclaim--;
    }
  };

  /* Calculate how much big of an object (in bytes) to allocate
   * for one with a body of +original+ and a stack of +stack+ */
  static size_t add_stack(size_t original, size_t stack) {
    return original + (sizeof(OBJECT) * stack);
  }

  /* Initialize +ctx+'s fields */
  static void init_context(STATE, MethodContext* ctx, size_t stack) {
    ctx->ip = 0;
    SET(ctx, block, Qnil);
    SET(ctx, name, Qnil);
    SET(ctx, home, Qnil);

    ctx->stack_size = stack;
    for(size_t i = 0; i < stack; i++) {
      ctx->stk[i] = Qnil;
    }

    ctx->js.stack = ctx->stk - 1;
  }

  /* Find a context to use. Either use a cache or create one in the heap. */
  static MethodContext* allocate(STATE, Class* cls, size_t stack_size) {
    MethodContext* ctx;
    size_t which_cache = SmallContextCache;

    /* If it's small enough, use the set small size. */
    if(stack_size < SmallContextSize) {
      stack_size = SmallContextSize;

    /* If it's bigger than our large size, always use the heap. */
    } else if(stack_size > LargeContextSize) {
      goto allocate_heap;

    /* Otherwise use a large size. */
    } else {
      stack_size = LargeContextSize;
      which_cache = LargeContextCache;
    }

    if((ctx = state->context_cache->get(which_cache)) != NULL) {
      goto initialize;
    }

allocate_heap:
    size_t bytes = add_stack(sizeof(MethodContext), stack_size);<commit_msg>moved initialization of variable bytes out of goto block to make the compiler happier<commit_after>#include "builtin/contexts.hpp"
#include "objectmemory.hpp"
#include "builtin/block_environment.hpp"

#define CountContextCaches 2

/* These numbers were taken from Squeak */
#define SmallContextSize   16
#define SmallContextCache  0
#define LargeContextSize   56
#define LargeContextCache  1

namespace rubinius {

  /* Implements a simple context cache based on having context of a couple
   * sizes only. This implementation also support 'huge' contexts by
   * always just heap allocating them. */
  class ContextCache {
  public:
    /* A stack depth, indicates how many more contexts we can recycle.
     * This is reset to 0 if it's determined that context recycle needs
     * to be disabled for all current contexts. */
    int reclaim;

    /* A simple array of MethodContext's. The contexts are treated like
     * linked lists, chaining to the next context off their home field.
     * This lets us store any number of contexts quickly in a couple
     * of different caches. Each cache contains context of all the same
     * size. */
    MethodContext* caches[CountContextCaches];

    /* Reset all state to empty. */
    void reset() {
      reclaim = 0;
      for(size_t i = 0; i < CountContextCaches; i++) {
        caches[i] = (MethodContext*)Qnil;
      }
    }

    /* Retrieve a context from +which+ cache. Return NULL if the cache
     * was empty. */
    MethodContext* get(size_t which) {
      MethodContext* ctx;
      if((ctx = caches[which]) != Qnil) {
        /* We chain off ->home */
        caches[which] = ctx->home;
        return ctx;
      }

      return NULL;
    }

    /* Add context +ctx+ to cache +which+. */
    void add(size_t which, MethodContext* ctx) {
      ctx->home = caches[which];
      caches[which] = ctx;

      reclaim--;
    }
  };

  /* Calculate how much big of an object (in bytes) to allocate
   * for one with a body of +original+ and a stack of +stack+ */
  static size_t add_stack(size_t original, size_t stack) {
    return original + (sizeof(OBJECT) * stack);
  }

  /* Initialize +ctx+'s fields */
  static void init_context(STATE, MethodContext* ctx, size_t stack) {
    ctx->ip = 0;
    SET(ctx, block, Qnil);
    SET(ctx, name, Qnil);
    SET(ctx, home, Qnil);

    ctx->stack_size = stack;
    for(size_t i = 0; i < stack; i++) {
      ctx->stk[i] = Qnil;
    }

    ctx->js.stack = ctx->stk - 1;
  }

  /* Find a context to use. Either use a cache or create one in the heap. */
  static MethodContext* allocate(STATE, Class* cls, size_t stack_size) {
    MethodContext* ctx;
    size_t which_cache = SmallContextCache;
    size_t bytes;

    /* If it's small enough, use the set small size. */
    if(stack_size < SmallContextSize) {
      stack_size = SmallContextSize;

    /* If it's bigger than our large size, always use the heap. */
    } else if(stack_size > LargeContextSize) {
      goto allocate_heap;

    /* Otherwise use a large size. */
    } else {
      stack_size = LargeContextSize;
      which_cache = LargeContextCache;
    }

    if((ctx = state->context_cache->get(which_cache)) != NULL) {
      goto initialize;
    }

allocate_heap:
    bytes = add_stack(sizeof(MethodContext), stack_size);
{'fraction_non_alphanumeric': 0.10189609989209188, 'fraction_numerical': 0.004008016032064128, 'mean_word_length': 2.7394812680115272, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4788749', 'n_tokens_mistral': 2004, 'n_tokens_neox': 1936, 'n_words': 701}