Skip to content

Commit 2552ac0

Browse files
author
Mihail Slavchev
committed
refactor code to cache per V8 isolate instead of global statics
1 parent 8c635a5 commit 2552ac0

14 files changed

Lines changed: 295 additions & 213 deletions

src/jni/ArgConverter.cpp

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,25 +17,25 @@ using namespace v8;
1717
using namespace std;
1818
using namespace tns;
1919

20-
void ArgConverter::Init()
20+
void ArgConverter::Init(Isolate *isolate)
2121
{
22-
auto isolate = Isolate::GetCurrent();
22+
auto cache = GetCache(isolate);
2323

2424
auto ft = FunctionTemplate::New(isolate, ArgConverter::NativeScriptLongFunctionCallback);
2525
ft->SetClassName(V8StringConstants::GetLongNumber());
2626
ft->InstanceTemplate()->Set(V8StringConstants::GetValueOf(), FunctionTemplate::New(isolate, ArgConverter::NativeScriptLongValueOfFunctionCallback));
2727
ft->InstanceTemplate()->Set(V8StringConstants::GetToString(), FunctionTemplate::New(isolate, ArgConverter::NativeScriptLongToStringFunctionCallback));
28-
NATIVESCRIPT_NUMBER_CTOR_FUNC = new Persistent<Function>(isolate, ft->GetFunction());
28+
cache->LongNumberCtorFunc = new Persistent<Function>(isolate, ft->GetFunction());
2929

3030
auto nanObject = Number::New(isolate, numeric_limits<double>::quiet_NaN()).As<NumberObject>();
31-
NAN_NUMBER_OBJECT = new Persistent<NumberObject>(isolate, nanObject);
31+
cache->NanNumberObject = new Persistent<NumberObject>(isolate, nanObject);
3232
}
3333

3434
void ArgConverter::NativeScriptLongValueOfFunctionCallback(const v8::FunctionCallbackInfo<Value>& args)
3535
{
3636
try
3737
{
38-
auto isolate = Isolate::GetCurrent();
38+
auto isolate = args.GetIsolate();
3939
args.GetReturnValue().Set(Number::New(isolate, numeric_limits<double>::quiet_NaN()));
4040
}
4141
catch (NativeScriptException& e)
@@ -80,11 +80,12 @@ void ArgConverter::NativeScriptLongFunctionCallback(const v8::FunctionCallbackIn
8080
{
8181
try
8282
{
83-
auto isolate = Isolate::GetCurrent();
83+
auto isolate = args.GetIsolate();
8484
auto thiz = args.This();
85+
auto cache = GetCache(isolate);
8586
thiz->SetHiddenValue(V8StringConstants::GetJavaLong(), Boolean::New(isolate, true));
8687
NumericCasts::MarkAsLong(thiz, args[0]);
87-
thiz->SetPrototype(Local<NumberObject>::New(Isolate::GetCurrent(), *NAN_NUMBER_OBJECT));
88+
thiz->SetPrototype(Local<NumberObject>::New(isolate, *cache->NanNumberObject));
8889
}
8990
catch (NativeScriptException& e)
9091
{
@@ -249,23 +250,22 @@ Local<String> ArgConverter::jcharToV8String(jchar value)
249250
return v8String;
250251
}
251252

252-
Local<Value> ArgConverter::ConvertFromJavaLong(jlong value)
253+
Local<Value> ArgConverter::ConvertFromJavaLong(Isolate *isolate, jlong value)
253254
{
254255
Local<Value> convertedValue;
255256
long long longValue = value;
256257

257-
auto isolate = Isolate::GetCurrent();
258-
259258
if ((-JS_LONG_LIMIT < longValue) && (longValue < JS_LONG_LIMIT))
260259
{
261260
convertedValue = Number::New(isolate, longValue);
262261
}
263262
else
264263
{
264+
auto cache = GetCache(isolate);
265265
char strNumber[24];
266266
sprintf(strNumber, "%lld", longValue);
267267
Local<Value> strValue = ConvertToV8String(strNumber);
268-
convertedValue = Local<Function>::New(isolate, *NATIVESCRIPT_NUMBER_CTOR_FUNC)->CallAsConstructor(1, &strValue);
268+
convertedValue = Local<Function>::New(isolate, *cache->LongNumberCtorFunc)->CallAsConstructor(1, &strValue);
269269
}
270270

271271
return convertedValue;
@@ -290,6 +290,21 @@ int64_t ArgConverter::ConvertToJavaLong(const Local<Value>& value)
290290
return longValue;
291291
}
292292

293-
Persistent<Function>* ArgConverter::NATIVESCRIPT_NUMBER_CTOR_FUNC = nullptr;
294-
Persistent<NumberObject>* ArgConverter::NAN_NUMBER_OBJECT = nullptr;
293+
ArgConverter::Cache* ArgConverter::GetCache(v8::Isolate *isolate)
294+
{
295+
Cache *cache;
296+
auto itFound = s_cache.find(isolate);
297+
if (itFound == s_cache.end())
298+
{
299+
cache = new Cache;
300+
s_cache.insert(make_pair(isolate, cache));
301+
}
302+
else
303+
{
304+
cache = itFound->second;
305+
}
306+
return cache;
307+
}
308+
309+
std::map<Isolate*, ArgConverter::Cache*> ArgConverter::s_cache;
295310
char* ArgConverter::charBuffer = new char[ArgConverter::BUFFER_SIZE];

src/jni/ArgConverter.h

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,18 @@
1111
#include "v8.h"
1212
#include "JEnv.h"
1313
#include <string>
14+
#include <map>
1415

1516
namespace tns
1617
{
1718
class ArgConverter
1819
{
1920
public:
20-
static void Init();
21+
static void Init(v8::Isolate *isolate);
2122

2223
static v8::Local<v8::Array> ConvertJavaArgsToJsArgs(v8::Isolate *isolate, jobjectArray args);
2324

24-
static v8::Local<v8::Value> ConvertFromJavaLong(jlong value);
25+
static v8::Local<v8::Value> ConvertFromJavaLong(v8::Isolate *isolate, jlong value);
2526

2627
static int64_t ConvertToJavaLong(const v8::Local<v8::Value>& value);
2728

@@ -30,6 +31,10 @@ namespace tns
3031
static std::string jstringToString(jstring value);
3132

3233
private:
34+
struct Cache;
35+
36+
static Cache* GetCache(v8::Isolate *isolate);
37+
3338
static bool ReadJStringInBuffer(jstring value, jsize& utfLength);
3439

3540
static jstring ObjectToString(jobject object);
@@ -44,11 +49,16 @@ namespace tns
4449

4550
static const long long JS_LONG_LIMIT = ((long long) 1) << 53;
4651

47-
static v8::Persistent<v8::Function> *NATIVESCRIPT_NUMBER_CTOR_FUNC;
48-
static v8::Persistent<v8::NumberObject> *NAN_NUMBER_OBJECT;
52+
struct Cache
53+
{
54+
v8::Persistent<v8::Function> *LongNumberCtorFunc;
55+
56+
v8::Persistent<v8::NumberObject> *NanNumberObject;
57+
};
4958

5059
static char *charBuffer;
5160
static const int BUFFER_SIZE = 1024 * 64; // 64KB size. TODO: Do we need a larger/smaller buffer?
61+
static std::map<v8::Isolate*, Cache*> s_cache;
5262
};
5363
}
5464

src/jni/ArrayElementAccessor.cpp

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,14 @@ Local<Value> ArrayElementAccessor::GetArrayElement(Isolate *isolate, const Local
3535
jbooleanArray boolArr = static_cast<jbooleanArray>(arr);
3636
jboolean boolArrValue;
3737
env.GetBooleanArrayRegion(boolArr, startIndex, length, &boolArrValue);
38-
value = ConvertToJsValue(objectManager, env, elementSignature, &boolArrValue);
38+
value = ConvertToJsValue(isolate, objectManager, env, elementSignature, &boolArrValue);
3939
}
4040
else if (elementSignature == "B")
4141
{
4242
jbyteArray byteArr = static_cast<jbyteArray>(arr);
4343
jbyte byteArrValue;
4444
env.GetByteArrayRegion(byteArr, startIndex, length, &byteArrValue);
45-
value = ConvertToJsValue(objectManager, env, elementSignature, &byteArrValue);
45+
value = ConvertToJsValue(isolate, objectManager, env, elementSignature, &byteArrValue);
4646
}
4747
else if (elementSignature == "C")
4848
{
@@ -51,48 +51,48 @@ Local<Value> ArrayElementAccessor::GetArrayElement(Isolate *isolate, const Local
5151
env.GetCharArrayRegion(charArr, startIndex, length, &charArrValue);
5252
JniLocalRef s(env.NewString(&charArrValue, 1));
5353
const char* singleChar = env.GetStringUTFChars(s, &isCopy);
54-
value = ConvertToJsValue(objectManager, env, elementSignature, singleChar);
54+
value = ConvertToJsValue(isolate, objectManager, env, elementSignature, singleChar);
5555
env.ReleaseStringUTFChars(s, singleChar);
5656
}
5757
else if (elementSignature == "S")
5858
{
5959
jshortArray shortArr = static_cast<jshortArray>(arr);
6060
jshort shortArrValue;
6161
env.GetShortArrayRegion(shortArr, startIndex, length, &shortArrValue);
62-
value = ConvertToJsValue(objectManager, env, elementSignature, &shortArrValue);
62+
value = ConvertToJsValue(isolate, objectManager, env, elementSignature, &shortArrValue);
6363
}
6464
else if (elementSignature == "I")
6565
{
6666
jintArray intArr = static_cast<jintArray>(arr);
6767
jint intArrValue;
6868
env.GetIntArrayRegion(intArr, startIndex, length, &intArrValue);
69-
value = ConvertToJsValue(objectManager, env, elementSignature, &intArrValue);
69+
value = ConvertToJsValue(isolate, objectManager, env, elementSignature, &intArrValue);
7070
}
7171
else if (elementSignature == "J")
7272
{
7373
jlongArray longArr = static_cast<jlongArray>(arr);
7474
jlong longArrValue;
7575
env.GetLongArrayRegion(longArr, startIndex, length, &longArrValue);
76-
value = ConvertToJsValue(objectManager, env, elementSignature, &longArrValue);
76+
value = ConvertToJsValue(isolate, objectManager, env, elementSignature, &longArrValue);
7777
}
7878
else if (elementSignature == "F")
7979
{
8080
jfloatArray floatArr = static_cast<jfloatArray>(arr);
8181
jfloat floatArrValue;
8282
env.GetFloatArrayRegion(floatArr, startIndex, length, &floatArrValue);
83-
value = ConvertToJsValue(objectManager, env, elementSignature, &floatArrValue);
83+
value = ConvertToJsValue(isolate, objectManager, env, elementSignature, &floatArrValue);
8484
}
8585
else if (elementSignature == "D")
8686
{
8787
jdoubleArray doubleArr = static_cast<jdoubleArray>(arr);
8888
jdouble doubleArrValue;
8989
env.GetDoubleArrayRegion(doubleArr, startIndex, length, &doubleArrValue);
90-
value = ConvertToJsValue(objectManager, env, elementSignature, &doubleArrValue);
90+
value = ConvertToJsValue(isolate, objectManager, env, elementSignature, &doubleArrValue);
9191
}
9292
else
9393
{
9494
jobject result = env.GetObjectArrayElement(static_cast<jobjectArray>(arr), index);
95-
value = ConvertToJsValue(objectManager, env, elementSignature, &result);
95+
value = ConvertToJsValue(isolate, objectManager, env, elementSignature, &result);
9696
env.DeleteLocalRef(result);
9797
}
9898

@@ -199,12 +199,10 @@ void ArrayElementAccessor::SetArrayElement(Isolate *isolate, const Local<Object>
199199
}
200200
}
201201

202-
Local<Value> ArrayElementAccessor::ConvertToJsValue(ObjectManager *objectManager, JEnv& env, const string& elementSignature, const void *value)
202+
Local<Value> ArrayElementAccessor::ConvertToJsValue(Isolate *isolate, ObjectManager *objectManager, JEnv& env, const string& elementSignature, const void *value)
203203
{
204204
Local<Value> jsValue;
205205

206-
auto isolate = Isolate::GetCurrent();
207-
208206
if (elementSignature == "Z")
209207
{
210208
jsValue = Boolean::New(isolate, *(jboolean*) value);
@@ -227,7 +225,7 @@ Local<Value> ArrayElementAccessor::ConvertToJsValue(ObjectManager *objectManager
227225
}
228226
else if (elementSignature == "J")
229227
{
230-
jsValue = ArgConverter::ConvertFromJavaLong(*(jlong*) value);
228+
jsValue = ArgConverter::ConvertFromJavaLong(isolate, *(jlong*) value);
231229
}
232230
else if (elementSignature == "F")
233231
{

src/jni/ArrayElementAccessor.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ namespace tns
1616
void SetArrayElement(v8::Isolate *isolate, const v8::Local<v8::Object>& array, uint32_t index, const std::string& arraySignature, v8::Local<v8::Value>& value);
1717

1818
private:
19-
v8::Local<v8::Value> ConvertToJsValue(ObjectManager *objectManager, JEnv& env, const std::string& elementSignature, const void *value);
19+
v8::Local<v8::Value> ConvertToJsValue(v8::Isolate *isolate, ObjectManager *objectManager, JEnv& env, const std::string& elementSignature, const void *value);
2020
};
2121
}
2222

src/jni/CallbackHandlers.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ using namespace v8;
2626
using namespace std;
2727
using namespace tns;
2828

29-
void CallbackHandlers::Init(ObjectManager *objectManager)
29+
void CallbackHandlers::Init(Isolate *isolate, ObjectManager *objectManager)
3030
{
3131
JEnv env;
3232

@@ -57,7 +57,7 @@ void CallbackHandlers::Init(ObjectManager *objectManager)
5757
GET_CHANGE_IN_BYTES_OF_USED_MEMORY_METHOD_ID = env.GetMethodID(RUNTIME_CLASS, "getChangeInBytesOfUsedMemory", "()J");
5858
assert(GET_CHANGE_IN_BYTES_OF_USED_MEMORY_METHOD_ID != nullptr);
5959

60-
MetadataNode::Init();
60+
MetadataNode::Init(isolate);
6161

6262
MethodCache::Init();
6363
}
@@ -279,7 +279,7 @@ void CallbackHandlers::CallJavaMethod(const Local<Object>& caller, const string&
279279
throw NativeScriptException(err.msg);
280280
}
281281

282-
auto isolate = Isolate::GetCurrent();
282+
auto isolate = args.GetIsolate();
283283

284284
JniLocalRef callerJavaObject;
285285

@@ -428,7 +428,7 @@ void CallbackHandlers::CallJavaMethod(const Local<Object>& caller, const string&
428428
{
429429
result = env.CallLongMethodA(callerJavaObject, mid, javaArgs);
430430
}
431-
auto jsLong = ArgConverter::ConvertFromJavaLong(result);
431+
auto jsLong = ArgConverter::ConvertFromJavaLong(isolate, result);
432432
args.GetReturnValue().Set(jsLong);
433433
break;
434434
}

src/jni/CallbackHandlers.h

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ namespace tns
2323
{
2424
public:
2525

26-
static void Init(ObjectManager *objectManager);
26+
static void Init(v8::Isolate *isolate, ObjectManager *objectManager);
2727

2828
static v8::Local<v8::Object> CreateJSWrapper(v8::Isolate *isolate, jint javaObjectID, const std::string& typeName);
2929

@@ -84,13 +84,6 @@ namespace tns
8484

8585
static v8::Local<v8::Object> FindClass(v8::Isolate *isolate, const std::string& className);
8686

87-
static MetadataTreeNode *metadataRoot;
88-
89-
static jclass RUNTIME_CLASS;
90-
91-
static jclass JAVA_LANG_STRING;
92-
//
93-
9487
private:
9588
CallbackHandlers()
9689
{
@@ -102,6 +95,10 @@ namespace tns
10295

10396
static v8::Persistent<v8::Object>* MarkJsObject(const v8::Local<v8::Object>& object, std::string mark, const v8::Local<v8::Value>& value);
10497

98+
static jclass RUNTIME_CLASS;
99+
100+
static jclass JAVA_LANG_STRING;
101+
105102
static jmethodID RESOLVE_CLASS_METHOD_ID;
106103

107104
static jmethodID CREATE_INSTANCE_METHOD_ID;
@@ -122,6 +119,8 @@ namespace tns
122119

123120
static FieldAccessor fieldAccessor;
124121

122+
static MetadataTreeNode *metadataRoot;
123+
125124
static std::map<std::string, int> s_constructorCache;
126125

127126
static std::map<std::string, jclass> s_classCache;

src/jni/FieldAccessor.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ Local<Value> FieldAccessor::GetJavaField(Isolate *isolate, const Local<Object>&
159159
{
160160
result = env.GetLongField(targetJavaObject, fieldId);
161161
}
162-
fieldResult = handleScope.Escape(ArgConverter::ConvertFromJavaLong(result));
162+
fieldResult = handleScope.Escape(ArgConverter::ConvertFromJavaLong(isolate, result));
163163
break;
164164
}
165165
case 'F': //float

0 commit comments

Comments
 (0)