Skip to content
Permalink
Browse files

Make GlobOpt handle new class construction ops, shorten some names fo…

…r clarity
  • Loading branch information
pleath committed Dec 5, 2019
1 parent 0a70737 commit 31a0c1bbdc7212dbc47b8e9056f8f75e6b067344
break;
}

case Js::OpCode::InitClass:
case Js::OpCode::NewClassProto:
Assert(instr->GetSrc1());
if (instr->GetSrc2() == nullptr)
if (IR::AddrOpnd::IsEqualAddr(instr->GetSrc1(), (void*)func->GetScriptContextInfo()->GetObjectPrototypeAddr()))
{
// No extends operand, so the InitClass will not make something into a prototype
// No extends operand, the proto parent is the Object prototype
break;
}

if(doNativeArrayTypeSpec)
{
// Class/object construction can make something a prototype
kills.SetKillsNativeArrays();
}
break;

// Fall through
case Js::OpCode::NewScObjectNoCtor:
case Js::OpCode::NewScObjectNoCtorFull:
if(doNativeArrayTypeSpec)
@@ -564,7 +564,14 @@ GlobOpt::ProcessFieldKills(IR::Instr *instr, BVSparse<JitArenaAllocator> *bv, bo
}
break;

case Js::OpCode::InitClass:
case Js::OpCode::NewClassProto:
Assert(instr->GetSrc1());
if (IR::AddrOpnd::IsEqualAddr(instr->GetSrc1(), (void*)func->GetScriptContextInfo()->GetObjectPrototypeAddr()))
{
// No extends operand, the proto parent is the Object prototype
break;
}
// Fall through
case Js::OpCode::InitProto:
case Js::OpCode::NewScObjectNoCtor:
case Js::OpCode::NewScObjectNoCtorFull:
@@ -2401,7 +2401,7 @@ IRBuilder::BuildInitClass(uint32 offset, Js::RegSlot regConstructor, Js::RegSlot
{
IR::RegOpnd * opndProto = BuildDstOpnd(regProto);
opndProto->SetValueType(ValueType::GetObject(ObjectType::Object));
IR::Instr * instr = IR::Instr::New(Js::OpCode::NewClassCtorProto, opndProto, opndProtoParent, m_func);
IR::Instr * instr = IR::Instr::New(Js::OpCode::NewClassProto, opndProto, opndProtoParent, m_func);
this->AddInstr(instr, offset);

instr = IR::Instr::New(Js::OpCode::ExtendArg_A, IR::RegOpnd::New(TyVar, m_func), opndConstructorParent, m_func);
@@ -330,7 +330,7 @@ HELPERCALLCHK(NewScObjectNoArgNoCtor, Js::JavascriptOperators::NewScObjectNoArgN
HELPERCALLCHK(UpdateNewScObjectCache, Js::JavascriptOperators::UpdateNewScObjectCache, AttrCanNotBeReentrant)
HELPERCALLCHK(EnsureObjectLiteralType, Js::JavascriptOperators::EnsureObjectLiteralType, AttrCanNotBeReentrant)

HELPERCALLCHK(Op_NewClassCtorProto, Js::JavascriptOperators::OP_NewClassCtorProto, AttrCanNotBeReentrant)
HELPERCALLCHK(Op_NewClassProto, Js::JavascriptOperators::OP_NewClassProto, AttrCanNotBeReentrant)

HELPERCALLCHK(OP_ClearAttributes, Js::JavascriptOperators::OP_ClearAttributes, AttrCanThrow | AttrCanNotBeReentrant)

@@ -2817,8 +2817,8 @@ Lowerer::LowerRange(IR::Instr *instrStart, IR::Instr *instrEnd, bool defaultDoFa
case Js::OpCode::DeletedNonHelperBranch:
break;

case Js::OpCode::NewClassCtorProto:
this->LowerUnaryHelperMem(instr, IR::HelperOp_NewClassCtorProto);
case Js::OpCode::NewClassProto:
this->LowerUnaryHelperMem(instr, IR::HelperOp_NewClassProto);
break;

case Js::OpCode::NewClassConstructor:
@@ -2284,15 +2284,27 @@ AddrOpnd::CopyInternal(Func *func)
///----------------------------------------------------------------------------

bool
AddrOpnd::IsEqualInternal(Opnd *opnd)
AddrOpnd::IsEqualAddr(Opnd *opnd, void *addr)
{
return opnd->IsAddrOpnd() && opnd->AsAddrOpnd()->IsEqualAddr(addr);
}

bool
AddrOpnd::IsEqualAddr(void *addr) const
{
return m_address == addr;
}

bool
AddrOpnd::IsEqualInternal(Opnd *opnd) const
{
Assert(m_kind == OpndKindAddr);
if (!opnd->IsAddrOpnd())
{
return false;
}

return m_address == opnd->AsAddrOpnd()->m_address;
return IsEqualAddr(opnd->AsAddrOpnd()->m_address);
}

void
@@ -1515,7 +1515,9 @@ class AddrOpnd sealed : public Opnd
public:
//Note type: OpndKindAddr
AddrOpnd * CopyInternal(Func *func);
bool IsEqualInternal(Opnd *opnd);
bool IsEqualInternal(Opnd *opnd) const;
bool IsEqualAddr(void *addr) const;
static bool IsEqualAddr(IR::Opnd * opnd, void * addr);
void FreeInternal(Func * func);

bool IsDynamic() const { return addrOpndKind > AddrOpndKindConstantVar; }
@@ -401,7 +401,7 @@ MACRO_EXTEND_WMS( InitClassMemberSetComputedName,ElementI, OpSideEffect
MACRO_EXTEND_WMS( InitClassMemberGetComputedName,ElementI, OpSideEffect|OpOpndHasImplicitCall|OpPostOpDbgBailOut) // Class member in get syntax with computed property name
MACRO_EXTEND_WMS( BrOnClassConstructor, BrReg1, None) // Branch if argument is a class constructor
MACRO_EXTEND_WMS( BrOnBaseConstructorKind, BrReg1, None) // Branch if argument's [[ConstructorKind]] is 'base'
MACRO_BACKEND_ONLY( NewClassCtorProto, Empty, OpSideEffect)
MACRO_BACKEND_ONLY( NewClassProto, Empty, OpSideEffect)
MACRO_BACKEND_ONLY( NewClassConstructor, Empty, OpSideEffect)
MACRO_BACKEND_ONLY( BrOnConstructor_A, BrReg1, None)

@@ -7912,7 +7912,7 @@ namespace Js
Assert(constructorParent && (JavascriptOperators::IsConstructor(constructorParent) || constructorParent == scriptContext->GetLibrary()->GetFunctionPrototype()));

// Create prototype object with the default class prototype object shape {'constructor': W:T, E:F, C:T} and [[Prototype]] == protoParent
DynamicObject * proto = scriptContext->GetLibrary()->CreateClassConstructorPrototypeObject(protoParent);
DynamicObject * proto = scriptContext->GetLibrary()->CreateClassPrototypeObject(protoParent);

// Create class constructor object for the constructor function, with default constructor shape:
// {'prototype': W:F, E:F, C:F}, {'length': W:F, E:F, C:T}, {'name': W:F, E:F, C:T}
@@ -7772,11 +7772,11 @@ using namespace Js;
JIT_HELPER_END(ScrObj_OP_IsInst);
}

Var JavascriptOperators::OP_NewClassCtorProto(Var protoParent, ScriptContext * scriptContext)
Var JavascriptOperators::OP_NewClassProto(Var protoParent, ScriptContext * scriptContext)
{
JIT_HELPER_NOT_REENTRANT_HEADER(Op_NewClassCtorProto, reentrancylock, scriptContext->GetThreadContext());
return scriptContext->GetLibrary()->CreateClassConstructorPrototypeObject(VarTo<RecyclableObject>(protoParent));
JIT_HELPER_END(Op_NewClassCtorProto);
JIT_HELPER_NOT_REENTRANT_HEADER(Op_NewClassProto, reentrancylock, scriptContext->GetThreadContext());
return scriptContext->GetLibrary()->CreateClassPrototypeObject(VarTo<RecyclableObject>(protoParent));
JIT_HELPER_END(Op_NewClassProto);
}

void JavascriptOperators::OP_LoadUndefinedToElement(Var instance, PropertyId propertyId)
@@ -540,7 +540,7 @@ namespace Js
static Var OP_NewPseudoScope(ScriptContext *scriptContext);
static Var OP_NewBlockScope(ScriptContext *scriptContext);
static Var OP_CloneBlockScope(BlockActivationObject *blockScope, ScriptContext *scriptContext);
static Var OP_NewClassCtorProto(Var protoParent, ScriptContext * scriptContext);
static Var OP_NewClassProto(Var protoParent, ScriptContext * scriptContext);
static void OP_LoadUndefinedToElement(Var instance, PropertyId propertyId);
static void OP_LoadUndefinedToElementDynamic(Var instance, PropertyId propertyId, ScriptContext* scriptContext);
static void OP_LoadUndefinedToElementScoped(FrameDisplay *pScope, PropertyId propertyId, Var defaultInstance, ScriptContext* scriptContext);
@@ -103,7 +103,7 @@ namespace Js
SimplePropertyDescriptor(NO_WRITE_BARRIER_TAG(BuiltInPropertyRecords::length), PropertyConfigurable)
};

SimplePropertyDescriptor const JavascriptLibrary::ClassConstructorPrototypePropertyDescriptors[1] =
SimplePropertyDescriptor const JavascriptLibrary::ClassPrototypePropertyDescriptors[1] =
{
SimplePropertyDescriptor(NO_WRITE_BARRIER_TAG(BuiltInPropertyRecords::constructor), PropertyConfigurable | PropertyWritable)
};
@@ -475,13 +475,13 @@ namespace Js
heapArgumentsType = DynamicType::New(scriptContext, TypeIds_Arguments, objectPrototype, nullptr,
SimpleDictionaryTypeHandler::New(scriptContext, HeapArgumentsPropertyDescriptors, _countof(HeapArgumentsPropertyDescriptors), 0, 0, true, true), true, true);

classConstructorPrototypeTypeHandler =
classPrototypeTypeHandler =
#if ENABLE_FIXED_FIELDS
SimpleDictionaryTypeHandler::NewInitialized
#else
SimpleDictionaryTypeHandler::New
#endif
(scriptContext, ClassConstructorPrototypePropertyDescriptors, _countof(ClassConstructorPrototypePropertyDescriptors), 0, 0, true, true);
(scriptContext, ClassPrototypePropertyDescriptors, _countof(ClassPrototypePropertyDescriptors), 0, 0, true, true);

TypePath *const strictHeapArgumentsTypePath = TypePath::New(recycler);
strictHeapArgumentsTypePath->Add(BuiltInPropertyRecords::callee);
@@ -6658,13 +6658,13 @@ namespace Js
return prototype;
}

DynamicObject* JavascriptLibrary::CreateClassConstructorPrototypeObject(RecyclableObject * protoParent)
DynamicObject* JavascriptLibrary::CreateClassPrototypeObject(RecyclableObject * protoParent)
{
// We can't share types of objects that are prototypes. If we gain the ability to do that, try using a shared type
// with a PathTypeHandler for this object. (PathTypeHandler and not SimpleTypeHandler, because it will likely have
// user-defined properties on it.) Until then, make a new type for each object and use a SimpleDictionaryTypeHandler.
DynamicType * dynamicType =
DynamicType::New(scriptContext, TypeIds_Object, protoParent, nullptr, classConstructorPrototypeTypeHandler);
DynamicType::New(scriptContext, TypeIds_Object, protoParent, nullptr, classPrototypeTypeHandler);
dynamicType->SetHasNoEnumerableProperties(true);
DynamicObject * proto = DynamicObject::New(this->GetRecycler(), dynamicType);
return proto;
@@ -295,7 +295,7 @@ namespace Js
Field(DynamicTypeHandler *) functionTypeHandlerWithLength;
Field(DynamicTypeHandler *) functionWithPrototypeAndLengthTypeHandler;
Field(DynamicTypeHandler *) functionWithPrototypeTypeHandler;
Field(DynamicTypeHandler *) classConstructorPrototypeTypeHandler;
Field(DynamicTypeHandler *) classPrototypeTypeHandler;

Field(DynamicType *) externalFunctionWithDeferredPrototypeType;
Field(DynamicType *) externalFunctionWithLengthAndDeferredPrototypeType;
@@ -556,7 +556,7 @@ namespace Js
static SimplePropertyDescriptor const FunctionWithNonWritablePrototypeAndLengthTypeDescriptors[2];
static SimplePropertyDescriptor const FunctionWithNonWritablePrototypeLengthAndNameTypeDescriptors[3];
static SimplePropertyDescriptor const ModuleNamespaceTypeDescriptors[1];
static SimplePropertyDescriptor const ClassConstructorPrototypePropertyDescriptors[1];
static SimplePropertyDescriptor const ClassPrototypePropertyDescriptors[1];

public:

@@ -1055,7 +1055,7 @@ namespace Js
DynamicObject* CreateGeneratorConstructorPrototypeObject();
DynamicObject* CreateAsyncGeneratorConstructorPrototypeObject();
DynamicObject* CreateConstructorPrototypeObject(JavascriptFunction * constructor);
DynamicObject* CreateClassConstructorPrototypeObject(RecyclableObject * protoParent);
DynamicObject* CreateClassPrototypeObject(RecyclableObject * protoParent);
DynamicObject* CreateObject(const bool allowObjectHeaderInlining = false, const PropertyIndex requestedInlineSlotCapacity = 0);
DynamicObject* CreateObject(DynamicTypeHandler * typeHandler);
DynamicObject* CreateActivationObject();

0 comments on commit 31a0c1b

Please sign in to comment.
You can’t perform that action at this time.