Selaa lähdekoodia

Make GlobOpt handle new class construction ops, shorten some names for clarity

Paul Leathers 6 vuotta sitten
vanhempi
sitoutus
31a0c1bbdc

+ 4 - 11
lib/Backend/GlobOpt.cpp

@@ -13931,21 +13931,14 @@ GlobOpt::CheckJsArrayKills(IR::Instr *const instr)
             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)

+ 8 - 1
lib/Backend/GlobOptFields.cpp

@@ -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:

+ 1 - 1
lib/Backend/IRBuilder.cpp

@@ -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);

+ 1 - 1
lib/Backend/JnHelperMethodList.h

@@ -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)
 

+ 2 - 2
lib/Backend/Lower.cpp

@@ -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:

+ 14 - 2
lib/Backend/Opnd.cpp

@@ -2284,7 +2284,19 @@ 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())
@@ -2292,7 +2304,7 @@ AddrOpnd::IsEqualInternal(Opnd *opnd)
         return false;
     }
 
-    return m_address == opnd->AsAddrOpnd()->m_address;
+    return IsEqualAddr(opnd->AsAddrOpnd()->m_address);
 }
 
 void

+ 3 - 1
lib/Backend/Opnd.h

@@ -1515,7 +1515,9 @@ public:
 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; }

+ 1 - 1
lib/Runtime/ByteCode/OpCodes.h

@@ -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)
 

+ 1 - 1
lib/Runtime/Language/InterpreterStackFrame.cpp

@@ -7912,7 +7912,7 @@ skipThunk:
         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}

+ 4 - 4
lib/Runtime/Language/JavascriptOperators.cpp

@@ -7772,11 +7772,11 @@ SetElementIHelper_INDEX_TYPE_IS_NUMBER:
         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)

+ 1 - 1
lib/Runtime/Language/JavascriptOperators.h

@@ -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);

+ 5 - 5
lib/Runtime/Library/JavascriptLibrary.cpp

@@ -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;

+ 3 - 3
lib/Runtime/Library/JavascriptLibrary.h

@@ -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();