aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@theqtcompany.com>2015-01-09 23:36:57 +0100
committerSimon Hausmann <simon.hausmann@digia.com>2015-01-12 11:04:36 +0100
commitb29a1aee35bc6e79beb028c92e5aab9bee0c18b3 (patch)
treefff5e8400fa797108f1835128c775bdab934bdb3 /src
parent431458b685fa9f7355f50d21a09ee9f93bcb42d5 (diff)
Move extensible into the internal class
With this, we can now save one pointer per Heap object. Change-Id: I7f69193ff51c9fd9c5dbfba90aa1ebb3f93da2e6 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'src')
-rw-r--r--src/qml/jsruntime/qv4internalclass.cpp26
-rw-r--r--src/qml/jsruntime/qv4internalclass_p.h5
-rw-r--r--src/qml/jsruntime/qv4object_p.h3
-rw-r--r--src/qml/jsruntime/qv4objectproto.cpp6
-rw-r--r--src/qml/jsruntime/qv4value_p.h15
5 files changed, 32 insertions, 23 deletions
diff --git a/src/qml/jsruntime/qv4internalclass.cpp b/src/qml/jsruntime/qv4internalclass.cpp
index 8c44d65426..2115ee09a0 100644
--- a/src/qml/jsruntime/qv4internalclass.cpp
+++ b/src/qml/jsruntime/qv4internalclass.cpp
@@ -116,6 +116,7 @@ InternalClass::InternalClass(ExecutionEngine *engine)
, m_sealed(0)
, m_frozen(0)
, size(0)
+ , extensible(true)
{
}
@@ -130,7 +131,9 @@ InternalClass::InternalClass(const QV4::InternalClass &other)
, m_sealed(0)
, m_frozen(0)
, size(other.size)
+ , extensible(other.extensible)
{
+ Q_ASSERT(extensible);
}
void InternalClass::changeMember(Object *object, String *string, PropertyAttributes data, uint *index)
@@ -228,6 +231,27 @@ InternalClass *InternalClass::changeVTable(const ManagedVTable *vt)
return newClass;
}
+InternalClass *InternalClass::nonExtensible()
+{
+ if (!extensible)
+ return this;
+
+ Transition temp;
+ temp.vtable = 0;
+ temp.lookup = 0;
+ temp.flags = Transition::NotExtensible;
+
+ Transition &t = lookupOrInsertTransition(temp);
+ if (t.lookup)
+ return t.lookup;
+
+ InternalClass *newClass = engine->newClass(*this);
+ newClass->extensible = false;
+
+ t.lookup = newClass;
+ return newClass;
+}
+
void InternalClass::addMember(Object *object, String *string, PropertyAttributes data, uint *index)
{
data.resolve();
@@ -357,6 +381,7 @@ InternalClass *InternalClass::sealed()
attrs.setConfigurable(false);
m_sealed = m_sealed->addMember(nameMap.at(i), attrs);
}
+ m_sealed = m_sealed->nonExtensible();
m_sealed->m_sealed = m_sealed;
return m_sealed;
@@ -377,6 +402,7 @@ InternalClass *InternalClass::frozen()
attrs.setConfigurable(false);
m_frozen = m_frozen->addMember(nameMap.at(i), attrs);
}
+ m_frozen = m_frozen->nonExtensible();
m_frozen->m_frozen = m_frozen;
m_frozen->m_sealed = m_frozen;
diff --git a/src/qml/jsruntime/qv4internalclass_p.h b/src/qml/jsruntime/qv4internalclass_p.h
index 5973ca2c7c..b92bee3fac 100644
--- a/src/qml/jsruntime/qv4internalclass_p.h
+++ b/src/qml/jsruntime/qv4internalclass_p.h
@@ -197,7 +197,8 @@ struct InternalClassTransition
int flags;
enum {
// range 0-0xff is reserved for attribute changes
- VTableChange = 0x100
+ VTableChange = 0x100,
+ NotExtensible = 0x200
};
bool operator==(const InternalClassTransition &other) const
@@ -223,9 +224,11 @@ struct InternalClass : public QQmlJS::Managed {
InternalClass *m_frozen;
uint size;
+ bool extensible;
static InternalClass *create(ExecutionEngine *engine, const ManagedVTable *vtable);
InternalClass *changeVTable(const ManagedVTable *vt);
+ InternalClass *nonExtensible();
static void addMember(Object *object, String *string, PropertyAttributes data, uint *index);
InternalClass *addMember(String *string, PropertyAttributes data, uint *index = 0);
InternalClass *addMember(Identifier *identifier, PropertyAttributes data, uint *index = 0);
diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h
index a38750dd07..298779906b 100644
--- a/src/qml/jsruntime/qv4object_p.h
+++ b/src/qml/jsruntime/qv4object_p.h
@@ -140,8 +140,7 @@ struct Q_QML_EXPORT Object: Managed {
inline ExecutionEngine *engine() const { return internalClass()->engine; }
- bool isExtensible() const { return d()->extensible; }
- void setExtensible(bool b) { d()->extensible = b; }
+ bool isExtensible() const { return d()->internalClass->extensible; }
// Array handling
diff --git a/src/qml/jsruntime/qv4objectproto.cpp b/src/qml/jsruntime/qv4objectproto.cpp
index 34a9b9cb64..445d4f7a68 100644
--- a/src/qml/jsruntime/qv4objectproto.cpp
+++ b/src/qml/jsruntime/qv4objectproto.cpp
@@ -244,8 +244,6 @@ ReturnedValue ObjectPrototype::method_seal(CallContext *ctx)
if (!o)
return ctx->engine()->throwTypeError();
- o->setExtensible(false);
-
o->setInternalClass(o->internalClass()->sealed());
if (o->arrayData()) {
@@ -269,8 +267,6 @@ ReturnedValue ObjectPrototype::method_freeze(CallContext *ctx)
if (ArgumentsObject::isNonStrictArgumentsObject(o))
Scoped<ArgumentsObject>(scope, o)->fullyCreate();
- o->setExtensible(false);
-
o->setInternalClass(o->internalClass()->frozen());
if (o->arrayData()) {
@@ -292,7 +288,7 @@ ReturnedValue ObjectPrototype::method_preventExtensions(CallContext *ctx)
if (!o)
return ctx->engine()->throwTypeError();
- o->setExtensible(false);
+ o->setInternalClass(o->internalClass()->nonExtensible());
return o.asReturnedValue();
}
diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h
index 31db8a21c5..526cb01ac4 100644
--- a/src/qml/jsruntime/qv4value_p.h
+++ b/src/qml/jsruntime/qv4value_p.h
@@ -50,7 +50,6 @@ struct Q_QML_EXPORT Base {
Base() {}
Base(InternalClass *internal)
: internalClass(internal)
- , extensible(1)
{
Q_ASSERT(inUse() && !isMarked());
// ####
@@ -60,20 +59,6 @@ struct Q_QML_EXPORT Base {
InternalClass *internalClass;
quintptr mm_data;
};
- struct {
- uchar _markBit : 1;
- uchar _inUse : 1;
- uchar extensible : 1; // used by Object
- uchar _needsActivation : 1; // used by FunctionObject
- uchar _strictMode : 1; // used by FunctionObject
- uchar _bindingKeyFlag : 1;
- uchar _hasAccessorProperty : 1;
- uchar _unused : 1;
- mutable uchar _subtype;
- uchar _unused2;
- uchar _unused3;
-
- };
void setVTable(const ManagedVTable *vt);
inline ReturnedValue asReturnedValue() const;