Unify layout of function objects
Ensure we have the proto property at always the same place. This will be used in a subsequent commit to optimize accesses to the prototype property e.g. when doing instanceof operations or constructor calls. Change-Id: I6e9a19e0b7d0e8ab583648a60d1978f5cf838b06 Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
This commit is contained in:
parent
9df44b2b50
commit
7c59262503
|
@ -351,23 +351,29 @@ ExecutionEngine::ExecutionEngine(QJSEngine *jsEngine)
|
|||
jsObjects[FunctionProto] = memoryManager->allocObject<FunctionPrototype>(ic->d());
|
||||
ic = newInternalClass(FunctionObject::staticVTable(), functionPrototype());
|
||||
classes[Class_FunctionObject] = ic->d();
|
||||
// Add an invalid prototype slot, so that all function objects have the same layout
|
||||
// This helps speed up instanceof operations and other things where we need to query
|
||||
// prototype property (as we always know it's location)
|
||||
ic = ic->addMember(id_prototype()->propertyKey(), Attr_Invalid, index);
|
||||
Q_ASSERT(index->index == Heap::FunctionObject::Index_Prototype);
|
||||
ic = ic->addMember(id_name()->propertyKey(), Attr_ReadOnly, index);
|
||||
Q_ASSERT(index->index == Heap::ArrowFunction::Index_Name);
|
||||
ic = ic->addMember(id_length()->propertyKey(), Attr_ReadOnly_ButConfigurable, index);
|
||||
Q_ASSERT(index->index == Heap::ArrowFunction::Index_Length);
|
||||
classes[Class_ArrowFunction] = ic->changeVTable(ArrowFunction::staticVTable());
|
||||
ic = ic->changeVTable(ScriptFunction::staticVTable());
|
||||
classes[Class_ScriptFunction] = ic->d();
|
||||
ic = ic->changeVTable(ConstructorFunction::staticVTable());
|
||||
classes[Class_ConstructorFunction] = ic->d();
|
||||
ic = ic->changeVTable(MemberFunction::staticVTable());
|
||||
classes[Class_MemberFunction] = ic->d();
|
||||
ic = ic->changeVTable(GeneratorFunction::staticVTable());
|
||||
classes[Class_MemberFunction] = ic->d();
|
||||
ic = ic->changeVTable(GeneratorFunction::staticVTable());
|
||||
classes[Class_GeneratorFunction] = ic->d();
|
||||
ic = ic->changeVTable(MemberGeneratorFunction::staticVTable());
|
||||
classes[Class_MemberGeneratorFunction] = ic->d();
|
||||
|
||||
ic = ic->changeMember(id_prototype()->propertyKey(), Attr_NotConfigurable|Attr_NotEnumerable);
|
||||
ic = ic->changeVTable(ScriptFunction::staticVTable());
|
||||
classes[Class_ScriptFunction] = ic->d();
|
||||
ic = ic->changeVTable(ConstructorFunction::staticVTable());
|
||||
classes[Class_ConstructorFunction] = ic->d();
|
||||
|
||||
classes[Class_ObjectProto] = classes[Class_Object]->addMember(id_constructor()->propertyKey(), Attr_NotEnumerable, index);
|
||||
Q_ASSERT(index->index == Heap::FunctionObject::Index_ProtoConstructor);
|
||||
|
||||
|
|
|
@ -76,7 +76,8 @@ namespace Heap {
|
|||
DECLARE_HEAP_OBJECT(FunctionObject, Object) {
|
||||
DECLARE_MARKOBJECTS(FunctionObject);
|
||||
enum {
|
||||
Index_ProtoConstructor = 0
|
||||
Index_ProtoConstructor = 0,
|
||||
Index_Prototype = 0
|
||||
};
|
||||
|
||||
bool isConstructor() const {
|
||||
|
@ -111,7 +112,7 @@ struct IndexedBuiltinFunction : FunctionObject {
|
|||
|
||||
struct ArrowFunction : FunctionObject {
|
||||
enum {
|
||||
Index_Name,
|
||||
Index_Name = Index_Prototype + 1,
|
||||
Index_Length
|
||||
};
|
||||
void init(QV4::ExecutionContext *scope, Function *function, QV4::String *name = nullptr);
|
||||
|
@ -122,10 +123,6 @@ struct ArrowFunction : FunctionObject {
|
|||
|
||||
DECLARE_HEAP_OBJECT(ScriptFunction, ArrowFunction) {
|
||||
DECLARE_MARKOBJECTS(ScriptFunction)
|
||||
enum {
|
||||
Index_Name,
|
||||
Index_Length
|
||||
};
|
||||
void init(QV4::ExecutionContext *scope, Function *function);
|
||||
};
|
||||
|
||||
|
|
|
@ -233,6 +233,10 @@ struct InternalClass : Managed
|
|||
return d()->addMember(identifier, data, entry);
|
||||
}
|
||||
|
||||
Q_REQUIRED_RESULT Heap::InternalClass *changeMember(PropertyKey identifier, PropertyAttributes data, InternalClassEntry *entry = nullptr) {
|
||||
return d()->changeMember(identifier, data, entry);
|
||||
}
|
||||
|
||||
void operator =(Heap::InternalClass *ic) {
|
||||
Value::operator=(ic);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue