<commit_before>// railgun vm stack
// construct Frame on this stack,
// and traverse Frames when GC maker comes
#ifndef IV_LV5_RAILGUN_STACK_H_
#define IV_LV5_RAILGUN_STACK_H_
#include <cstddef>
#include <cmath>
#include <algorithm>
#include <iterator>
#include <new>
#include "noncopyable.h"
#include "singleton.h"
#include "os_allocator.h"
#include "lv5/internal.h"
#include "lv5/jsval.h"
#include "lv5/gc_kind.h"
#include "lv5/railgun/frame.h"
#include "lv5/railgun/direct_threading.h"
namespace iv {
namespace lv5 {
namespace railgun {

class Stack : core::Noncopyable<Stack> {
 public:
  typedef JSVal* iterator;
  typedef const JSVal* const_iterator;

  typedef std::iterator_traits<iterator>::value_type value_type;

  typedef std::iterator_traits<iterator>::pointer pointer;
  typedef std::iterator_traits<const_iterator>::pointer const_pointer;
  typedef std::iterator_traits<iterator>::reference reference;
  typedef std::iterator_traits<const_iterator>::reference const_reference;

  typedef std::reverse_iterator<iterator> reverse_iterator;
  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;

  typedef std::iterator_traits<iterator>::difference_type difference_type;
  typedef std::size_t size_type;

  // not bytes. JSVals capacity.
  // if you calc bytes, sizeof(JSVal) * kStackCapacity
  static const size_type kStackCapacity = 16 * 1024;
  static const size_type kStackBytes = kStackCapacity * sizeof(JSVal);

  // bytes. 4KB is page size.
  static const size_type kCommitSize = 4 * core::Size::KB;

  class Resource : public GCKind<Resource> {
   public:
    explicit Resource(Stack* stack)
      : stack_(stack) {
    }

    Stack* stack() const {
      return stack_;
    }

    GC_ms_entry* MarkChildren(GC_word* top,
                              GC_ms_entry* entry,
                              GC_ms_entry* mark_sp_limit,
                              GC_word env) {
      if (stack_) {
        Frame* current = stack_->current_;
        if (current) {
          // mark Frame member
          entry = MarkFrame(entry, mark_sp_limit,
                            current, stack_->stack_pointer_);
          // traverse frames
          for (Frame *next = current, *now = current->prev_;
               now; next = now, now = next->prev_) {
            entry = MarkFrame(entry, mark_sp_limit, now, next->GetFrameBase());
          }
        }
      }
      return entry;
    }

   private:
    Stack* stack_;
  };

  Stack()
    : stack_(NULL),
      stack_pointer_(NULL),
      resource_(NULL),
      base_(NULL),
      current_(NULL) {
    stack_pointer_ = stack_ =
        reinterpret_cast<JSVal*>(GC_MALLOC(kStackBytes));
//    stack_pointer_ = stack_ =
//        reinterpret_cast<JSVal*>(
//            core::OSAllocator::Allocate(kStackBytes));
    stack_pointer_ += 1;  // for Global This
    // register root
    // resource_ = new Resource(this);
  }

  explicit Stack(DispatchTableTag tag) { }  // empty

  ~Stack() {
    if (stack_) {  // normal pass
//      core::OSAllocator::Decommit(stack_, kStackBytes);
//      core::OSAllocator::Deallocate(stack_, kStackBytes);
      // GC_free(resource_);
    }
  }

  // returns new frame for function call
  Frame* NewCodeFrame(Context* ctx,
                      JSVal* sp,
                      Code* code,
                      JSEnv* env,
                      Instruction* pc,
                      std::size_t argc,
                      bool constructor_call) {
    assert(code);
    if (JSVal* mem = GainFrame(sp, code)) {
      Frame* frame = reinterpret_cast<Frame*>(mem);
      frame->code_ = code;
      frame->prev_pc_ = pc;
      if (code->HasDeclEnv()) {
        frame->variable_env_ = frame->lexical_env_ =<commit_msg>fix stack<commit_after>// railgun vm stack
// construct Frame on this stack,
// and traverse Frames when GC maker comes
#ifndef IV_LV5_RAILGUN_STACK_H_
#define IV_LV5_RAILGUN_STACK_H_
#include <cstddef>
#include <cmath>
#include <algorithm>
#include <iterator>
#include <new>
#include "noncopyable.h"
#include "singleton.h"
#include "os_allocator.h"
#include "lv5/internal.h"
#include "lv5/jsval.h"
#include "lv5/gc_kind.h"
#include "lv5/railgun/frame.h"
#include "lv5/railgun/direct_threading.h"
namespace iv {
namespace lv5 {
namespace railgun {

class Stack : core::Noncopyable<Stack> {
 public:
  typedef JSVal* iterator;
  typedef const JSVal* const_iterator;

  typedef std::iterator_traits<iterator>::value_type value_type;

  typedef std::iterator_traits<iterator>::pointer pointer;
  typedef std::iterator_traits<const_iterator>::pointer const_pointer;
  typedef std::iterator_traits<iterator>::reference reference;
  typedef std::iterator_traits<const_iterator>::reference const_reference;

  typedef std::reverse_iterator<iterator> reverse_iterator;
  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;

  typedef std::iterator_traits<iterator>::difference_type difference_type;
  typedef std::size_t size_type;

  // not bytes. JSVals capacity.
  // if you calc bytes, sizeof(JSVal) * kStackCapacity
  static const size_type kStackCapacity = 16 * 1024;
  static const size_type kStackBytes = kStackCapacity * sizeof(JSVal);

  // bytes. 4KB is page size.
  static const size_type kCommitSize = 4 * core::Size::KB;

  class Resource : public GCKind<Resource> {
   public:
    explicit Resource(Stack* stack)
      : stack_(stack) {
    }

    Stack* stack() const {
      return stack_;
    }

    GC_ms_entry* MarkChildren(GC_word* top,
                              GC_ms_entry* entry,
                              GC_ms_entry* mark_sp_limit,
                              GC_word env) {
      if (stack_) {
        Frame* current = stack_->current_;
        if (current) {
          // mark Frame member
          entry = MarkFrame(entry, mark_sp_limit,
                            current, stack_->stack_pointer_);
          // traverse frames
          for (Frame *next = current, *now = current->prev_;
               now; next = now, now = next->prev_) {
            entry = MarkFrame(entry, mark_sp_limit, now, next->GetFrameBase());
          }
        }
      }
      return entry;
    }

   private:
    Stack* stack_;
  };

  Stack()
    : stack_(NULL),
      stack_pointer_(NULL),
      resource_(NULL),
      base_(NULL),
      current_(NULL) {
    stack_pointer_ = stack_ =
        reinterpret_cast<JSVal*>(
            core::OSAllocator::Allocate(kStackBytes));
    stack_pointer_ += 1;  // for Global This
    // register root
    resource_ = new Resource(this);
  }

  explicit Stack(DispatchTableTag tag) { }  // empty

  ~Stack() {
    if (stack_) {  // normal pass
      core::OSAllocator::Decommit(stack_, kStackBytes);
      core::OSAllocator::Deallocate(stack_, kStackBytes);
      delete resource_;
    }
  }

  // returns new frame for function call
  Frame* NewCodeFrame(Context* ctx,
                      JSVal* sp,
                      Code* code,
                      JSEnv* env,
                      Instruction* pc,
                      std::size_t argc,
                      bool constructor_call) {
    assert(code);
    if (JSVal* mem = GainFrame(sp, code)) {
      Frame* frame = reinterpret_cast<Frame*>(mem);
      frame->code_ = code;
      frame->prev_pc_ = pc;
      if (code->HasDeclEnv()) {
        frame->variable_env_ = frame->lexical_env_ =
{'fraction_non_alphanumeric': 0.11011419249592169, 'fraction_numerical': 0.004622077215878194, 'mean_word_length': 2.631293188548865, 'pattern_counts': {'":': 0, '<': 38, '<?xml version=': 0, '>': 58, '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': '6239231', 'n_tokens_mistral': 2277, 'n_tokens_neox': 2192, 'n_words': 517}