<commit_before>#include <iostream>

#include "vm.hpp"

#include "exception.hpp"
#include "exception_point.hpp"
#include "arguments.hpp"
#include "dispatch.hpp"
#include "native_libraries.hpp"
#include "primitives.hpp"
#include "call_frame.hpp"
#include "objectmemory.hpp"

#include "builtin/array.hpp"
#include "builtin/exception.hpp"
#include "builtin/nativemethod.hpp"
#include "builtin/string.hpp"
#include "builtin/system.hpp"
#include "builtin/tuple.hpp"
#include "builtin/capi_handle.hpp"

#include "instruments/profiler.hpp"

#include "capi/capi.hpp"
#include "capi/handle.hpp"

namespace rubinius {
  /** Thread-local NativeMethodEnvironment instance. */
  thread::ThreadData<NativeMethodEnvironment*> native_method_environment;

/* Class methods */

  NativeMethodEnvironment* NativeMethodEnvironment::get() {
    return native_method_environment.get();
  }

  NativeMethodFrame::~NativeMethodFrame() {
    flush_cached_data();
    for(capi::HandleSet::iterator i = handles_.begin();
        i != handles_.end();
        i++) {
      capi::Handle* handle = *i;
      handle->deref();
    }
  }

  VALUE NativeMethodFrame::get_handle(STATE, Object* obj) {
    InflatedHeader* ih = state->om->inflate_header(obj);

    capi::Handle* handle = ih->handle();

    if(!handle) {
      handle = new capi::Handle(state, obj);
      ih->set_handle(handle);

      state->shared.global_handles()->add(handle);
    }

    handle->ref();
    handles_.insert(handle);

    return handle->as_value();
  }

  Object* NativeMethodFrame::get_object(VALUE val) {
    return capi::Handle::from(val)->object();
  }

  void NativeMethodFrame::flush_cached_data() {<commit_msg>Fix handle leakage GC issue<commit_after>#include <iostream>

#include "vm.hpp"

#include "exception.hpp"
#include "exception_point.hpp"
#include "arguments.hpp"
#include "dispatch.hpp"
#include "native_libraries.hpp"
#include "primitives.hpp"
#include "call_frame.hpp"
#include "objectmemory.hpp"

#include "builtin/array.hpp"
#include "builtin/exception.hpp"
#include "builtin/nativemethod.hpp"
#include "builtin/string.hpp"
#include "builtin/system.hpp"
#include "builtin/tuple.hpp"
#include "builtin/capi_handle.hpp"

#include "instruments/profiler.hpp"

#include "capi/capi.hpp"
#include "capi/handle.hpp"

namespace rubinius {
  /** Thread-local NativeMethodEnvironment instance. */
  thread::ThreadData<NativeMethodEnvironment*> native_method_environment;

/* Class methods */

  NativeMethodEnvironment* NativeMethodEnvironment::get() {
    return native_method_environment.get();
  }

  NativeMethodFrame::~NativeMethodFrame() {
    flush_cached_data();
    for(capi::HandleSet::iterator i = handles_.begin();
        i != handles_.end();
        i++) {
      capi::Handle* handle = *i;
      handle->deref();
    }
  }

  VALUE NativeMethodFrame::get_handle(STATE, Object* obj) {
    InflatedHeader* ih = state->om->inflate_header(obj);

    capi::Handle* handle = ih->handle();

    if(handle) {
      // ref() ONLY if it's not already in there!
      // otherwise the refcount is wrong and we leak handles.
      capi::HandleSet::iterator pos = handles_.find(handle);
      if(pos == handles_.end()) {
        handle->ref();
        handles_.insert(handle);
      }
    } else {
      handle = new capi::Handle(state, obj);
      ih->set_handle(handle);

      state->shared.global_handles()->add(handle);

      handle->ref();
      handles_.insert(handle);
    }

    return handle->as_value();
  }

  Object* NativeMethodFrame::get_object(VALUE val) {
    return capi::Handle::from(val)->object();
  }

  void NativeMethodFrame::flush_cached_data() {
{'fraction_non_alphanumeric': 0.14962799669330393, 'fraction_numerical': 0.0, 'mean_word_length': 4.1931330472103, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 28, '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': '4525313', 'n_tokens_mistral': 1162, 'n_tokens_neox': 1151, 'n_words': 215}