History

V8 optimizations

ksuprynowicz committed 3 years ago

Commit eabc7271 parent a57c7a52 files · +47 −37Browse files

Showing the changes to libraries/script-engine/src/v8/ScriptObjectV8Proxy.cpp (1 of 2 files). Show all

Unified · Split

libraries/script-engine/src/v8/ScriptObjectV8Proxy.cpp+37−27
@@ -255,13 +255,13 @@ void ScriptObjectV8Proxy::investigate() { · 254 unmodified lines
255255 v8::HandleScope handleScope(_engine->getIsolate());
256256 v8::Context::Scope contextScope(_engine->getContext());
257257
258+ const QMetaObject* metaObject = qobject->metaObject();
259+
258260 //auto objectTemplate = _v8ObjectTemplate.Get(_engine->getIsolate());
259261 auto objectTemplate = v8::ObjectTemplate::New(_engine->getIsolate());
260262 objectTemplate->SetInternalFieldCount(3);
261263 objectTemplate->SetHandler(v8::NamedPropertyHandlerConfiguration(v8Get, v8Set, nullptr, nullptr, v8GetPropertyNames));
262264
263− const QMetaObject* metaObject = qobject->metaObject();
264−
265265 //qCDebug(scriptengine_v8) << "Investigate: " << metaObject->className();
266266 if (QString("ConsoleScriptingInterface") == metaObject->className()) {
267267 printf("ConsoleScriptingInterface");
@@ -283,9 +283,9 @@ void ScriptObjectV8Proxy::investigate() { · 15 unmodified lines
283283 }
284284 }
285285
286− auto v8Name = v8::String::NewFromUtf8(_engine->getIsolate(), prop.name()).ToLocalChecked();
287− PropertyDef& propDef = _props.insert(idx, PropertyDef(_engine, v8Name, idx)).value();
288− _propNameMap.insert(V8ScriptString(_engine, v8Name), &propDef);
286+ //auto v8Name = v8::String::NewFromUtf8(_engine->getIsolate(), prop.name()).ToLocalChecked();
287+ PropertyDef& propDef = _props.insert(idx, PropertyDef(prop.name(), idx)).value();
288+ _propNameMap.insert(prop.name(), &propDef);
289289 propDef.flags = ScriptValue::Undeletable | ScriptValue::PropertyGetter | ScriptValue::PropertySetter |
290290 ScriptValue::QObjectMember;
291291 if (prop.isConstant()) propDef.flags |= ScriptValue::ReadOnly;
@@ -294,7 +294,7 @@ void ScriptObjectV8Proxy::investigate() { · 2 unmodified lines
294294 // discover methods
295295 startIdx = (_wrapOptions & ScriptEngine::ExcludeSuperClassMethods) ? metaObject->methodOffset() : 0;
296296 num = metaObject->methodCount();
297− QHash<V8ScriptString, int> methodNames;
297+ QHash<QString, int> methodNames;
298298 for (int idx = startIdx; idx < num; ++idx) {
299299 QMetaMethod method = metaObject->method(idx);
300300 //qCDebug(scriptengine_v8) << "Investigate: " << metaObject->className() << " Method: " << method.name();
@@ -325,17 +325,17 @@ void ScriptObjectV8Proxy::investigate() { · 24 unmodified lines
325325
326326 auto nameString = v8::String::NewFromUtf8(_engine->getIsolate(), szName.data(), v8::NewStringType::kNormal, szName.length()).ToLocalChecked();
327327 V8ScriptString name(_engine, nameString);
328− auto nameLookup = methodNames.find(name);
328+ auto nameLookup = methodNames.find(szName);
329329 if (isSignal) {
330330 if (nameLookup == methodNames.end()) {
331− SignalDef& signalDef = _signals.insert(idx, SignalDef(_engine, name.get(), idx)).value();
332− signalDef.name = name;
331+ SignalDef& signalDef = _signals.insert(idx, SignalDef(szName, idx)).value();
332+ signalDef.name = szName;
333333 signalDef.signal = method;
334− _signalNameMap.insert(name, &signalDef);
334+ _signalNameMap.insert(szName, &signalDef);
335335 //qCDebug(scriptengine_v8) << "Utf8Value 1: " << QString(*v8::String::Utf8Value(const_cast<v8::Isolate*>(_engine->getIsolate()), nameString));
336336 //qCDebug(scriptengine_v8) << "Utf8Value 2: " << QString(*v8::String::Utf8Value(const_cast<v8::Isolate*>(_engine->getIsolate()), name.constGet()));
337337 //qCDebug(scriptengine_v8) << "toQString: " << name.toQString();
338− methodNames.insert(name, idx);
338+ methodNames.insert(szName, idx);
339339 } else {
340340 int originalMethodId = nameLookup.value();
341341 SignalDefMap::iterator signalLookup = _signals.find(originalMethodId);
@@ -357,18 +357,18 @@ void ScriptObjectV8Proxy::investigate() { · 15 unmodified lines
357357 }
358358 }
359359 if (nameLookup == methodNames.end()) {
360− MethodDef& methodDef = _methods.insert(idx, MethodDef(_engine, name.get(), idx)).value();
361− methodDef.name = name;
362− methodDef.numMaxParms = parameterCount;
360+ MethodDef& methodDef = _methods.insert(idx, MethodDef(szName, idx)).value();
361+ methodDef.name = szName;
362+ methodDef.numMaxParams = parameterCount;
363363 methodDef.methods.append(method);
364− _methodNameMap.insert(name, &methodDef);
365− methodNames.insert(name, idx);
364+ _methodNameMap.insert(szName, &methodDef);
365+ methodNames.insert(szName, idx);
366366 } else {
367367 int originalMethodId = nameLookup.value();
368368 MethodDefMap::iterator methodLookup = _methods.find(originalMethodId);
369369 Q_ASSERT(methodLookup != _methods.end());
370370 MethodDef& methodDef = methodLookup.value();
371− if(methodDef.numMaxParms < parameterCount) methodDef.numMaxParms = parameterCount;
371+ if(methodDef.numMaxParams < parameterCount) methodDef.numMaxParams = parameterCount;
372372 methodDef.methods.append(method);
373373 }
374374 }
@@ -386,13 +386,18 @@ void ScriptObjectV8Proxy::investigate() { · 11 unmodified lines
386386 _v8Object.SetWeak(this, weakHandleCallback, v8::WeakCallbackType::kParameter);
387387 }
388388
389+ /*if (QString(metaObject->className()) == QString("TestQObject")) {
390+ //qDebug() << "TestQObject investigate: _methods.size: " << _methods.size();
391+ return;
392+ }*/
393+
389394 // Add all the methods objects as properties - this allows adding properties to a given method later. Is used by Script.request.
390395 // V8TODO: Should these be deleted when the script-owned object is destroyed? It needs checking if script-owned objects will be garbage-collected, or will self-referencing prevent it.
391396 for (auto i = _methods.begin(); i != _methods.end(); i++) {
392397 //V8TODO: lifetime may prevent garbage collection?
393398 V8ScriptValue method = ScriptMethodV8Proxy::newMethod(_engine, qobject, V8ScriptValue(_engine, v8Object),
394− i.value().methods, i.value().numMaxParms);
395− if(!propertiesObject->Set(_engine->getContext(), i.value().name.constGet(), method.get()).FromMaybe(false)) {
399+ i.value().methods, i.value().numMaxParams);
400+ if(!propertiesObject->Set(_engine->getContext(), v8::String::NewFromUtf8(isolate, i.value().name.toStdString().c_str()).ToLocalChecked(), method.get()).FromMaybe(false)) {
396401 Q_ASSERT(false);
397402 }
398403 }
@@ -416,6 +421,7 @@ QString ScriptObjectV8Proxy::name() const { · 17 unmodified lines
416421 return _object->metaObject()->className();
417422 }
418423
424+// V8TODO: check if it would be more optimal to use V8ScriptString& name or QString name
419425 ScriptObjectV8Proxy::QueryFlags ScriptObjectV8Proxy::queryProperty(const V8ScriptValue& object, const V8ScriptString& name, QueryFlags flags, uint* id) {
420426 auto isolate = _engine->getIsolate();
421427 v8::Locker locker(isolate);
@@ -424,7 +430,7 @@ ScriptObjectV8Proxy::QueryFlags ScriptObjectV8Proxy::queryProperty(const V8Scrip · 2 unmodified lines
424430 // V8TODO: this might be inefficient when there's large number of properties
425431 v8::Local<v8::Context> context = _engine->getContext();
426432 v8::Context::Scope contextScope(context);
427− v8::String::Utf8Value nameStr(isolate, name.constGet());
433+ QString nameStr(*v8::String::Utf8Value(isolate, name.constGet()));
428434
429435 // check for methods
430436 /*for (MethodDefMap::const_iterator trans = _methods.cbegin(); trans != _methods.cend(); ++trans) {
@@ -434,7 +440,7 @@ ScriptObjectV8Proxy::QueryFlags ScriptObjectV8Proxy::queryProperty(const V8Scrip · 3 unmodified lines
434440 *id = trans.key() | METHOD_TYPE;
435441 return flags & (HandlesReadAccess | HandlesWriteAccess);
436442 }*/
437− MethodNameMap::const_iterator method = _methodNameMap.find(name);
443+ MethodNameMap::const_iterator method = _methodNameMap.find(nameStr);
438444 if (method != _methodNameMap.cend()) {
439445 //v8::String::Utf8Value methodNameStr(isolate, trans.value().name.constGet());
440446 //qCDebug(scriptengine_v8) << "queryProperty : " << *nameStr << " method: " << *methodNameStr;
@@ -450,7 +456,7 @@ ScriptObjectV8Proxy::QueryFlags ScriptObjectV8Proxy::queryProperty(const V8Scrip · 9 unmodified lines
450456 *id = trans.key() | PROPERTY_TYPE;
451457 return flags & (HandlesReadAccess | HandlesWriteAccess);
452458 }*/
453− PropertyNameMap::const_iterator prop = _propNameMap.find(name);
459+ PropertyNameMap::const_iterator prop = _propNameMap.find(nameStr);
454460 if (prop != _propNameMap.cend()) {
455461 const PropertyDef* propDef = prop.value();
456462 *id = propDef->_id | PROPERTY_TYPE;
@@ -458,8 +464,9 @@ ScriptObjectV8Proxy::QueryFlags ScriptObjectV8Proxy::queryProperty(const V8Scrip · 1 unmodified line
458464 }
459465
460466 // check for signals
467+ // V8TODO: this should use _signalNameMap QHash for faster search
461468 for (SignalDefMap::const_iterator trans = _signals.cbegin(); trans != _signals.cend(); ++trans) {
462− if (!(trans.value().name == name)) continue;
469+ if (!(trans.value().name == nameStr)) continue;
463470 *id = trans.key() | SIGNAL_TYPE;
464471 return flags & (HandlesReadAccess | HandlesWriteAccess);
465472 }
@@ -627,17 +634,20 @@ v8::Local<v8::Array> ScriptObjectV8Proxy::getPropertyNames() { · 161 unmodified lines
627634 v8::Local<v8::Array> properties = v8::Array::New(isolate, _props.size() + _methods.size() + _signals.size());
628635 uint32_t position = 0;
629636 for (PropertyDefMap::const_iterator i = _props.begin(); i != _props.end(); i++){
630− if(!properties->Set(context, position++, i.value().name.constGet()).FromMaybe(false)) {
637+ v8::Local<v8::String> name = v8::String::NewFromUtf8(isolate, i.value().name.toStdString().c_str()).ToLocalChecked();
638+ if(!properties->Set(context, position++, name).FromMaybe(false)) {
631639 qCDebug(scriptengine_v8) << "ScriptObjectV8Proxy::getPropertyNames: Cannot add property member name";
632640 }
633641 }
634642 for (MethodDefMap::const_iterator i = _methods.begin(); i != _methods.end(); i++){
635− if(!properties->Set(context, position++, i.value().name.constGet()).FromMaybe(false)) {
643+ v8::Local<v8::String> name = v8::String::NewFromUtf8(isolate, i.value().name.toStdString().c_str()).ToLocalChecked();
644+ if(!properties->Set(context, position++, name).FromMaybe(false)) {
636645 qCDebug(scriptengine_v8) << "ScriptObjectV8Proxy::getPropertyNames: Cannot add property member name";
637646 }
638647 }
639648 for (SignalDefMap::const_iterator i = _signals.begin(); i != _signals.end(); i++){
640− if(!properties->Set(context, position++, i.value().name.constGet()).FromMaybe(false)) {
649+ v8::Local<v8::String> name = v8::String::NewFromUtf8(isolate, i.value().name.toStdString().c_str()).ToLocalChecked();
650+ if(!properties->Set(context, position++, name).FromMaybe(false)) {
641651 qCDebug(scriptengine_v8) << "ScriptObjectV8Proxy::getPropertyNames: Cannot add property member name";
642652 }
643653 }
@@ -692,7 +702,7 @@ V8ScriptValue ScriptObjectV8Proxy::property(const V8ScriptValue& object, const V · 48 unmodified lines
692702 }
693703 Q_ASSERT(false);
694704 qCDebug(scriptengine_v8) << "(This should not happen) Creating new method object for " << metaObject->className() << " " << name.toQString();
695− return ScriptMethodV8Proxy::newMethod(_engine, qobject, object, methodDef.methods, methodDef.numMaxParms);
705+ return ScriptMethodV8Proxy::newMethod(_engine, qobject, object, methodDef.methods, methodDef.numMaxParams);
696706 }
697707 case SIGNAL_TYPE: {
698708 int signalId = id & ~TYPE_MASK;