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
255 v8::HandleScope handleScope(_engine->getIsolate());255 v8::HandleScope handleScope(_engine->getIsolate());
256 v8::Context::Scope contextScope(_engine->getContext());256 v8::Context::Scope contextScope(_engine->getContext());
257 257
258 const QMetaObject* metaObject = qobject->metaObject();
259
258 //auto objectTemplate = _v8ObjectTemplate.Get(_engine->getIsolate());260 //auto objectTemplate = _v8ObjectTemplate.Get(_engine->getIsolate());
259 auto objectTemplate = v8::ObjectTemplate::New(_engine->getIsolate());261 auto objectTemplate = v8::ObjectTemplate::New(_engine->getIsolate());
260 objectTemplate->SetInternalFieldCount(3);262 objectTemplate->SetInternalFieldCount(3);
261 objectTemplate->SetHandler(v8::NamedPropertyHandlerConfiguration(v8Get, v8Set, nullptr, nullptr, v8GetPropertyNames));263 objectTemplate->SetHandler(v8::NamedPropertyHandlerConfiguration(v8Get, v8Set, nullptr, nullptr, v8GetPropertyNames));
262 264
263 const QMetaObject* metaObject = qobject->metaObject();
264
265 //qCDebug(scriptengine_v8) << "Investigate: " << metaObject->className();265 //qCDebug(scriptengine_v8) << "Investigate: " << metaObject->className();
266 if (QString("ConsoleScriptingInterface") == metaObject->className()) {266 if (QString("ConsoleScriptingInterface") == metaObject->className()) {
267 printf("ConsoleScriptingInterface");267 printf("ConsoleScriptingInterface");
@@ -283,9 +283,9 @@ void ScriptObjectV8Proxy::investigate() { · 15 unmodified lines
283 }283 }
284 }284 }
285 285
286 auto v8Name = v8::String::NewFromUtf8(_engine->getIsolate(), prop.name()).ToLocalChecked();286 //auto v8Name = v8::String::NewFromUtf8(_engine->getIsolate(), prop.name()).ToLocalChecked();
287 PropertyDef& propDef = _props.insert(idx, PropertyDef(_engine, v8Name, idx)).value();287 PropertyDef& propDef = _props.insert(idx, PropertyDef(prop.name(), idx)).value();
288 _propNameMap.insert(V8ScriptString(_engine, v8Name), &propDef);288 _propNameMap.insert(prop.name(), &propDef);
289 propDef.flags = ScriptValue::Undeletable | ScriptValue::PropertyGetter | ScriptValue::PropertySetter |289 propDef.flags = ScriptValue::Undeletable | ScriptValue::PropertyGetter | ScriptValue::PropertySetter |
290 ScriptValue::QObjectMember;290 ScriptValue::QObjectMember;
291 if (prop.isConstant()) propDef.flags |= ScriptValue::ReadOnly;291 if (prop.isConstant()) propDef.flags |= ScriptValue::ReadOnly;
@@ -294,7 +294,7 @@ void ScriptObjectV8Proxy::investigate() { · 2 unmodified lines
294 // discover methods294 // discover methods
295 startIdx = (_wrapOptions & ScriptEngine::ExcludeSuperClassMethods) ? metaObject->methodOffset() : 0;295 startIdx = (_wrapOptions & ScriptEngine::ExcludeSuperClassMethods) ? metaObject->methodOffset() : 0;
296 num = metaObject->methodCount();296 num = metaObject->methodCount();
297 QHash<V8ScriptString, int> methodNames;297 QHash<QString, int> methodNames;
298 for (int idx = startIdx; idx < num; ++idx) {298 for (int idx = startIdx; idx < num; ++idx) {
299 QMetaMethod method = metaObject->method(idx);299 QMetaMethod method = metaObject->method(idx);
300 //qCDebug(scriptengine_v8) << "Investigate: " << metaObject->className() << " Method: " << method.name();300 //qCDebug(scriptengine_v8) << "Investigate: " << metaObject->className() << " Method: " << method.name();
@@ -325,17 +325,17 @@ void ScriptObjectV8Proxy::investigate() { · 24 unmodified lines
325 325
326 auto nameString = v8::String::NewFromUtf8(_engine->getIsolate(), szName.data(), v8::NewStringType::kNormal, szName.length()).ToLocalChecked();326 auto nameString = v8::String::NewFromUtf8(_engine->getIsolate(), szName.data(), v8::NewStringType::kNormal, szName.length()).ToLocalChecked();
327 V8ScriptString name(_engine, nameString);327 V8ScriptString name(_engine, nameString);
328 auto nameLookup = methodNames.find(name);328 auto nameLookup = methodNames.find(szName);
329 if (isSignal) {329 if (isSignal) {
330 if (nameLookup == methodNames.end()) {330 if (nameLookup == methodNames.end()) {
331 SignalDef& signalDef = _signals.insert(idx, SignalDef(_engine, name.get(), idx)).value();331 SignalDef& signalDef = _signals.insert(idx, SignalDef(szName, idx)).value();
332 signalDef.name = name;332 signalDef.name = szName;
333 signalDef.signal = method;333 signalDef.signal = method;
334 _signalNameMap.insert(name, &signalDef);334 _signalNameMap.insert(szName, &signalDef);
335 //qCDebug(scriptengine_v8) << "Utf8Value 1: " << QString(*v8::String::Utf8Value(const_cast<v8::Isolate*>(_engine->getIsolate()), nameString));335 //qCDebug(scriptengine_v8) << "Utf8Value 1: " << QString(*v8::String::Utf8Value(const_cast<v8::Isolate*>(_engine->getIsolate()), nameString));
336 //qCDebug(scriptengine_v8) << "Utf8Value 2: " << QString(*v8::String::Utf8Value(const_cast<v8::Isolate*>(_engine->getIsolate()), name.constGet()));336 //qCDebug(scriptengine_v8) << "Utf8Value 2: " << QString(*v8::String::Utf8Value(const_cast<v8::Isolate*>(_engine->getIsolate()), name.constGet()));
337 //qCDebug(scriptengine_v8) << "toQString: " << name.toQString();337 //qCDebug(scriptengine_v8) << "toQString: " << name.toQString();
338 methodNames.insert(name, idx);338 methodNames.insert(szName, idx);
339 } else {339 } else {
340 int originalMethodId = nameLookup.value();340 int originalMethodId = nameLookup.value();
341 SignalDefMap::iterator signalLookup = _signals.find(originalMethodId);341 SignalDefMap::iterator signalLookup = _signals.find(originalMethodId);
@@ -357,18 +357,18 @@ void ScriptObjectV8Proxy::investigate() { · 15 unmodified lines
357 }357 }
358 }358 }
359 if (nameLookup == methodNames.end()) {359 if (nameLookup == methodNames.end()) {
360 MethodDef& methodDef = _methods.insert(idx, MethodDef(_engine, name.get(), idx)).value();360 MethodDef& methodDef = _methods.insert(idx, MethodDef(szName, idx)).value();
361 methodDef.name = name;361 methodDef.name = szName;
362 methodDef.numMaxParms = parameterCount;362 methodDef.numMaxParams = parameterCount;
363 methodDef.methods.append(method);363 methodDef.methods.append(method);
364 _methodNameMap.insert(name, &methodDef);364 _methodNameMap.insert(szName, &methodDef);
365 methodNames.insert(name, idx);365 methodNames.insert(szName, idx);
366 } else {366 } else {
367 int originalMethodId = nameLookup.value();367 int originalMethodId = nameLookup.value();
368 MethodDefMap::iterator methodLookup = _methods.find(originalMethodId);368 MethodDefMap::iterator methodLookup = _methods.find(originalMethodId);
369 Q_ASSERT(methodLookup != _methods.end());369 Q_ASSERT(methodLookup != _methods.end());
370 MethodDef& methodDef = methodLookup.value();370 MethodDef& methodDef = methodLookup.value();
371 if(methodDef.numMaxParms < parameterCount) methodDef.numMaxParms = parameterCount;371 if(methodDef.numMaxParams < parameterCount) methodDef.numMaxParams = parameterCount;
372 methodDef.methods.append(method);372 methodDef.methods.append(method);
373 }373 }
374 }374 }
@@ -386,13 +386,18 @@ void ScriptObjectV8Proxy::investigate() { · 11 unmodified lines
386 _v8Object.SetWeak(this, weakHandleCallback, v8::WeakCallbackType::kParameter);386 _v8Object.SetWeak(this, weakHandleCallback, v8::WeakCallbackType::kParameter);
387 }387 }
388 388
389 /*if (QString(metaObject->className()) == QString("TestQObject")) {
390 //qDebug() << "TestQObject investigate: _methods.size: " << _methods.size();
391 return;
392 }*/
393
389 // Add all the methods objects as properties - this allows adding properties to a given method later. Is used by Script.request.394 // Add all the methods objects as properties - this allows adding properties to a given method later. Is used by Script.request.
390 // 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.395 // 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.
391 for (auto i = _methods.begin(); i != _methods.end(); i++) {396 for (auto i = _methods.begin(); i != _methods.end(); i++) {
392 //V8TODO: lifetime may prevent garbage collection?397 //V8TODO: lifetime may prevent garbage collection?
393 V8ScriptValue method = ScriptMethodV8Proxy::newMethod(_engine, qobject, V8ScriptValue(_engine, v8Object),398 V8ScriptValue method = ScriptMethodV8Proxy::newMethod(_engine, qobject, V8ScriptValue(_engine, v8Object),
394 i.value().methods, i.value().numMaxParms);399 i.value().methods, i.value().numMaxParams);
395 if(!propertiesObject->Set(_engine->getContext(), i.value().name.constGet(), method.get()).FromMaybe(false)) {400 if(!propertiesObject->Set(_engine->getContext(), v8::String::NewFromUtf8(isolate, i.value().name.toStdString().c_str()).ToLocalChecked(), method.get()).FromMaybe(false)) {
396 Q_ASSERT(false);401 Q_ASSERT(false);
397 }402 }
398 }403 }
@@ -416,6 +421,7 @@ QString ScriptObjectV8Proxy::name() const { · 17 unmodified lines
416 return _object->metaObject()->className();421 return _object->metaObject()->className();
417}422}
418 423
424// V8TODO: check if it would be more optimal to use V8ScriptString& name or QString name
419ScriptObjectV8Proxy::QueryFlags ScriptObjectV8Proxy::queryProperty(const V8ScriptValue& object, const V8ScriptString& name, QueryFlags flags, uint* id) {425ScriptObjectV8Proxy::QueryFlags ScriptObjectV8Proxy::queryProperty(const V8ScriptValue& object, const V8ScriptString& name, QueryFlags flags, uint* id) {
420 auto isolate = _engine->getIsolate();426 auto isolate = _engine->getIsolate();
421 v8::Locker locker(isolate);427 v8::Locker locker(isolate);
@@ -424,7 +430,7 @@ ScriptObjectV8Proxy::QueryFlags ScriptObjectV8Proxy::queryProperty(const V8Scrip · 2 unmodified lines
424 // V8TODO: this might be inefficient when there's large number of properties430 // V8TODO: this might be inefficient when there's large number of properties
425 v8::Local<v8::Context> context = _engine->getContext();431 v8::Local<v8::Context> context = _engine->getContext();
426 v8::Context::Scope contextScope(context);432 v8::Context::Scope contextScope(context);
427 v8::String::Utf8Value nameStr(isolate, name.constGet());433 QString nameStr(*v8::String::Utf8Value(isolate, name.constGet()));
428 434
429 // check for methods435 // check for methods
430 /*for (MethodDefMap::const_iterator trans = _methods.cbegin(); trans != _methods.cend(); ++trans) {436 /*for (MethodDefMap::const_iterator trans = _methods.cbegin(); trans != _methods.cend(); ++trans) {
@@ -434,7 +440,7 @@ ScriptObjectV8Proxy::QueryFlags ScriptObjectV8Proxy::queryProperty(const V8Scrip · 3 unmodified lines
434 *id = trans.key() | METHOD_TYPE;440 *id = trans.key() | METHOD_TYPE;
435 return flags & (HandlesReadAccess | HandlesWriteAccess);441 return flags & (HandlesReadAccess | HandlesWriteAccess);
436 }*/442 }*/
437 MethodNameMap::const_iterator method = _methodNameMap.find(name);443 MethodNameMap::const_iterator method = _methodNameMap.find(nameStr);
438 if (method != _methodNameMap.cend()) {444 if (method != _methodNameMap.cend()) {
439 //v8::String::Utf8Value methodNameStr(isolate, trans.value().name.constGet());445 //v8::String::Utf8Value methodNameStr(isolate, trans.value().name.constGet());
440 //qCDebug(scriptengine_v8) << "queryProperty : " << *nameStr << " method: " << *methodNameStr;446 //qCDebug(scriptengine_v8) << "queryProperty : " << *nameStr << " method: " << *methodNameStr;
@@ -450,7 +456,7 @@ ScriptObjectV8Proxy::QueryFlags ScriptObjectV8Proxy::queryProperty(const V8Scrip · 9 unmodified lines
450 *id = trans.key() | PROPERTY_TYPE;456 *id = trans.key() | PROPERTY_TYPE;
451 return flags & (HandlesReadAccess | HandlesWriteAccess);457 return flags & (HandlesReadAccess | HandlesWriteAccess);
452 }*/458 }*/
453 PropertyNameMap::const_iterator prop = _propNameMap.find(name);459 PropertyNameMap::const_iterator prop = _propNameMap.find(nameStr);
454 if (prop != _propNameMap.cend()) {460 if (prop != _propNameMap.cend()) {
455 const PropertyDef* propDef = prop.value();461 const PropertyDef* propDef = prop.value();
456 *id = propDef->_id | PROPERTY_TYPE;462 *id = propDef->_id | PROPERTY_TYPE;
@@ -458,8 +464,9 @@ ScriptObjectV8Proxy::QueryFlags ScriptObjectV8Proxy::queryProperty(const V8Scrip · 1 unmodified line
458 }464 }
459 465
460 // check for signals466 // check for signals
467 // V8TODO: this should use _signalNameMap QHash for faster search
461 for (SignalDefMap::const_iterator trans = _signals.cbegin(); trans != _signals.cend(); ++trans) {468 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;
463 *id = trans.key() | SIGNAL_TYPE;470 *id = trans.key() | SIGNAL_TYPE;
464 return flags & (HandlesReadAccess | HandlesWriteAccess);471 return flags & (HandlesReadAccess | HandlesWriteAccess);
465 }472 }
@@ -627,17 +634,20 @@ v8::Local<v8::Array> ScriptObjectV8Proxy::getPropertyNames() { · 161 unmodified lines
627 v8::Local<v8::Array> properties = v8::Array::New(isolate, _props.size() + _methods.size() + _signals.size());634 v8::Local<v8::Array> properties = v8::Array::New(isolate, _props.size() + _methods.size() + _signals.size());
628 uint32_t position = 0;635 uint32_t position = 0;
629 for (PropertyDefMap::const_iterator i = _props.begin(); i != _props.end(); i++){636 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)) {
631 qCDebug(scriptengine_v8) << "ScriptObjectV8Proxy::getPropertyNames: Cannot add property member name";639 qCDebug(scriptengine_v8) << "ScriptObjectV8Proxy::getPropertyNames: Cannot add property member name";
632 }640 }
633 }641 }
634 for (MethodDefMap::const_iterator i = _methods.begin(); i != _methods.end(); i++){642 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)) {
636 qCDebug(scriptengine_v8) << "ScriptObjectV8Proxy::getPropertyNames: Cannot add property member name";645 qCDebug(scriptengine_v8) << "ScriptObjectV8Proxy::getPropertyNames: Cannot add property member name";
637 }646 }
638 }647 }
639 for (SignalDefMap::const_iterator i = _signals.begin(); i != _signals.end(); i++){648 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)) {
641 qCDebug(scriptengine_v8) << "ScriptObjectV8Proxy::getPropertyNames: Cannot add property member name";651 qCDebug(scriptengine_v8) << "ScriptObjectV8Proxy::getPropertyNames: Cannot add property member name";
642 }652 }
643 }653 }
@@ -692,7 +702,7 @@ V8ScriptValue ScriptObjectV8Proxy::property(const V8ScriptValue& object, const V · 48 unmodified lines
692 }702 }
693 Q_ASSERT(false);703 Q_ASSERT(false);
694 qCDebug(scriptengine_v8) << "(This should not happen) Creating new method object for " << metaObject->className() << " " << name.toQString();704 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);
696 }706 }
697 case SIGNAL_TYPE: {707 case SIGNAL_TYPE: {
698 int signalId = id & ~TYPE_MASK;708 int signalId = id & ~TYPE_MASK;