<commit_before>// Copyright 2004-present Facebook. All Rights Reserved.

#include "JSCExecutor.h"

#include <algorithm>
#include <sstream>
#include <string>
#include <fb/log.h>
#include <folly/json.h>
#include <folly/String.h>
#include <jni/fbjni/Exceptions.h>
#include "Value.h"
#include "jni/OnLoad.h"

#ifdef WITH_JSC_EXTRA_TRACING
#include <react/JSCTracing.h>
#include <react/JSCLegacyProfiler.h>
#include <JavaScriptCore/API/JSProfilerPrivate.h>
#endif

#ifdef WITH_FBSYSTRACE
#include <fbsystrace.h>
using fbsystrace::FbSystraceSection;
#endif

// Add native performance markers support
#include <react/JSCPerfLogging.h>

using namespace facebook::jni;

namespace facebook {
namespace react {

static std::unordered_map<JSContextRef, JSCExecutor*> s_globalContextRefToJSCExecutor;
static JSValueRef nativeFlushQueueImmediate(
    JSContextRef ctx,
    JSObjectRef function,
    JSObjectRef thisObject,
    size_t argumentCount,
    const JSValueRef arguments[],
    JSValueRef *exception);
static JSValueRef nativeLoggingHook(
    JSContextRef ctx,
    JSObjectRef function,
    JSObjectRef thisObject,
    size_t argumentCount,
    const JSValueRef arguments[],
    JSValueRef *exception);

static JSValueRef evaluateScriptWithJSC(
    JSGlobalContextRef ctx,
    JSStringRef script,
    JSStringRef sourceURL) {
  JSValueRef exn;
  auto result = JSEvaluateScript(ctx, script, nullptr, sourceURL, 0, &exn);
  if (result == nullptr) {
    JSValueProtect(ctx, exn);
    std::string exceptionText = Value(ctx, exn).toString().str();
    FBLOGE("Got JS Exception: %s", exceptionText.c_str());
    auto line = Value(ctx, JSObjectGetProperty(ctx,
      JSValueToObject(ctx, exn, nullptr),
      JSStringCreateWithUTF8CString("line"), nullptr
    ));
    std::ostringstream lineInfo;
    if (line != nullptr && line.isNumber()) {
      lineInfo << " (line " << line.asInteger() << " in the generated bundle)";
    } else {
      lineInfo << " (no line info)";
    }
    throwNewJavaException("com/facebook/react/bridge/JSExecutionException", (exceptionText + lineInfo.str()).c_str());
  }
  return result;
}

std::unique_ptr<JSExecutor> JSCExecutorFactory::createJSExecutor(FlushImmediateCallback cb) {
  return std::unique_ptr<JSExecutor>(new JSCExecutor(cb));
}

JSCExecutor::JSCExecutor(FlushImmediateCallback cb) :
    m_flushImmediateCallback(cb) {
  m_context = JSGlobalContextCreateInGroup(nullptr, nullptr);
  s_globalContextRefToJSCExecutor[m_context] = this;
  installGlobalFunction(m_context, "nativeFlushQueueImmediate", nativeFlushQueueImmediate);
  installGlobalFunction(m_context, "nativeLoggingHook", nativeLoggingHook);
  #ifdef WITH_JSC_EXTRA_TRACING
  addNativeTracingHooks(m_context);
  addNativeProfilingHooks(m_context);
  addNativePerfLoggingHooks(m_context);
  #endif
}

JSCExecutor::~JSCExecutor() {
  s_globalContextRefToJSCExecutor.erase(m_context);
  JSGlobalContextRelease(m_context);
}

void JSCExecutor::executeApplicationScript(
    const std::string& script,
    const std::string& sourceURL) {
  JNIEnv* env = Environment::current();
  jclass markerClass = env->FindClass("com/facebook/react/bridge/ReactMarker");
  jmethodID logMarkerMethod = facebook::react::getLogMarkerMethod();
  jstring startStringMarker = env->NewStringUTF("executeApplicationScript_startStringConvert");
  jstring endStringMarker = env->NewStringUTF("executeApplicationScript_endStringConvert");
<commit_msg>Improve JSC GC implementation on android<commit_after>// Copyright 2004-present Facebook. All Rights Reserved.

#include "JSCExecutor.h"

#include <algorithm>
#include <sstream>
#include <string>
#include <fb/log.h>
#include <folly/json.h>
#include <folly/String.h>
#include <jni/fbjni/Exceptions.h>
#include "Value.h"
#include "jni/OnLoad.h"

#ifdef WITH_JSC_EXTRA_TRACING
#include <react/JSCTracing.h>
#include <react/JSCLegacyProfiler.h>
#include <JavaScriptCore/API/JSProfilerPrivate.h>
#endif

#ifdef WITH_FBSYSTRACE
#include <fbsystrace.h>
using fbsystrace::FbSystraceSection;
#endif

// Add native performance markers support
#include <react/JSCPerfLogging.h>

#ifdef WITH_FB_JSC_TUNING
#include <jsc_config_android.h>
#endif

using namespace facebook::jni;

namespace facebook {
namespace react {

static std::unordered_map<JSContextRef, JSCExecutor*> s_globalContextRefToJSCExecutor;
static JSValueRef nativeFlushQueueImmediate(
    JSContextRef ctx,
    JSObjectRef function,
    JSObjectRef thisObject,
    size_t argumentCount,
    const JSValueRef arguments[],
    JSValueRef *exception);
static JSValueRef nativeLoggingHook(
    JSContextRef ctx,
    JSObjectRef function,
    JSObjectRef thisObject,
    size_t argumentCount,
    const JSValueRef arguments[],
    JSValueRef *exception);

static JSValueRef evaluateScriptWithJSC(
    JSGlobalContextRef ctx,
    JSStringRef script,
    JSStringRef sourceURL) {
  JSValueRef exn;
  auto result = JSEvaluateScript(ctx, script, nullptr, sourceURL, 0, &exn);
  if (result == nullptr) {
    JSValueProtect(ctx, exn);
    std::string exceptionText = Value(ctx, exn).toString().str();
    FBLOGE("Got JS Exception: %s", exceptionText.c_str());
    auto line = Value(ctx, JSObjectGetProperty(ctx,
      JSValueToObject(ctx, exn, nullptr),
      JSStringCreateWithUTF8CString("line"), nullptr
    ));
    std::ostringstream lineInfo;
    if (line != nullptr && line.isNumber()) {
      lineInfo << " (line " << line.asInteger() << " in the generated bundle)";
    } else {
      lineInfo << " (no line info)";
    }
    throwNewJavaException("com/facebook/react/bridge/JSExecutionException", (exceptionText + lineInfo.str()).c_str());
  }
  return result;
}

std::unique_ptr<JSExecutor> JSCExecutorFactory::createJSExecutor(FlushImmediateCallback cb) {
  return std::unique_ptr<JSExecutor>(new JSCExecutor(cb));
}

JSCExecutor::JSCExecutor(FlushImmediateCallback cb) :
    m_flushImmediateCallback(cb) {
  m_context = JSGlobalContextCreateInGroup(nullptr, nullptr);
  s_globalContextRefToJSCExecutor[m_context] = this;
  installGlobalFunction(m_context, "nativeFlushQueueImmediate", nativeFlushQueueImmediate);
  installGlobalFunction(m_context, "nativeLoggingHook", nativeLoggingHook);

  #ifdef WITH_FB_JSC_TUNING
  configureJSCForAndroid();
  #endif

  #ifdef WITH_JSC_EXTRA_TRACING
  addNativeTracingHooks(m_context);
  addNativeProfilingHooks(m_context);
  addNativePerfLoggingHooks(m_context);
  #endif
}

JSCExecutor::~JSCExecutor() {
  s_globalContextRefToJSCExecutor.erase(m_context);
  JSGlobalContextRelease(m_context);
}

void JSCExecutor::executeApplicationScript(
    const std::string& script,
    const std::string& sourceURL) {
  JNIEnv* env = Environment::current();
  jclass markerClass = env->FindClass("com/facebook/react/bridge/ReactMarker");
  jmethodID logMarkerMethod = facebook::react::getLogMarkerMethod();
  jstring startStringMarker = env->NewStringUTF("executeApplicationScript_startStringConvert");
  jstring endStringMarker = env->NewStringUTF("executeApplicationScript_endStringConvert");

{'fraction_non_alphanumeric': 0.10963407661520869, 'fraction_numerical': 0.0017152658662092624, 'mean_word_length': 5.907206317867719, 'pattern_counts': {'":': 0, '<': 50, '<?xml version=': 0, '>': 40, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1362005', 'n_tokens_mistral': 2261, 'n_tokens_neox': 2245, 'n_words': 434}