aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@theqtcompany.com>2015-08-27 14:38:24 +0200
committerLars Knoll <lars.knoll@theqtcompany.com>2015-09-22 08:19:59 +0000
commit9420eb5c4e55d68b996bb0120db1f2dfeeef3a8c (patch)
treeb8d3e9b6c41f728de1749f5fe029046277c4a9d4
parent17a0c271e0ec606d15fc87dab23b2e3750c0e301 (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.cpp25
-rw-r--r--src/qml/jsruntime/qv4engine_p.h1
-rw-r--r--src/qml/jsruntime/qv4object.cpp1
-rw-r--r--src/qml/jsruntime/qv4regexpobject.cpp50
-rw-r--r--src/qml/jsruntime/qv4regexpobject_p.h25
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