Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 76 additions & 32 deletions test-app/runtime/src/main/cpp/com_tns_Runtime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,75 @@
using namespace std;
using namespace tns;

Runtime* TryGetRuntime(int runtimeId);

namespace {
jint GenerateNewObjectIdFast(jint runtimeId) {
auto runtime = TryGetRuntime(runtimeId);
if (runtime == nullptr) {
return 0;
}

return runtime->GenerateNewObjectId(nullptr, nullptr);
}

jboolean NotifyGcFast(JNIEnv* env, jclass, jobject runtimeObject, jint runtimeId) {
auto runtime = TryGetRuntime(runtimeId);
if (runtime == nullptr) {
return JNI_FALSE;
}

return runtime->NotifyGC(env, runtimeObject) ? JNI_TRUE : JNI_FALSE;
}

jint GetPointerSizeFast() {
return sizeof(void*);
}

jint GetCurrentRuntimeIdFast() {
Isolate* isolate = Isolate::TryGetCurrent();
if (isolate == nullptr) {
return -1;
}

Runtime* runtime = Runtime::GetRuntime(isolate);
return runtime->GetId();
}

void SetManualInstrumentationModeFast(JNIEnv*, jclass, jstring mode) {
Runtime::SetManualInstrumentationMode(mode);
}

void RegisterRuntimeNativeFastMethods(JNIEnv* env) {
jclass runtimeNativeFastClass = env->FindClass("com/tns/RuntimeNativeFast");
if (runtimeNativeFastClass == nullptr) {
throw NativeScriptException("Unable to find com/tns/RuntimeNativeFast for JNI registration.");
}

JNINativeMethod methods[] = {
{ const_cast<char*>("generateNewObjectId"), const_cast<char*>("(I)I"), reinterpret_cast<void*>(GenerateNewObjectIdFast) },
{ const_cast<char*>("notifyGc"), const_cast<char*>("(Lcom/tns/Runtime;I)Z"), reinterpret_cast<void*>(NotifyGcFast) },
{ const_cast<char*>("getCurrentRuntimeId"), const_cast<char*>("()I"), reinterpret_cast<void*>(GetCurrentRuntimeIdFast) },
{ const_cast<char*>("getPointerSize"), const_cast<char*>("()I"), reinterpret_cast<void*>(GetPointerSizeFast) },
{ const_cast<char*>("SetManualInstrumentationMode"), const_cast<char*>("(Ljava/lang/String;)V"), reinterpret_cast<void*>(SetManualInstrumentationModeFast) },
};

if (env->RegisterNatives(runtimeNativeFastClass, methods, sizeof(methods) / sizeof(methods[0])) != JNI_OK) {
throw NativeScriptException("Unable to register com/tns/RuntimeNativeFast native methods.");
}

env->DeleteLocalRef(runtimeNativeFastClass);
}
} // namespace

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) {
try {
Runtime::Init(vm, reserved);
JNIEnv* env = nullptr;
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK || env == nullptr) {
throw NativeScriptException("Unable to retrieve JNIEnv during JNI_OnLoad.");
}
RegisterRuntimeNativeFastMethods(env);
} catch (NativeScriptException& e) {
e.ReThrowToJava();
} catch (std::exception e) {
Expand All @@ -25,8 +91,7 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) {
return JNI_VERSION_1_6;
}

// @FastNative signature - optimized JNI, keeps JNIEnv* for jstring handling
extern "C" JNIEXPORT void Java_com_tns_Runtime_SetManualInstrumentationMode(JNIEnv* _env, jobject obj, jstring mode) {
extern "C" JNIEXPORT void Java_com_tns_Runtime_SetManualInstrumentationModeLegacy(JNIEnv*, jclass, jstring mode) {
try {
Runtime::SetManualInstrumentationMode(mode);
} catch (...) {
Expand Down Expand Up @@ -215,14 +280,9 @@ extern "C" JNIEXPORT void Java_com_tns_Runtime_createJSInstanceNative(JNIEnv* _e
}
}

// @CriticalNative signature - no JNIEnv* or jobject parameters
extern "C" JNIEXPORT jint Java_com_tns_Runtime_generateNewObjectId(jint runtimeId) {
extern "C" JNIEXPORT jint Java_com_tns_Runtime_generateNewObjectIdLegacy(JNIEnv*, jclass, jint runtimeId) {
try {
auto runtime = TryGetRuntime(runtimeId);
if (runtime == nullptr) {
return 0;
}
return runtime->GenerateNewObjectId(nullptr, nullptr);
return GenerateNewObjectIdFast(runtimeId);
} catch (NativeScriptException& e) {
e.ReThrowToJava();
} catch (std::exception e) {
Expand All @@ -238,15 +298,8 @@ extern "C" JNIEXPORT jint Java_com_tns_Runtime_generateNewObjectId(jint runtimeI
return 0;
}

// @FastNative signature - optimized JNI, keeps JNIEnv* for NotifyGC
extern "C" JNIEXPORT jboolean Java_com_tns_Runtime_notifyGc(JNIEnv* env, jobject obj, jint runtimeId) {
auto runtime = TryGetRuntime(runtimeId);
if (runtime == nullptr) {
return JNI_FALSE;
}

jboolean success = runtime->NotifyGC(env, obj) ? JNI_TRUE : JNI_FALSE;
return success;
extern "C" JNIEXPORT jboolean Java_com_tns_Runtime_notifyGcLegacy(JNIEnv* env, jobject obj, jint runtimeId) {
return NotifyGcFast(env, nullptr, obj, runtimeId);
}

extern "C" JNIEXPORT void Java_com_tns_Runtime_lock(JNIEnv* env, jobject obj, jint runtimeId) {
Expand Down Expand Up @@ -291,21 +344,12 @@ extern "C" JNIEXPORT void Java_com_tns_Runtime_passExceptionToJsNative(JNIEnv* e
}
}

// @CriticalNative signature - no JNIEnv* or jobject parameters
extern "C" JNIEXPORT jint Java_com_tns_Runtime_getPointerSize() {
return sizeof(void*);
extern "C" JNIEXPORT jint Java_com_tns_Runtime_getPointerSizeLegacy(JNIEnv*, jclass) {
return GetPointerSizeFast();
}

// @CriticalNative signature - no JNIEnv* or jobject parameters
extern "C" JNIEXPORT jint Java_com_tns_Runtime_getCurrentRuntimeId() {
Isolate* isolate = Isolate::TryGetCurrent();
if (isolate == nullptr) {
return -1;
}

Runtime* runtime = Runtime::GetRuntime(isolate);
int id = runtime->GetId();
return id;
extern "C" JNIEXPORT jint Java_com_tns_Runtime_getCurrentRuntimeIdLegacy(JNIEnv*, jclass) {
return GetCurrentRuntimeIdFast();
}

extern "C" JNIEXPORT void Java_com_tns_Runtime_WorkerGlobalOnMessageCallback(JNIEnv* env, jobject obj, jint runtimeId, jstring msg) {
Expand Down Expand Up @@ -415,4 +459,4 @@ extern "C" JNIEXPORT void Java_com_tns_Runtime_ResetDateTimeConfigurationCache(J

auto isolate = runtime->GetIsolate();
isolate->DateTimeConfigurationChangeNotification(Isolate::TimeZoneDetection::kRedetect);
}
}
63 changes: 50 additions & 13 deletions test-app/runtime/src/main/java/com/tns/Runtime.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.tns;

import android.os.Build;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
Expand Down Expand Up @@ -31,15 +32,15 @@
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.Collections;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.concurrent.RunnableFuture;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.Collections;
import dalvik.annotation.optimization.CriticalNative;
import dalvik.annotation.optimization.FastNative;

public class Runtime {
private static final boolean USE_FAST_NATIVE_METHODS = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O;

private native void initNativeScript(int runtimeId, String filesPath, String nativeLibDir, boolean verboseLoggingEnabled, boolean isDebuggable, String packageName,
Object[] v8Options, String callingDir, int maxLogcatObjectSize, boolean forceLog);

Expand All @@ -53,26 +54,62 @@ private native void initNativeScript(int runtimeId, String filesPath, String nat

private native void createJSInstanceNative(int runtimeId, Object javaObject, int javaObjectID, String canonicalName);

@CriticalNative
private static native int generateNewObjectId(int runtimeId);
private static int generateNewObjectId(int runtimeId) {
if (USE_FAST_NATIVE_METHODS) {
return RuntimeNativeFast.generateNewObjectId(runtimeId);
}

return generateNewObjectIdLegacy(runtimeId);
}

private static native int generateNewObjectIdLegacy(int runtimeId);

private boolean notifyGc(int runtimeId) {
if (USE_FAST_NATIVE_METHODS) {
return RuntimeNativeFast.notifyGc(this, runtimeId);
}

return notifyGcLegacy(runtimeId);
}

@FastNative
private native boolean notifyGc(int runtimeId);
private native boolean notifyGcLegacy(int runtimeId);

private native void lock(int runtimeId);

private native void unlock(int runtimeId);

private native void passExceptionToJsNative(int runtimeId, Throwable ex, String message, String fullStackTrace, String jsStackTrace, boolean isDiscarded);

@CriticalNative
private static native int getCurrentRuntimeId();
private static int getCurrentRuntimeId() {
if (USE_FAST_NATIVE_METHODS) {
return RuntimeNativeFast.getCurrentRuntimeId();
}

return getCurrentRuntimeIdLegacy();
}

private static native int getCurrentRuntimeIdLegacy();

public static int getPointerSize() {
if (USE_FAST_NATIVE_METHODS) {
return RuntimeNativeFast.getPointerSize();
}

return getPointerSizeLegacy();
}

private static native int getPointerSizeLegacy();

public static void SetManualInstrumentationMode(String mode) {
if (USE_FAST_NATIVE_METHODS) {
RuntimeNativeFast.SetManualInstrumentationMode(mode);
return;
}

@CriticalNative
public static native int getPointerSize();
SetManualInstrumentationModeLegacy(mode);
}

@FastNative
public static native void SetManualInstrumentationMode(String mode);
private static native void SetManualInstrumentationModeLegacy(String mode);

private static native void WorkerGlobalOnMessageCallback(int runtimeId, String message);

Expand Down
24 changes: 24 additions & 0 deletions test-app/runtime/src/main/java/com/tns/RuntimeNativeFast.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.tns;

import dalvik.annotation.optimization.CriticalNative;
import dalvik.annotation.optimization.FastNative;

final class RuntimeNativeFast {
private RuntimeNativeFast() {
}

@CriticalNative
static native int generateNewObjectId(int runtimeId);

@FastNative
static native boolean notifyGc(Runtime runtime, int runtimeId);

@CriticalNative
static native int getCurrentRuntimeId();

@CriticalNative
static native int getPointerSize();

@FastNative
static native void SetManualInstrumentationMode(String mode);
}
Loading