diff options
author | Lars Knoll <lars.knoll@theqtcompany.com> | 2015-08-27 14:38:24 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@theqtcompany.com> | 2015-09-22 08:19:59 +0000 |
commit | 9420eb5c4e55d68b996bb0120db1f2dfeeef3a8c (patch) | |
tree | b8d3e9b6c41f728de1749f5fe029046277c4a9d4 | |
parent | 17a0c271e0ec606d15fc87dab23b2e3750c0e301 (diff) |
Use the new construction scheme for RegExpObjects
Gives around 10% speed improvement on the v8 regexp
benchmark.
Change-Id: Iad37bcbc79ccbfb92f65852b660364c919862a75
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
-rw-r--r-- | src/qml/jsruntime/qv4engine.cpp | 25 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4engine_p.h | 1 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4object.cpp | 1 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4regexpobject.cpp | 50 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4regexpobject_p.h | 25 |
5 files changed, 46 insertions, 56 deletions
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index e9c285ea45..d881474bbc 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -332,7 +332,20 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory) protoClass = emptyClass->addMember(id_constructor(), Attr_NotEnumerable, &index); Q_ASSERT(index == Heap::FunctionObject::Index_ProtoConstructor); - jsObjects[RegExpProto] = memoryManager->alloc<RegExpPrototype>(this); + Scope scope(this); + ScopedString str(scope); + regExpObjectClass = emptyClass->addMember(id_lastIndex(), Attr_NotEnumerable|Attr_NotConfigurable, &index); + Q_ASSERT(index == RegExpObject::Index_LastIndex); + regExpObjectClass = regExpObjectClass->addMember((str = newIdentifier(QStringLiteral("source"))), Attr_ReadOnly, &index); + Q_ASSERT(index == RegExpObject::Index_Source); + regExpObjectClass = regExpObjectClass->addMember((str = newIdentifier(QStringLiteral("global"))), Attr_ReadOnly, &index); + Q_ASSERT(index == RegExpObject::Index_Global); + regExpObjectClass = regExpObjectClass->addMember((str = newIdentifier(QStringLiteral("ignoreCase"))), Attr_ReadOnly, &index); + Q_ASSERT(index == RegExpObject::Index_IgnoreCase); + regExpObjectClass = regExpObjectClass->addMember((str = newIdentifier(QStringLiteral("multiline"))), Attr_ReadOnly, &index); + Q_ASSERT(index == RegExpObject::Index_Multiline); + + jsObjects[RegExpProto] = memoryManager->allocObject<RegExpPrototype>(regExpObjectClass, objectPrototype()); regExpExecArrayClass = arrayClass->addMember(id_index(), Attr_Data, &index); Q_ASSERT(index == RegExpObject::Index_ArrayIndex); regExpExecArrayClass = regExpExecArrayClass->addMember(id_input(), Attr_Data, &index); @@ -349,7 +362,6 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory) jsObjects[VariantProto] = memoryManager->alloc<VariantPrototype>(emptyClass, objectPrototype()); Q_ASSERT(variantPrototype()->prototype() == objectPrototype()->d()); - Scope scope(this); jsObjects[SequenceProto] = ScopedValue(scope, memoryManager->alloc<SequencePrototype>(arrayClass, arrayPrototype())); ExecutionContext *global = rootContext(); @@ -431,7 +443,6 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory) globalObject->defineDefaultProperty(QStringLiteral("ArrayBuffer"), *arrayBufferCtor()); globalObject->defineDefaultProperty(QStringLiteral("DataView"), *dataViewCtor()); - ScopedString str(scope); for (int i = 0; i < Heap::TypedArray::NTypes; ++i) globalObject->defineDefaultProperty((str = typedArrayCtors[i].as<FunctionObject>()->name())->toQString(), typedArrayCtors[i]); ScopedObject o(scope); @@ -643,16 +654,12 @@ Heap::RegExpObject *ExecutionEngine::newRegExpObject(const QString &pattern, int Heap::RegExpObject *ExecutionEngine::newRegExpObject(RegExp *re, bool global) { - Scope scope(this); - Scoped<RegExpObject> object(scope, memoryManager->alloc<RegExpObject>(this, re, global)); - return object->d(); + return memoryManager->allocObject<RegExpObject>(regExpObjectClass, regExpPrototype(), re, global); } Heap::RegExpObject *ExecutionEngine::newRegExpObject(const QRegExp &re) { - Scope scope(this); - Scoped<RegExpObject> object(scope, memoryManager->alloc<RegExpObject>(this, re)); - return object->d(); + return memoryManager->allocObject<RegExpObject>(regExpObjectClass, regExpPrototype(), re); } Heap::Object *ExecutionEngine::newErrorObject(const Value &value) diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h index dc57f05ba1..64c3d1cb99 100644 --- a/src/qml/jsruntime/qv4engine_p.h +++ b/src/qml/jsruntime/qv4engine_p.h @@ -230,6 +230,7 @@ public: InternalClass *protoClass; InternalClass *regExpExecArrayClass; + InternalClass *regExpObjectClass; InternalClass *argumentsObjectClass; InternalClass *strictArgumentsObjectClass; diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp index c8b703e198..2245e1de61 100644 --- a/src/qml/jsruntime/qv4object.cpp +++ b/src/qml/jsruntime/qv4object.cpp @@ -215,7 +215,6 @@ void Object::markObjects(Heap::Base *that, ExecutionEngine *e) if (o->inlineMemberSize) { Value *v = o->propertyData(0); - Q_ASSERT(((char *)v) - ((char *)that) == sizeof(Heap::Object)); for (uint i = 0; i < o->inlineMemberSize; ++i) v[i].mark(e); } diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp index 6ee485b811..1839ff17ab 100644 --- a/src/qml/jsruntime/qv4regexpobject.cpp +++ b/src/qml/jsruntime/qv4regexpobject.cpp @@ -62,35 +62,30 @@ Q_CORE_EXPORT QString qt_regexp_toCanonical(const QString &, QRegExp::PatternSyn using namespace QV4; DEFINE_OBJECT_VTABLE(RegExpObject); -DEFINE_OBJECT_VTABLE(RegExpPrototype); -Heap::RegExpObject::RegExpObject(InternalClass *ic, QV4::Object *prototype) - : Heap::Object(ic, prototype) +Heap::RegExpObject::RegExpObject() { - Scope scope(ic->engine); + Scope scope(internalClass->engine); Scoped<QV4::RegExpObject> o(scope, this); - o->d()->value = QV4::RegExp::create(ic->engine, QString(), false, false); + o->d()->value = QV4::RegExp::create(scope.engine, QString(), false, false); o->d()->global = false; - o->init(ic->engine); + o->initProperties(); } -Heap::RegExpObject::RegExpObject(QV4::ExecutionEngine *engine, QV4::RegExp *value, bool global) - : Heap::Object(engine->emptyClass, engine->regExpPrototype()) - , value(value->d()) +Heap::RegExpObject::RegExpObject(QV4::RegExp *value, bool global) + : value(value->d()) , global(global) { - Scope scope(engine); + Scope scope(internalClass->engine); Scoped<QV4::RegExpObject> o(scope, this); - o->init(engine); + o->initProperties(); } // Converts a QRegExp to a JS RegExp. // The conversion is not 100% exact since ECMA regexp and QRegExp // have different semantics/flags, but we try to do our best. -Heap::RegExpObject::RegExpObject(QV4::ExecutionEngine *engine, const QRegExp &re) - : Heap::Object(engine->emptyClass, engine->regExpPrototype()) +Heap::RegExpObject::RegExpObject(const QRegExp &re) { - value = 0; global = false; // Convert the pattern to a ECMAScript pattern. @@ -130,26 +125,21 @@ Heap::RegExpObject::RegExpObject(QV4::ExecutionEngine *engine, const QRegExp &re pattern = ecmaPattern; } - Scope scope(engine); + Scope scope(internalClass->engine); Scoped<QV4::RegExpObject> o(scope, this); - o->d()->value = QV4::RegExp::create(engine, pattern, re.caseSensitivity() == Qt::CaseInsensitive, false); + o->d()->value = QV4::RegExp::create(scope.engine, pattern, re.caseSensitivity() == Qt::CaseInsensitive, false); - o->init(engine); + o->initProperties(); } -void RegExpObject::init(ExecutionEngine *engine) +void RegExpObject::initProperties() { - Scope scope(engine); - ScopedObject protectThis(scope, this); + *propertyData(Index_LastIndex) = Primitive::fromInt32(0); - ScopedString lastIndex(scope, engine->newIdentifier(QStringLiteral("lastIndex"))); - ScopedValue v(scope, Primitive::fromInt32(0)); - insertMember(lastIndex, v, Attr_NotEnumerable|Attr_NotConfigurable); - if (!this->value()) - return; + Q_ASSERT(value()); - QString p = this->value()->pattern; + QString p = value()->pattern; if (p.isEmpty()) { p = QStringLiteral("(?:)"); } else { @@ -157,10 +147,10 @@ void RegExpObject::init(ExecutionEngine *engine) p.replace('/', QLatin1String("\\/")); } - defineReadonlyProperty(QStringLiteral("source"), (v = engine->newString(p))); - defineReadonlyProperty(QStringLiteral("global"), Primitive::fromBoolean(global())); - defineReadonlyProperty(QStringLiteral("ignoreCase"), Primitive::fromBoolean(this->value()->ignoreCase)); - defineReadonlyProperty(QStringLiteral("multiline"), Primitive::fromBoolean(this->value()->multiLine)); + *propertyData(Index_Source) = engine()->newString(p); + *propertyData(Index_Global) = Primitive::fromBoolean(global()); + *propertyData(Index_IgnoreCase) = Primitive::fromBoolean(value()->ignoreCase); + *propertyData(Index_Multiline) = Primitive::fromBoolean(value()->multiLine); } diff --git a/src/qml/jsruntime/qv4regexpobject_p.h b/src/qml/jsruntime/qv4regexpobject_p.h index 04fc838147..0c9757a514 100644 --- a/src/qml/jsruntime/qv4regexpobject_p.h +++ b/src/qml/jsruntime/qv4regexpobject_p.h @@ -57,9 +57,9 @@ namespace QV4 { namespace Heap { struct RegExpObject : Object { - RegExpObject(InternalClass *ic, QV4::Object *prototype); - RegExpObject(QV4::ExecutionEngine *engine, QV4::RegExp *value, bool global); - RegExpObject(QV4::ExecutionEngine *engine, const QRegExp &re); + RegExpObject(); + RegExpObject(QV4::RegExp *value, bool global); + RegExpObject(const QRegExp &re); Pointer<RegExp> value; bool global; @@ -74,11 +74,6 @@ struct RegExpCtor : FunctionObject { void clearLastMatch(); }; -struct RegExpPrototype : RegExpObject -{ - inline RegExpPrototype(ExecutionEngine *e); -}; - } struct RegExpObject: Object { @@ -93,6 +88,11 @@ struct RegExpObject: Object { }; enum { + Index_LastIndex = 0, + Index_Source = 1, + Index_Global = 2, + Index_IgnoreCase = 3, + Index_Multiline = 4, Index_ArrayIndex = Heap::ArrayObject::LengthPropertyIndex + 1, Index_ArrayInput = Index_ArrayIndex + 1 }; @@ -100,7 +100,7 @@ struct RegExpObject: Object { Heap::RegExp *value() const { return d()->value; } bool global() const { return d()->global; } - void init(ExecutionEngine *engine); + void initProperties(); Value *lastIndexProperty(); QRegExp toQRegExp() const; @@ -128,8 +128,6 @@ struct RegExpCtor: FunctionObject struct RegExpPrototype: RegExpObject { - V4_OBJECT2(RegExpPrototype, RegExpObject) - void init(ExecutionEngine *engine, Object *ctor); static ReturnedValue method_exec(CallContext *ctx); @@ -145,11 +143,6 @@ struct RegExpPrototype: RegExpObject static ReturnedValue method_get_rightContext(CallContext *ctx); }; -inline Heap::RegExpPrototype::RegExpPrototype(ExecutionEngine *e) - : RegExpObject(e->emptyClass, e->objectPrototype()) -{ -} - } QT_END_NAMESPACE |