Bläddra i källkod

Revert recent change that introduced bugs that block internal tools

Seth Brenith (O'BRIEN) 8 år sedan
förälder
incheckning
bd7948bd59
69 ändrade filer med 380 tillägg och 625 borttagningar
  1. 1 2
      lib/Runtime/Language/CacheOperators.h
  2. 4 9
      lib/Runtime/Language/CacheOperators.inl
  3. 2 4
      lib/Runtime/Language/InlineCache.h
  4. 38 104
      lib/Runtime/Language/InlineCache.inl
  5. 8 8
      lib/Runtime/Language/InterpreterStackFrame.cpp
  6. 60 127
      lib/Runtime/Language/JavascriptOperators.cpp
  7. 1 7
      lib/Runtime/Language/JavascriptOperators.h
  8. 2 2
      lib/Runtime/Language/ModuleNamespace.cpp
  9. 1 1
      lib/Runtime/Language/ModuleNamespace.h
  10. 1 1
      lib/Runtime/Language/ProfilingHelpers.cpp
  11. 2 2
      lib/Runtime/Library/ArgumentsObject.cpp
  12. 1 1
      lib/Runtime/Library/ArgumentsObject.h
  13. 2 2
      lib/Runtime/Library/BoundFunction.cpp
  14. 1 1
      lib/Runtime/Library/BoundFunction.h
  15. 2 2
      lib/Runtime/Library/ES5Array.cpp
  16. 1 1
      lib/Runtime/Library/ES5Array.h
  17. 7 7
      lib/Runtime/Library/GlobalObject.cpp
  18. 1 1
      lib/Runtime/Library/GlobalObject.h
  19. 2 3
      lib/Runtime/Library/JSONStringifier.cpp
  20. 2 2
      lib/Runtime/Library/JavascriptArray.cpp
  21. 1 1
      lib/Runtime/Library/JavascriptArray.h
  22. 2 2
      lib/Runtime/Library/JavascriptFunction.cpp
  23. 1 1
      lib/Runtime/Library/JavascriptFunction.h
  24. 3 3
      lib/Runtime/Library/JavascriptGeneratorFunction.cpp
  25. 1 1
      lib/Runtime/Library/JavascriptGeneratorFunction.h
  26. 2 3
      lib/Runtime/Library/JavascriptObject.cpp
  27. 2 9
      lib/Runtime/Library/JavascriptProxy.cpp
  28. 1 1
      lib/Runtime/Library/JavascriptProxy.h
  29. 2 2
      lib/Runtime/Library/JavascriptRegExpConstructor.cpp
  30. 1 1
      lib/Runtime/Library/JavascriptRegExpConstructor.h
  31. 3 3
      lib/Runtime/Library/JavascriptRegularExpression.cpp
  32. 1 1
      lib/Runtime/Library/JavascriptRegularExpression.h
  33. 1 1
      lib/Runtime/Library/JavascriptString.cpp
  34. 1 1
      lib/Runtime/Library/JavascriptString.h
  35. 4 4
      lib/Runtime/Library/JavascriptStringObject.cpp
  36. 1 1
      lib/Runtime/Library/JavascriptStringObject.h
  37. 1 1
      lib/Runtime/Library/JavascriptVariantDate.h
  38. 4 4
      lib/Runtime/Library/ModuleRoot.cpp
  39. 1 1
      lib/Runtime/Library/ModuleRoot.h
  40. 65 59
      lib/Runtime/Library/PropertyRecordUsageCache.h
  41. 14 8
      lib/Runtime/Library/PropertyString.h
  42. 3 3
      lib/Runtime/Library/TypedArray.cpp
  43. 1 1
      lib/Runtime/Library/TypedArray.h
  44. 3 3
      lib/Runtime/Types/DeferredTypeHandler.h
  45. 33 46
      lib/Runtime/Types/DictionaryTypeHandler.cpp
  46. 3 4
      lib/Runtime/Types/DictionaryTypeHandler.h
  47. 1 1
      lib/Runtime/Types/DynamicObject.h
  48. 2 2
      lib/Runtime/Types/DynamicType.cpp
  49. 2 2
      lib/Runtime/Types/ES5ArrayTypeHandler.cpp
  50. 1 1
      lib/Runtime/Types/ES5ArrayTypeHandler.h
  51. 1 1
      lib/Runtime/Types/MissingPropertyTypeHandler.cpp
  52. 1 1
      lib/Runtime/Types/MissingPropertyTypeHandler.h
  53. 1 1
      lib/Runtime/Types/NullTypeHandler.cpp
  54. 1 1
      lib/Runtime/Types/NullTypeHandler.h
  55. 23 56
      lib/Runtime/Types/PathTypeHandler.cpp
  56. 1 5
      lib/Runtime/Types/PathTypeHandler.h
  57. 1 1
      lib/Runtime/Types/RecyclableObject.cpp
  58. 1 1
      lib/Runtime/Types/RecyclableObject.h
  59. 1 1
      lib/Runtime/Types/RecyclableObject.inl
  60. 23 28
      lib/Runtime/Types/SimpleDictionaryTypeHandler.cpp
  61. 3 4
      lib/Runtime/Types/SimpleDictionaryTypeHandler.h
  62. 1 6
      lib/Runtime/Types/SimpleTypeHandler.cpp
  63. 1 1
      lib/Runtime/Types/SimpleTypeHandler.h
  64. 1 1
      lib/Runtime/Types/SpreadArgument.h
  65. 1 1
      lib/Runtime/Types/TypeHandler.h
  66. 17 55
      lib/Runtime/Types/TypePropertyCache.cpp
  67. 0 1
      lib/Runtime/Types/TypePropertyCache.h
  68. 1 1
      lib/Runtime/Types/WithScopeObject.cpp
  69. 1 1
      lib/Runtime/Types/WithScopeObject.h

+ 1 - 2
lib/Runtime/Language/CacheOperators.h

@@ -29,8 +29,7 @@ namespace Js
             bool CheckTypePropertyCache,
             bool IsInlineCacheAvailable,
             bool IsPolymorphicInlineCacheAvailable,
-            bool ReturnOperationInfo,
-            bool OutputExistence /*When set, propertyValue represents whether the property exists on the instance, not its actual value*/>
+            bool ReturnOperationInfo>
         static bool TryGetProperty(Var const instance, const bool isRoot, RecyclableObject *const object, const PropertyId propertyId, Var *const propertyValue, ScriptContext *const requestContext, PropertyCacheOperationInfo * operationInfo, PropertyValueInfo *const propertyValueInfo);
         template<
             bool CheckLocal,

+ 4 - 9
lib/Runtime/Language/CacheOperators.inl

@@ -15,8 +15,7 @@ namespace Js
         bool CheckTypePropertyCache,
         bool IsInlineCacheAvailable,
         bool IsPolymorphicInlineCacheAvailable,
-        bool ReturnOperationInfo,
-        bool OutputExistence /*When set, propertyValue represents whether the property exists on the instance, not its actual value*/>
+        bool ReturnOperationInfo>
     inline bool CacheOperators::TryGetProperty(
         Var const instance,
         const bool isRoot,
@@ -39,7 +38,7 @@ namespace Js
             InlineCache *const inlineCache = IsInlineCacheAvailable ? propertyValueInfo->GetInlineCache() : nullptr;
             if(IsInlineCacheAvailable)
             {
-                if (inlineCache->TryGetProperty<CheckLocal, CheckProto, CheckAccessor, CheckMissing, ReturnOperationInfo, OutputExistence>(
+                if (inlineCache->TryGetProperty<CheckLocal, CheckProto, CheckAccessor, CheckMissing, ReturnOperationInfo>(
                         instance,
                         object,
                         propertyId,
@@ -74,8 +73,7 @@ namespace Js
                             CheckAccessor,
                             CheckMissing,
                             IsInlineCacheAvailable,
-                            ReturnOperationInfo,
-                            OutputExistence
+                            ReturnOperationInfo
                         >(
                             instance,
                             object,
@@ -98,7 +96,7 @@ namespace Js
 
         TypePropertyCache *const typePropertyCache = object->GetType()->GetPropertyCache();
         if(!typePropertyCache ||
-            !typePropertyCache->TryGetProperty<OutputExistence>(
+            !typePropertyCache->TryGetProperty(
                     CheckMissing,
                     object,
                     propertyId,
@@ -348,9 +346,6 @@ namespace Js
             {
                 return;
             }
-
-            // Before allowing proxies to cache, we would need to solve various issues (see JavascriptProxy::GetPropertyQuery).
-            Assert(!JavascriptProxy::Is(objectWithProperty));
         }
         else
         {

+ 2 - 4
lib/Runtime/Language/InlineCache.h

@@ -283,8 +283,7 @@ namespace Js
             bool CheckProto,
             bool CheckAccessor,
             bool CheckMissing,
-            bool ReturnOperationInfo,
-            bool OutputExistence /*When set, propertyValue is true or false, representing whether the property exists on the instance not its actual value*/>
+            bool ReturnOperationInfo>
         bool TryGetProperty(
             Var const instance,
             RecyclableObject *const propertyObject,
@@ -464,8 +463,7 @@ namespace Js
             bool CheckAccessor,
             bool CheckMissing,
             bool IsInlineCacheAvailable,
-            bool ReturnOperationInfo,
-            bool OutputExistence /*When set, propertyValue is true or false, representing whether the property exists on the instance not its actual value*/>
+            bool ReturnOperationInfo>
         bool TryGetProperty(
             Var const instance,
             RecyclableObject *const propertyObject,

+ 38 - 104
lib/Runtime/Language/InlineCache.inl

@@ -11,8 +11,7 @@ namespace Js
         bool CheckProto,
         bool CheckAccessor,
         bool CheckMissing,
-        bool ReturnOperationInfo,
-        bool OutputExistence /*When set, propertyValue represents whether the property exists on the instance, not its actual value*/>
+        bool ReturnOperationInfo>
     bool InlineCache::TryGetProperty(
         Var const instance,
         RecyclableObject *const propertyObject,
@@ -36,17 +35,9 @@ namespace Js
         if (CheckLocal && type == u.local.type)
         {
             Assert(propertyObject->GetScriptContext() == requestContext); // we never cache a type from another script context
-            if (OutputExistence)
-            {
-                *propertyValue = requestContext->GetLibrary()->GetTrue();
-                Assert(JavascriptOperators::HasProperty(propertyObject, propertyId));
-            }
-            else
-            {
-                *propertyValue = DynamicObject::UnsafeFromVar(propertyObject)->GetInlineSlot(u.local.slotIndex);
-                Assert(*propertyValue == JavascriptOperators::GetProperty(propertyObject, propertyId, requestContext) ||
-                    (RootObjectBase::Is(propertyObject) && *propertyValue == JavascriptOperators::GetRootProperty(propertyObject, propertyId, requestContext)));
-            }
+            *propertyValue = DynamicObject::UnsafeFromVar(propertyObject)->GetInlineSlot(u.local.slotIndex);
+            Assert(*propertyValue == JavascriptOperators::GetProperty(propertyObject, propertyId, requestContext) ||
+                (RootObjectBase::Is(propertyObject) && *propertyValue == JavascriptOperators::GetRootProperty(propertyObject, propertyId, requestContext)));
             if (ReturnOperationInfo)
             {
                 operationInfo->cacheType = CacheType_Local;
@@ -58,17 +49,9 @@ namespace Js
         if (CheckLocal && TypeWithAuxSlotTag(type) == u.local.type)
         {
             Assert(propertyObject->GetScriptContext() == requestContext); // we never cache a type from another script context
-            if (OutputExistence)
-            {
-                *propertyValue = requestContext->GetLibrary()->GetTrue();
-                Assert(JavascriptOperators::HasProperty(propertyObject, propertyId));
-            }
-            else
-            {
-                *propertyValue = DynamicObject::UnsafeFromVar(propertyObject)->GetAuxSlot(u.local.slotIndex);
-                Assert(*propertyValue == JavascriptOperators::GetProperty(propertyObject, propertyId, requestContext) ||
-                    (RootObjectBase::Is(propertyObject) && *propertyValue == JavascriptOperators::GetRootProperty(propertyObject, propertyId, requestContext)));
-            }
+            *propertyValue = DynamicObject::UnsafeFromVar(propertyObject)->GetAuxSlot(u.local.slotIndex);
+            Assert(*propertyValue == JavascriptOperators::GetProperty(propertyObject, propertyId, requestContext) ||
+                (RootObjectBase::Is(propertyObject) && *propertyValue == JavascriptOperators::GetRootProperty(propertyObject, propertyId, requestContext)));
             if (ReturnOperationInfo)
             {
                 operationInfo->cacheType = CacheType_Local;
@@ -80,17 +63,9 @@ namespace Js
         if (CheckProto && type == u.proto.type && !this->u.proto.isMissing)
         {
             Assert(u.proto.prototypeObject->GetScriptContext() == requestContext); // we never cache a type from another script context
-            if (OutputExistence)
-            {
-                *propertyValue = requestContext->GetLibrary()->GetTrue();
-                Assert(JavascriptOperators::HasProperty(propertyObject, propertyId));
-            }
-            else
-            {
-                *propertyValue = u.proto.prototypeObject->GetInlineSlot(u.proto.slotIndex);
-                Assert(*propertyValue == JavascriptOperators::GetProperty(propertyObject, propertyId, requestContext) ||
-                    (RootObjectBase::Is(propertyObject) && *propertyValue == JavascriptOperators::GetRootProperty(propertyObject, propertyId, requestContext)));
-            }
+            *propertyValue = u.proto.prototypeObject->GetInlineSlot(u.proto.slotIndex);
+            Assert(*propertyValue == JavascriptOperators::GetProperty(propertyObject, propertyId, requestContext) ||
+                (RootObjectBase::Is(propertyObject) && *propertyValue == JavascriptOperators::GetRootProperty(propertyObject, propertyId, requestContext)));
             if (ReturnOperationInfo)
             {
                 operationInfo->cacheType = CacheType_Proto;
@@ -102,17 +77,9 @@ namespace Js
         if (CheckProto && TypeWithAuxSlotTag(type) == u.proto.type && !this->u.proto.isMissing)
         {
             Assert(u.proto.prototypeObject->GetScriptContext() == requestContext); // we never cache a type from another script context
-            if (OutputExistence)
-            {
-                *propertyValue = requestContext->GetLibrary()->GetTrue();
-                Assert(JavascriptOperators::HasProperty(propertyObject, propertyId));
-            }
-            else
-            {
-                *propertyValue = u.proto.prototypeObject->GetAuxSlot(u.proto.slotIndex);
-                Assert(*propertyValue == JavascriptOperators::GetProperty(propertyObject, propertyId, requestContext) ||
-                    (RootObjectBase::Is(propertyObject) && *propertyValue == JavascriptOperators::GetRootProperty(propertyObject, propertyId, requestContext)));
-            }
+            *propertyValue = u.proto.prototypeObject->GetAuxSlot(u.proto.slotIndex);
+            Assert(*propertyValue == JavascriptOperators::GetProperty(propertyObject, propertyId, requestContext) ||
+                (RootObjectBase::Is(propertyObject) && *propertyValue == JavascriptOperators::GetRootProperty(propertyObject, propertyId, requestContext)));
             if (ReturnOperationInfo)
             {
                 operationInfo->cacheType = CacheType_Proto;
@@ -126,30 +93,22 @@ namespace Js
             Assert(propertyObject->GetScriptContext() == requestContext); // we never cache a type from another script context
             Assert(u.accessor.flags & InlineCacheGetterFlag);
 
-            if (OutputExistence)
+            RecyclableObject * function;
+            if (u.accessor.isOnProto)
             {
-                *propertyValue = requestContext->GetLibrary()->GetTrue();
-                Assert(JavascriptOperators::HasProperty(propertyObject, propertyId));
+                function = RecyclableObject::UnsafeFromVar(u.accessor.object->GetInlineSlot(u.accessor.slotIndex));
             }
             else
             {
-                RecyclableObject * function;
-                if (u.accessor.isOnProto)
-                {
-                    function = RecyclableObject::UnsafeFromVar(u.accessor.object->GetInlineSlot(u.accessor.slotIndex));
-                }
-                else
-                {
-                    function = RecyclableObject::UnsafeFromVar(DynamicObject::UnsafeFromVar(propertyObject)->GetInlineSlot(u.accessor.slotIndex));
-                }
+                function = RecyclableObject::UnsafeFromVar(DynamicObject::UnsafeFromVar(propertyObject)->GetInlineSlot(u.accessor.slotIndex));
+            }
 
-                *propertyValue = JavascriptOperators::CallGetter(function, instance, requestContext);
+            *propertyValue = JavascriptOperators::CallGetter(function, instance, requestContext);
 
-                // Can't assert because the getter could have a side effect
+            // Can't assert because the getter could have a side effect
 #ifdef CHKGETTER
-                Assert(JavascriptOperators::Equal(*propertyValue, JavascriptOperators::GetProperty(propertyObject, propertyId, requestContext), requestContext));
+            Assert(JavascriptOperators::Equal(*propertyValue, JavascriptOperators::GetProperty(propertyObject, propertyId, requestContext), requestContext));
 #endif
-            }
             if (ReturnOperationInfo)
             {
                 operationInfo->cacheType = CacheType_Getter;
@@ -163,30 +122,22 @@ namespace Js
             Assert(propertyObject->GetScriptContext() == requestContext); // we never cache a type from another script context
             Assert(u.accessor.flags & InlineCacheGetterFlag);
 
-            if (OutputExistence)
+            RecyclableObject * function;
+            if (u.accessor.isOnProto)
             {
-                *propertyValue = requestContext->GetLibrary()->GetTrue();
-                Assert(JavascriptOperators::HasProperty(propertyObject, propertyId));
+                function = RecyclableObject::UnsafeFromVar(u.accessor.object->GetAuxSlot(u.accessor.slotIndex));
             }
             else
             {
-                RecyclableObject * function;
-                if (u.accessor.isOnProto)
-                {
-                    function = RecyclableObject::UnsafeFromVar(u.accessor.object->GetAuxSlot(u.accessor.slotIndex));
-                }
-                else
-                {
-                    function = RecyclableObject::UnsafeFromVar(DynamicObject::FromVar(propertyObject)->GetAuxSlot(u.accessor.slotIndex));
-                }
+                function = RecyclableObject::UnsafeFromVar(DynamicObject::FromVar(propertyObject)->GetAuxSlot(u.accessor.slotIndex));
+            }
 
-                *propertyValue = JavascriptOperators::CallGetter(function, instance, requestContext);
+            *propertyValue = JavascriptOperators::CallGetter(function, instance, requestContext);
 
-                // Can't assert because the getter could have a side effect
+            // Can't assert because the getter could have a side effect
 #ifdef CHKGETTER
-                Assert(JavascriptOperators::Equal(*propertyValue, JavascriptOperators::GetProperty(propertyObject, propertyId, requestContext), requestContext));
+            Assert(JavascriptOperators::Equal(*propertyValue, JavascriptOperators::GetProperty(propertyObject, propertyId, requestContext), requestContext));
 #endif
-            }
             if (ReturnOperationInfo)
             {
                 operationInfo->cacheType = CacheType_Getter;
@@ -198,17 +149,9 @@ namespace Js
         if (CheckMissing && type == u.proto.type && this->u.proto.isMissing)
         {
             Assert(u.proto.prototypeObject->GetScriptContext() == requestContext); // we never cache a type from another script context
-            if (OutputExistence)
-            {
-                *propertyValue = requestContext->GetLibrary()->GetFalse();
-                Assert(!JavascriptOperators::HasProperty(propertyObject, propertyId));
-            }
-            else
-            {
-                *propertyValue = u.proto.prototypeObject->GetInlineSlot(u.proto.slotIndex);
-                Assert(*propertyValue == JavascriptOperators::GetProperty(propertyObject, propertyId, requestContext) ||
-                    (RootObjectBase::Is(propertyObject) && *propertyValue == JavascriptOperators::GetRootProperty(propertyObject, propertyId, requestContext)));
-            }
+            *propertyValue = u.proto.prototypeObject->GetInlineSlot(u.proto.slotIndex);
+            Assert(*propertyValue == JavascriptOperators::GetProperty(propertyObject, propertyId, requestContext) ||
+                (RootObjectBase::Is(propertyObject) && *propertyValue == JavascriptOperators::GetRootProperty(propertyObject, propertyId, requestContext)));
 
 #ifdef MISSING_PROPERTY_STATS
             if (PHASE_STATS1(MissingPropertyCachePhase))
@@ -228,17 +171,9 @@ namespace Js
         if (CheckMissing && TypeWithAuxSlotTag(type) == u.proto.type && this->u.proto.isMissing)
         {
             Assert(u.proto.prototypeObject->GetScriptContext() == requestContext); // we never cache a type from another script context
-            if (OutputExistence)
-            {
-                *propertyValue = requestContext->GetLibrary()->GetFalse();
-                Assert(!JavascriptOperators::HasProperty(propertyObject, propertyId));
-            }
-            else
-            {
-                *propertyValue = u.proto.prototypeObject->GetAuxSlot(u.proto.slotIndex);
-                Assert(*propertyValue == JavascriptOperators::GetProperty(propertyObject, propertyId, requestContext) ||
-                    (RootObjectBase::Is(propertyObject) && *propertyValue == JavascriptOperators::GetRootProperty(propertyObject, propertyId, requestContext)));
-            }
+            *propertyValue = u.proto.prototypeObject->GetAuxSlot(u.proto.slotIndex);
+            Assert(*propertyValue == JavascriptOperators::GetProperty(propertyObject, propertyId, requestContext) ||
+                (RootObjectBase::Is(propertyObject) && *propertyValue == JavascriptOperators::GetRootProperty(propertyObject, propertyId, requestContext)));
 
 #ifdef MISSING_PROPERTY_STATS
             if (PHASE_STATS1(MissingPropertyCachePhase))
@@ -605,8 +540,7 @@ namespace Js
         bool CheckAccessor,
         bool CheckMissing,
         bool IsInlineCacheAvailable,
-        bool ReturnOperationInfo,
-        bool OutputExistence /*When set, propertyValue is true or false, representing whether the property exists on the instance not its actual value*/>
+        bool ReturnOperationInfo>
     bool PolymorphicInlineCache::TryGetProperty(
         Var const instance,
         RecyclableObject *const propertyObject,
@@ -630,7 +564,7 @@ namespace Js
             isEmpty = cache->IsEmpty();
         }
 #endif
-        bool result = cache->TryGetProperty<CheckLocal, CheckProto, CheckAccessor, CheckMissing, ReturnOperationInfo, OutputExistence>(
+        bool result = cache->TryGetProperty<CheckLocal, CheckProto, CheckAccessor, CheckMissing, ReturnOperationInfo>(
             instance, propertyObject, propertyId, propertyValue, requestContext, operationInfo);
 
 #ifdef CLONE_INLINECACHE_TO_EMPTYSLOT
@@ -639,7 +573,7 @@ namespace Js
             result = CheckClonedInlineCache(inlineCacheIndex, [&](uint tryInlineCacheIndex) -> bool
             {
                 cache = &inlineCaches[tryInlineCacheIndex];
-                return cache->TryGetProperty<CheckLocal, CheckProto, CheckAccessor, CheckMissing, ReturnOperationInfo, OutputExistence>(
+                return cache->TryGetProperty<CheckLocal, CheckProto, CheckAccessor, CheckMissing, ReturnOperationInfo>(
                     instance, propertyObject, propertyId, propertyValue, requestContext, operationInfo);
             });
         }

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

@@ -3377,7 +3377,7 @@ namespace Js
         PropertyValueInfo::SetCacheInfo(&info, GetFunctionBody(), inlineCache, playout->inlineCacheIndex, true);
         Var aValue;
         if (obj &&
-            CacheOperators::TryGetProperty<true, true, false, false, false, false, true, false, false, false>(
+            CacheOperators::TryGetProperty<true, true, false, false, false, false, true, false, false>(
                 obj, false, obj, propertyId, &aValue, GetScriptContext(), nullptr, &info))
         {
             SetReg(playout->Value, aValue);
@@ -3423,7 +3423,7 @@ namespace Js
         PropertyValueInfo info;
         PropertyValueInfo::SetCacheInfo(&info, GetFunctionBody(), inlineCache, playout->inlineCacheIndex, true);
         Var aValue;
-        if (CacheOperators::TryGetProperty<true, true, false, false, false, false, true, false, false, false>(
+        if (CacheOperators::TryGetProperty<true, true, false, false, false, false, true, false, false>(
                 obj, true, obj, propertyId, &aValue, GetScriptContext(), nullptr, &info))
         {
             SetReg(playout->Value, aValue);
@@ -3481,7 +3481,7 @@ namespace Js
         PropertyValueInfo::SetCacheInfo(&info, GetFunctionBody(), inlineCache, playout->inlineCacheIndex, true);
         Var aValue;
         if (obj &&
-            CacheOperators::TryGetProperty<true, true, false, false, false, false, true, false, false, false>(
+            CacheOperators::TryGetProperty<true, true, false, false, false, false, true, false, false>(
                 obj, false, obj, propertyId, &aValue, GetScriptContext(), nullptr, &info))
         {
             threadContext->CheckAndResetImplicitCallAccessorFlag();
@@ -3810,7 +3810,7 @@ namespace Js
         PropertyValueInfo info;
         PropertyValueInfo::SetCacheInfo(&info, GetFunctionBody(), inlineCache, playout->inlineCacheIndex, true);
         Var value;
-        if(CacheOperators::TryGetProperty<true, false, false, false, false, false, true, false, false, false>(
+        if(CacheOperators::TryGetProperty<true, false, false, false, false, false, true, false, false>(
                 obj, true, obj, propertyId, &value, GetScriptContext(), nullptr, &info))
         {
             SetReg(playout->Value, value);
@@ -4011,7 +4011,7 @@ namespace Js
             PropertyValueInfo::SetCacheInfo(&info, GetFunctionBody(), inlineCache, playout->inlineCacheIndex, true);
 
             Var value;
-            if (CacheOperators::TryGetProperty<true, false, false, false, false, false, true, false, false, false>(
+            if (CacheOperators::TryGetProperty<true, false, false, false, false, false, true, false, false>(
                     obj, false, obj, propertyId, &value, GetScriptContext(), nullptr, &info))
             {
                 SetReg(playout->Value, value);
@@ -4037,7 +4037,7 @@ namespace Js
             PropertyValueInfo::SetCacheInfo(&info, GetFunctionBody(), inlineCache, playout->PropertyIdIndex, true);
 
             Var value;
-            if (CacheOperators::TryGetProperty<true, false, false, false, false, false, true, false, false, false>(
+            if (CacheOperators::TryGetProperty<true, false, false, false, false, false, true, false, false>(
                 thisObj, false, superObj, propertyId, &value, GetScriptContext(), nullptr, &info))
             {
                 SetReg(playout->Value, value);
@@ -4158,7 +4158,7 @@ namespace Js
             PropertyValueInfo info;
             PropertyValueInfo::SetCacheInfo(&info, GetFunctionBody(), inlineCache, playout->inlineCacheIndex, true);
             Var value;
-            if (CacheOperators::TryGetProperty<true, false, false, false, false, false, true, false, false, false>(
+            if (CacheOperators::TryGetProperty<true, false, false, false, false, false, true, false, false>(
                     obj, false, obj, propertyId, &value, scriptContext, nullptr, &info))
             {
                 threadContext->CheckAndResetImplicitCallAccessorFlag();
@@ -4195,7 +4195,7 @@ namespace Js
             PropertyValueInfo info;
             PropertyValueInfo::SetCacheInfo(&info, GetFunctionBody(), inlineCache, playout->inlineCacheIndex, true);
             Var value;
-            if (CacheOperators::TryGetProperty<true, false, false, false, false, false, true, false, false, false>(
+            if (CacheOperators::TryGetProperty<true, false, false, false, false, false, true, false, false>(
                 obj, false, obj, propertyId, &value, scriptContext, nullptr, &info))
             {
                 threadContext->CheckAndResetImplicitCallAccessorFlag();

+ 60 - 127
lib/Runtime/Language/JavascriptOperators.cpp

@@ -123,7 +123,6 @@ namespace Js
             else
             {
                 JavascriptString* indexStr = JavascriptConversion::ToString(indexVar, scriptContext);
-
                 char16 const * propertyName = indexStr->GetString();
                 charcount_t const propertyLength = indexStr->GetLength();
 
@@ -1420,7 +1419,7 @@ CommonNumber:
     {
         while (!JavascriptOperators::IsNull(instance))
         {
-            PropertyQueryFlags result = instance->HasPropertyQuery(propertyId, nullptr /*info*/);
+            PropertyQueryFlags result = instance->HasPropertyQuery(propertyId);
             if (result != PropertyQueryFlags::Property_NotFound)
             {
                 return JavascriptConversion::PropertyQueryFlagsToBoolean(result); // return false if instance is typed array and HasPropertyQuery() returns PropertyQueryFlags::Property_Found_Undefined
@@ -1772,38 +1771,16 @@ CommonNumber:
         }
     }
 
-    template<bool OutputExistence, typename PropertyKeyType> PropertyQueryFlags QueryGetOrHasProperty(
-        Var originalInstance, RecyclableObject* object, PropertyKeyType propertyKey, Var* value, PropertyValueInfo* info, ScriptContext* requestContext);
-    template<> PropertyQueryFlags QueryGetOrHasProperty<false /*OutputExistence*/, PropertyId /*PropertyKeyType*/>(
-        Var originalInstance, RecyclableObject* object, PropertyId propertyKey, Var* value, PropertyValueInfo* info, ScriptContext* requestContext)
-    {
-        return object->GetPropertyQuery(originalInstance, propertyKey, value, info, requestContext);
-    }
-    template<> PropertyQueryFlags QueryGetOrHasProperty<false /*OutputExistence*/, JavascriptString* /*PropertyKeyType*/>(
-        Var originalInstance, RecyclableObject* object, JavascriptString* propertyKey, Var* value, PropertyValueInfo* info, ScriptContext* requestContext)
-    {
-        return object->GetPropertyQuery(originalInstance, propertyKey, value, info, requestContext);
-    }
-    template<> PropertyQueryFlags QueryGetOrHasProperty<true /*OutputExistence*/, PropertyId /*PropertyKeyType*/>(
-        Var originalInstance, RecyclableObject* object, PropertyId propertyKey, Var* value, PropertyValueInfo* info, ScriptContext* requestContext)
-    {
-        PropertyQueryFlags result = object->HasPropertyQuery(propertyKey, info);
-        *value = JavascriptBoolean::ToVar(JavascriptConversion::PropertyQueryFlagsToBoolean(result), requestContext);
-        return result;
-    }
-
-    template<bool OutputExistence, typename PropertyKeyType>
+    template<typename PropertyKeyType>
     BOOL JavascriptOperators::GetPropertyWPCache(Var instance, RecyclableObject* propertyObject, PropertyKeyType propertyKey, Var* value, ScriptContext* requestContext, _Inout_ PropertyValueInfo * info)
     {
-        Assert(value);
         RecyclableObject* object = propertyObject;
         while (!JavascriptOperators::IsNull(object))
         {
-            PropertyQueryFlags result = QueryGetOrHasProperty<OutputExistence>(instance, object, propertyKey, value, info, requestContext);
-
+            PropertyQueryFlags result = object->GetPropertyQuery(instance, propertyKey, value, info, requestContext);
             if (result != PropertyQueryFlags::Property_NotFound)
             {
-                if (!WithScopeObject::Is(object) && info->GetPropertyRecordUsageCache())
+                if (value && !WithScopeObject::Is(object) && info->GetPropertyRecordUsageCache())
                 {
                     PropertyId propertyId = info->GetPropertyRecordUsageCache()->GetPropertyRecord()->GetPropertyId();
                     CacheOperators::CachePropertyRead(instance, object, false, propertyId, false, info, requestContext);
@@ -1822,9 +1799,7 @@ CommonNumber:
             CacheOperators::CachePropertyRead(instance, requestContext->GetLibrary()->GetMissingPropertyHolder(), false, info->GetPropertyRecordUsageCache()->GetPropertyRecord()->GetPropertyId(), true, info, requestContext);
         }
 
-        *value = OutputExistence
-            ? requestContext->GetLibrary()->GetFalse()
-            : requestContext->GetMissingPropertyResult();
+        *value = requestContext->GetMissingPropertyResult();
         return FALSE;
     }
 
@@ -3377,6 +3352,7 @@ CommonNumber:
 
     Var JavascriptOperators::OP_GetElementI(Var instance, Var index, ScriptContext* scriptContext)
     {
+        JavascriptString *temp = nullptr;
 #if ENABLE_COPYONACCESS_ARRAY
         JavascriptLibrary::CheckAndConvertCopyOnAccessNativeIntArray<Var>(instance);
 #endif
@@ -3647,72 +3623,56 @@ CommonNumber:
                 goto TaggedIntIndex;
             }
         }
-        else if (RecyclableObject::Is(instance))
-        {
-            RecyclableObject* cacheOwner;
-            PropertyRecordUsageCache* propertyRecordUsageCache;
-            if (GetPropertyRecordUsageCache(index, scriptContext, &propertyRecordUsageCache, &cacheOwner))
-            {
-                return GetElementIWithCache(instance, cacheOwner, propertyRecordUsageCache, scriptContext);
-            }
-        }
-
-        return JavascriptOperators::GetElementIHelper(instance, index, instance, scriptContext);
-    }
-
-    _Success_(return) bool JavascriptOperators::GetPropertyRecordUsageCache(Var index, ScriptContext* scriptContext, _Outptr_ PropertyRecordUsageCache** propertyRecordUsageCache, _Outptr_ RecyclableObject** cacheOwner)
-    {
-        JavascriptString* string = JavascriptOperators::TryFromVar<JavascriptString>(index);
-        if (string)
+        else
         {
-            PropertyString * propertyString = nullptr;
-            if (VirtualTableInfo<Js::PropertyString>::HasVirtualTable(string))
+            temp = JavascriptOperators::TryFromVar<JavascriptString>(index);
+            if (temp && RecyclableObject::Is(instance)) // fastpath for PropertyStrings
             {
-                propertyString = (PropertyString*)string;
-            }
-            else if (VirtualTableInfo<Js::LiteralStringWithPropertyStringPtr>::HasVirtualTable(string))
-            {
-                LiteralStringWithPropertyStringPtr * strWithPtr = (LiteralStringWithPropertyStringPtr *)string;
-                if (!strWithPtr->HasPropertyRecord())
+                PropertyString * propertyString = nullptr;
+                if (VirtualTableInfo<Js::PropertyString>::HasVirtualTable(temp))
                 {
-                    PropertyRecord const * propertyRecord;
-                    strWithPtr->GetPropertyRecord(&propertyRecord); // lookup-cache propertyRecord
+                    propertyString = (PropertyString*)temp;
                 }
-                else
+                else if (VirtualTableInfo<Js::LiteralStringWithPropertyStringPtr>::HasVirtualTable(temp))
                 {
-                    propertyString = strWithPtr->GetOrAddPropertyString();
-                    // this is the second time this property string is used
-                    // we already had created the propertyRecord..
-                    // now create the propertyString!
+                    LiteralStringWithPropertyStringPtr * strWithPtr = (LiteralStringWithPropertyStringPtr *)temp;
+                    if (!strWithPtr->HasPropertyRecord())
+                    {
+                        PropertyRecord const * propertyRecord;
+                        strWithPtr->GetPropertyRecord(&propertyRecord); // lookup-cache propertyRecord
+                    }
+                    else
+                    {
+                        propertyString = strWithPtr->GetOrAddPropertyString();
+                        // this is the second time this property string is used
+                        // we already had created the propertyRecord..
+                        // now create the propertyString!
+                    }
                 }
-            }
 
-            if (propertyString != nullptr)
-            {
-                *propertyRecordUsageCache = propertyString->GetPropertyRecordUsageCache();
-                *cacheOwner = propertyString;
-                return true;
-            }
+                if (propertyString != nullptr)
+                {
+                    return GetElementIWithCache(instance, propertyString, propertyString->GetPropertyRecordUsageCache(), scriptContext);
+                }
 #ifdef ENABLE_DEBUG_CONFIG_OPTIONS
-            if (PHASE_TRACE1(PropertyCachePhase))
-            {
-                Output::Print(_u("PropertyCache: GetElem No property string for '%s'\n"), string->GetString());
-            }
+                if (PHASE_TRACE1(PropertyCachePhase))
+                {
+                    Output::Print(_u("PropertyCache: GetElem No property string for '%s'\n"), temp->GetString());
+                }
 #endif
 #if DBG_DUMP
-            scriptContext->forinNoCache++;
+                scriptContext->forinNoCache++;
 #endif
-        }
+            }
 
-        JavascriptSymbol* symbol = JavascriptOperators::TryFromVar<JavascriptSymbol>(index);
-        if (symbol)
-        {
-            *propertyRecordUsageCache = symbol->GetPropertyRecordUsageCache();
-            *cacheOwner = symbol;
-            return true;
+            JavascriptSymbol* symbol = JavascriptOperators::TryFromVar<JavascriptSymbol>(index);
+            if (symbol && RecyclableObject::Is(instance)) // fastpath for JavascriptSymbols
+            {
+                return GetElementIWithCache(instance, symbol, symbol->GetPropertyRecordUsageCache(), scriptContext);
+            }
         }
 
-        return false;
+        return JavascriptOperators::GetElementIHelper(instance, index, instance, scriptContext);
     }
 
     Var JavascriptOperators::GetElementIWithCache(Var instance, RecyclableObject* index, PropertyRecordUsageCache* propertyRecordUsageCache, ScriptContext* scriptContext)
@@ -3737,11 +3697,11 @@ CommonNumber:
         else
         {
             PropertyValueInfo info;
-            if (propertyRecordUsageCache->TryGetPropertyFromCache<false /* OwnPropertyOnly */, false /* OutputExistence */>(instance, object, &value, scriptContext, &info, index))
+            if (propertyRecordUsageCache->TryGetPropertyFromCache<false /* OwnPropertyOnly */>(instance, object, &value, scriptContext, &info, index))
             {
                 return value;
             }
-            if (JavascriptOperators::GetPropertyWPCache<false /* OutputExistence */>(instance, object, propertyRecord->GetPropertyId(), &value, scriptContext, &info))
+            if (JavascriptOperators::GetPropertyWPCache(instance, object, propertyRecord->GetPropertyId(), &value, scriptContext, &info))
             {
                 return value;
             }
@@ -3781,7 +3741,7 @@ CommonNumber:
         else if (indexType == IndexType_JavascriptString)
         {
             PropertyValueInfo info;
-            if (JavascriptOperators::GetPropertyWPCache<false /* OutputExistence */>(receiver, object, propertyNameString, &value, scriptContext, &info))
+            if (JavascriptOperators::GetPropertyWPCache(receiver, object, propertyNameString, &value, scriptContext, &info))
             {
                 return value;
             }
@@ -3799,7 +3759,7 @@ CommonNumber:
             if (propertyRecord != nullptr)
             {
                 PropertyValueInfo info;
-                if (JavascriptOperators::GetPropertyWPCache<false /* OutputExistence */>(receiver, object, propertyRecord->GetPropertyId(), &value, scriptContext, &info))
+                if (JavascriptOperators::GetPropertyWPCache(receiver, object, propertyRecord->GetPropertyId(), &value, scriptContext, &info))
                 {
                     return value;
                 }
@@ -7155,48 +7115,21 @@ SetElementIHelper_INDEX_TYPE_IS_NUMBER:
             JavascriptError::ThrowTypeError(scriptContext, JSERR_Operand_Invalid_NeedObject, _u("in"));
         }
 
-        RecyclableObject* object = RecyclableObject::FromVar(instance);
-        BOOL result;
         PropertyRecord const * propertyRecord = nullptr;
         uint32 index;
-        IndexType indexType;
+        IndexType indexType = GetIndexType(argProperty, scriptContext, &index, &propertyRecord, true);
 
-        // Fast path for JavascriptSymbols and PropertyStrings
-        RecyclableObject* cacheOwner;
-        PropertyRecordUsageCache* propertyRecordUsageCache;
-        if (GetPropertyRecordUsageCache(argProperty, scriptContext, &propertyRecordUsageCache, &cacheOwner))
-        {
-            Var value;
-            propertyRecord = propertyRecordUsageCache->GetPropertyRecord();
-            if (!propertyRecord->IsNumeric())
-            {
-                PropertyValueInfo info;
-                if (propertyRecordUsageCache->TryGetPropertyFromCache<false /* OwnPropertyOnly */, true /* OutputExistence */>(instance, object, &value, scriptContext, &info, cacheOwner))
-                {
-                    Assert(JavascriptBoolean::Is(value));
-                    return value;
-                }
-                result = JavascriptOperators::GetPropertyWPCache<true /* OutputExistence */>(instance, object, propertyRecordUsageCache->GetPropertyRecord()->GetPropertyId(), &value, scriptContext, &info);
-                Assert(value == JavascriptBoolean::ToVar(result, scriptContext));
-                return value;
-            }
-
-            // We don't cache numeric property lookups, so fall through to the IndexType_Number case
-            index = propertyRecord->GetNumericValue();
-            indexType = IndexType_Number;
-        }
-        else
-        {
-            indexType = GetIndexType(argProperty, scriptContext, &index, &propertyRecord, true);
-        }
+        RecyclableObject* object = RecyclableObject::FromVar(instance);
 
+        BOOL result;
         if (indexType == Js::IndexType_Number)
         {
             result = JavascriptOperators::HasItem(object, index);
         }
         else
         {
-            result = JavascriptOperators::HasProperty(object, propertyRecord->GetPropertyId());
+            PropertyId propertyId = propertyRecord->GetPropertyId();
+            result = JavascriptOperators::HasProperty(object, propertyId);
 
 #ifdef TELEMETRY_JSO
             {
@@ -7242,7 +7175,7 @@ SetElementIHelper_INDEX_TYPE_IS_NUMBER:
         PropertyValueInfo info;
         PropertyValueInfo::SetCacheInfo(&info, functionBody, inlineCache, inlineCacheIndex, !IsFromFullJit);
         Var value;
-        if (CacheOperators::TryGetProperty<true, true, true, true, true, true, !TInlineCache::IsPolymorphic, TInlineCache::IsPolymorphic, false, false>(
+        if (CacheOperators::TryGetProperty<true, true, true, true, true, true, !TInlineCache::IsPolymorphic, TInlineCache::IsPolymorphic, false>(
                 instance, false, object, propertyId, &value, scriptContext, nullptr, &info))
         {
             return value;
@@ -7293,7 +7226,7 @@ SetElementIHelper_INDEX_TYPE_IS_NUMBER:
         PropertyValueInfo info;
         PropertyValueInfo::SetCacheInfo(&info, functionBody, inlineCache, inlineCacheIndex, !IsFromFullJit);
         Var value;
-        if (CacheOperators::TryGetProperty<true, true, true, true, true, true, !TInlineCache::IsPolymorphic, TInlineCache::IsPolymorphic, false, false>(
+        if (CacheOperators::TryGetProperty<true, true, true, true, true, true, !TInlineCache::IsPolymorphic, TInlineCache::IsPolymorphic, false>(
             instance, false, object, propertyId, &value, scriptContext, nullptr, &info))
         {
             return value;
@@ -7324,7 +7257,7 @@ SetElementIHelper_INDEX_TYPE_IS_NUMBER:
         PropertyValueInfo info;
         PropertyValueInfo::SetCacheInfo(&info, inlineCache);
         Var value;
-        if (CacheOperators::TryGetProperty<true, true, true, true, false, true, !InlineCache::IsPolymorphic, InlineCache::IsPolymorphic, false, false>(
+        if (CacheOperators::TryGetProperty<true, true, true, true, false, true, !InlineCache::IsPolymorphic, InlineCache::IsPolymorphic, false>(
                 instance, false, object, propertyId, &value, scriptContext, nullptr, &info))
         {
             return value;
@@ -7378,7 +7311,7 @@ SetElementIHelper_INDEX_TYPE_IS_NUMBER:
         PropertyValueInfo info;
         PropertyValueInfo::SetCacheInfo(&info, functionBody, inlineCache, inlineCacheIndex, !IsFromFullJit);
         Var value;
-        if (CacheOperators::TryGetProperty<true, true, true, false, true, false, !TInlineCache::IsPolymorphic, TInlineCache::IsPolymorphic, false, false>(
+        if (CacheOperators::TryGetProperty<true, true, true, false, true, false, !TInlineCache::IsPolymorphic, TInlineCache::IsPolymorphic, false>(
                 object, true, object, propertyId, &value, scriptContext, nullptr, &info))
         {
             return value;
@@ -7408,7 +7341,7 @@ SetElementIHelper_INDEX_TYPE_IS_NUMBER:
         PropertyValueInfo info;
         PropertyValueInfo::SetCacheInfo(&info, functionBody, inlineCache, inlineCacheIndex, !IsFromFullJit);
         Var value = nullptr;
-        if (CacheOperators::TryGetProperty<true, true, true, false, true, false, !TInlineCache::IsPolymorphic, TInlineCache::IsPolymorphic, false, false>(
+        if (CacheOperators::TryGetProperty<true, true, true, false, true, false, !TInlineCache::IsPolymorphic, TInlineCache::IsPolymorphic, false>(
             object, true, object, propertyId, &value, scriptContext, nullptr, &info))
         {
             return value;
@@ -7479,7 +7412,7 @@ SetElementIHelper_INDEX_TYPE_IS_NUMBER:
             RecyclableObject* object = RecyclableObject::UnsafeFromVar(pDisplay->GetItem(i));
 
             Var value;
-            if (CacheOperators::TryGetProperty<true, true, true, false, true, true, !TInlineCache::IsPolymorphic, TInlineCache::IsPolymorphic, false, false>(
+            if (CacheOperators::TryGetProperty<true, true, true, false, true, true, !TInlineCache::IsPolymorphic, TInlineCache::IsPolymorphic, false>(
                     object, false, object, propertyId, &value, scriptContext, nullptr, &info))
             {
                 return value;
@@ -7578,7 +7511,7 @@ SetElementIHelper_INDEX_TYPE_IS_NUMBER:
         PropertyValueInfo info;
         PropertyValueInfo::SetCacheInfo(&info, functionBody, inlineCache, inlineCacheIndex, !IsFromFullJit);
         Var value;
-        if (CacheOperators::TryGetProperty<true, true, true, false, true, true, !TInlineCache::IsPolymorphic, TInlineCache::IsPolymorphic, false, false>(
+        if (CacheOperators::TryGetProperty<true, true, true, false, true, true, !TInlineCache::IsPolymorphic, TInlineCache::IsPolymorphic, false>(
                 instance, false, object, propertyId, &value, scriptContext, nullptr, &info))
         {
             return value;
@@ -7618,7 +7551,7 @@ SetElementIHelper_INDEX_TYPE_IS_NUMBER:
         PropertyValueInfo info;
         PropertyValueInfo::SetCacheInfo(&info, functionBody, inlineCache, inlineCacheIndex, !IsFromFullJit);
         Var value;
-        if (CacheOperators::TryGetProperty<true, true, true, false, true, false, !TInlineCache::IsPolymorphic, TInlineCache::IsPolymorphic, false, false>(
+        if (CacheOperators::TryGetProperty<true, true, true, false, true, false, !TInlineCache::IsPolymorphic, TInlineCache::IsPolymorphic, false>(
                 object, true, object, propertyId, &value, scriptContext, nullptr, &info))
         {
             return value;
@@ -7672,7 +7605,7 @@ SetElementIHelper_INDEX_TYPE_IS_NUMBER:
         PropertyValueInfo::SetCacheInfo(&info, functionBody, inlineCache, inlineCacheIndex, !IsFromFullJit);
         const bool isRoot = RootObjectBase::Is(object);
         Var value;
-        if (CacheOperators::TryGetProperty<true, true, true, false, true, false, !TInlineCache::IsPolymorphic, TInlineCache::IsPolymorphic, false, false>(
+        if (CacheOperators::TryGetProperty<true, true, true, false, true, false, !TInlineCache::IsPolymorphic, TInlineCache::IsPolymorphic, false>(
                 instance, isRoot, object, propertyId, &value, scriptContext, nullptr, &info))
         {
             return value;

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

@@ -177,7 +177,7 @@ namespace Js
         static BOOL HasProperty(RecyclableObject* instance, PropertyId propertyId);
         static BOOL HasRootProperty(RecyclableObject* instance, PropertyId propertyId);
         static BOOL HasProxyOrPrototypeInlineCacheProperty(RecyclableObject* instance, PropertyId propertyId);
-        template<bool OutputExistence, typename PropertyKeyType>
+        template<typename PropertyKeyType>
         static BOOL GetPropertyWPCache(Var instance, RecyclableObject* propertyObject, PropertyKeyType propertyKey, Var* value, ScriptContext* requestContext, _Inout_ PropertyValueInfo * info);
         static BOOL GetPropertyUnscopable(Var instance, RecyclableObject* propertyObject, PropertyId propertyId, Var* value, ScriptContext* requestContext, PropertyValueInfo* info=NULL);
         static Var  GetProperty(RecyclableObject* instance, PropertyId propertyId, ScriptContext* requestContext, PropertyValueInfo* info = NULL);
@@ -710,12 +710,6 @@ namespace Js
         static BOOL ToPropertyDescriptorForGenericObjects(Var propertySpec, PropertyDescriptor* descriptor, ScriptContext* scriptContext);
 
         static BOOL IsRemoteArray(RecyclableObject* instance);
-
-        // Get the property record usage cache from the given index variable, if it has one.
-        // Adds a PropertyString to a LiteralStringWithPropertyStringPtr on second call with that string.
-        // Also outputs the object that owns the usage cache, since PropertyRecordUsageCache is an interior pointer.
-        // Returns whether a PropertyRecordUsageCache was found.
-        _Success_(return) static bool GetPropertyRecordUsageCache(Var index, ScriptContext* scriptContext, _Outptr_ PropertyRecordUsageCache** propertyRecordUsageCache, _Outptr_ RecyclableObject** cacheOwner);
     };
 
 } // namespace Js

+ 2 - 2
lib/Runtime/Language/ModuleNamespace.cpp

@@ -145,13 +145,13 @@ namespace Js
         unambiguousNonLocalExports->AddNew(propertyId, *nonLocalExportNameRecord);
     }
 
-    PropertyQueryFlags ModuleNamespace::HasPropertyQuery(PropertyId propertyId, _Inout_opt_ PropertyValueInfo* info)
+    PropertyQueryFlags ModuleNamespace::HasPropertyQuery(PropertyId propertyId)
     {
         SimpleDictionaryPropertyDescriptor<BigPropertyIndex> propertyDescriptor;
         const Js::PropertyRecord* propertyRecord = GetScriptContext()->GetThreadContext()->GetPropertyName(propertyId);
         if (propertyRecord->IsSymbol())
         {
-            return this->DynamicObject::HasPropertyQuery(propertyId, info);
+            return this->DynamicObject::HasPropertyQuery(propertyId);
         }
         if (propertyMap != nullptr && propertyMap->TryGetValue(propertyRecord, &propertyDescriptor))
         {

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

@@ -34,7 +34,7 @@ namespace Js
         static ModuleNamespace* FromVar(Var obj) { AssertOrFailFast(JavascriptOperators::GetTypeId(obj) == TypeIds_ModuleNamespace); return static_cast<ModuleNamespace*>(obj); }
 
         virtual PropertyId GetPropertyId(BigPropertyIndex index) override;
-        virtual PropertyQueryFlags HasPropertyQuery(PropertyId propertyId, _Inout_opt_ PropertyValueInfo* info) override;
+        virtual PropertyQueryFlags HasPropertyQuery(PropertyId propertyId) override;
         virtual BOOL HasOwnProperty(PropertyId propertyId) override;
         virtual PropertyQueryFlags GetPropertyQuery(Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;
         virtual PropertyQueryFlags GetPropertyQuery(Var originalInstance, JavascriptString* propertyNameString, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;

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

@@ -894,7 +894,7 @@ namespace Js
             PropertyCacheOperationInfo operationInfo;
             PropertyValueInfo propertyValueInfo;
             PropertyValueInfo::SetCacheInfo(&propertyValueInfo, functionBody, inlineCache, inlineCacheIndex, true);
-            if (!CacheOperators::TryGetProperty<true, true, true, !Root && !Method, true, !Root, true, false, true, false>(
+            if (!CacheOperators::TryGetProperty<true, true, true, !Root && !Method, true, !Root, true, false, true>(
                     object,
                     Root,
                     object,

+ 2 - 2
lib/Runtime/Library/ArgumentsObject.cpp

@@ -321,7 +321,7 @@ namespace Js
 
     }
 
-    PropertyQueryFlags HeapArgumentsObject::HasPropertyQuery(PropertyId id, _Inout_opt_ PropertyValueInfo* info)
+    PropertyQueryFlags HeapArgumentsObject::HasPropertyQuery(PropertyId id)
     {
         ScriptContext *scriptContext = GetScriptContext();
 
@@ -332,7 +332,7 @@ namespace Js
             return HeapArgumentsObject::HasItemQuery(index);
         }
 
-        return DynamicObject::HasPropertyQuery(id, info);
+        return DynamicObject::HasPropertyQuery(id);
     }
 
     PropertyQueryFlags HeapArgumentsObject::GetPropertyQuery(Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext)

+ 1 - 1
lib/Runtime/Library/ArgumentsObject.h

@@ -75,7 +75,7 @@ namespace Js
         virtual BOOL SetItemAt(uint32 index, Var value);
         virtual BOOL DeleteItemAt(uint32 index);
 
-        virtual PropertyQueryFlags HasPropertyQuery(PropertyId propertyId, _Inout_opt_ PropertyValueInfo* info) override;
+        virtual PropertyQueryFlags HasPropertyQuery(PropertyId propertyId) override;
         virtual PropertyQueryFlags GetPropertyQuery(Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;
         virtual PropertyQueryFlags GetPropertyQuery(Var originalInstance, JavascriptString* propertyNameString, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;
         virtual PropertyQueryFlags GetPropertyReferenceQuery(Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;

+ 2 - 2
lib/Runtime/Library/BoundFunction.cpp

@@ -269,14 +269,14 @@ namespace Js
         return false;
     }
 
-    PropertyQueryFlags BoundFunction::HasPropertyQuery(PropertyId propertyId, _Inout_opt_ PropertyValueInfo* info)
+    PropertyQueryFlags BoundFunction::HasPropertyQuery(PropertyId propertyId)
     {
         if (propertyId == PropertyIds::length)
         {
             return PropertyQueryFlags::Property_Found;
         }
 
-        return JavascriptFunction::HasPropertyQuery(propertyId, info);
+        return JavascriptFunction::HasPropertyQuery(propertyId);
     }
 
     PropertyQueryFlags BoundFunction::GetPropertyQuery(Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext)

+ 1 - 1
lib/Runtime/Library/BoundFunction.h

@@ -26,7 +26,7 @@ namespace Js
         static bool Is(Var func){ return JavascriptFunction::Is(func) && JavascriptFunction::UnsafeFromVar(func)->IsBoundFunction(); }
         static Var NewInstance(RecyclableObject* function, CallInfo callInfo, ...);
         virtual JavascriptString* GetDisplayNameImpl() const override;
-        virtual PropertyQueryFlags HasPropertyQuery(PropertyId propertyId, _Inout_opt_ PropertyValueInfo* info) override;
+        virtual PropertyQueryFlags HasPropertyQuery(PropertyId propertyId) override;
         virtual PropertyQueryFlags GetPropertyQuery(Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;
         virtual PropertyQueryFlags GetPropertyQuery(Var originalInstance, JavascriptString* propertyNameString, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;
         virtual PropertyQueryFlags GetPropertyReferenceQuery(Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;

+ 2 - 2
lib/Runtime/Library/ES5Array.cpp

@@ -40,7 +40,7 @@ namespace Js
         return GetTypeHandler()->IsLengthWritable();
     }
 
-    PropertyQueryFlags ES5Array::HasPropertyQuery(PropertyId propertyId, _Inout_opt_ PropertyValueInfo* info)
+    PropertyQueryFlags ES5Array::HasPropertyQuery(PropertyId propertyId)
     {
         if (propertyId == PropertyIds::length)
         {
@@ -48,7 +48,7 @@ namespace Js
         }
 
         // Skip JavascriptArray override
-        return DynamicObject::HasPropertyQuery(propertyId, info);
+        return DynamicObject::HasPropertyQuery(propertyId);
     }
 
     BOOL ES5Array::IsWritable(PropertyId propertyId)

+ 1 - 1
lib/Runtime/Library/ES5Array.h

@@ -55,7 +55,7 @@ namespace Js
         //
         // To skip JavascriptArray overrides
         //
-        virtual PropertyQueryFlags HasPropertyQuery(PropertyId propertyId, _Inout_opt_ PropertyValueInfo* info) override;
+        virtual PropertyQueryFlags HasPropertyQuery(PropertyId propertyId) override;
         virtual BOOL IsWritable(PropertyId propertyId) override;
         virtual BOOL SetEnumerable(PropertyId propertyId, BOOL value) override;
         virtual BOOL SetWritable(PropertyId propertyId, BOOL value) override;

+ 7 - 7
lib/Runtime/Library/GlobalObject.cpp

@@ -125,7 +125,7 @@ namespace Js
 
     BOOL GlobalObject::ReserveGlobalProperty(PropertyId propertyId)
     {
-        if (JavascriptConversion::PropertyQueryFlagsToBoolean(DynamicObject::HasPropertyQuery(propertyId, nullptr /*info*/)))
+        if (JavascriptConversion::PropertyQueryFlagsToBoolean(DynamicObject::HasPropertyQuery(propertyId)))
         {
             return false;
         }
@@ -1780,9 +1780,9 @@ LHexError:
         return FALSE;
     }
 
-    PropertyQueryFlags GlobalObject::HasPropertyQuery(PropertyId propertyId, _Inout_opt_ PropertyValueInfo* info)
+    PropertyQueryFlags GlobalObject::HasPropertyQuery(PropertyId propertyId)
     {
-        return JavascriptConversion::BooleanToPropertyQueryFlags(JavascriptConversion::PropertyQueryFlagsToBoolean(DynamicObject::HasPropertyQuery(propertyId, info)) ||
+        return JavascriptConversion::BooleanToPropertyQueryFlags(JavascriptConversion::PropertyQueryFlagsToBoolean(DynamicObject::HasPropertyQuery(propertyId)) ||
             (this->directHostObject && JavascriptOperators::HasProperty(this->directHostObject, propertyId)) ||
             (this->hostObject && JavascriptOperators::HasProperty(this->hostObject, propertyId)));
     }
@@ -1796,13 +1796,13 @@ LHexError:
 
     BOOL GlobalObject::HasOwnProperty(PropertyId propertyId)
     {
-        return JavascriptConversion::PropertyQueryFlagsToBoolean(DynamicObject::HasPropertyQuery(propertyId, nullptr /*info*/)) ||
+        return JavascriptConversion::PropertyQueryFlagsToBoolean(DynamicObject::HasPropertyQuery(propertyId)) ||
             (this->directHostObject && this->directHostObject->HasProperty(propertyId));
     }
 
     BOOL GlobalObject::HasOwnPropertyNoHostObject(PropertyId propertyId)
     {
-        return JavascriptConversion::PropertyQueryFlagsToBoolean(DynamicObject::HasPropertyQuery(propertyId, nullptr /*info*/));
+        return JavascriptConversion::PropertyQueryFlagsToBoolean(DynamicObject::HasPropertyQuery(propertyId));
     }
 
     PropertyQueryFlags GlobalObject::GetPropertyQuery(Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext)
@@ -1922,7 +1922,7 @@ LHexError:
 
     BOOL GlobalObject::SetExistingProperty(PropertyId propertyId, Var value, PropertyValueInfo* info, BOOL *setAttempted)
     {
-        BOOL hasOwnProperty = JavascriptConversion::PropertyQueryFlagsToBoolean(DynamicObject::HasPropertyQuery(propertyId, nullptr /*info*/));
+        BOOL hasOwnProperty = JavascriptConversion::PropertyQueryFlagsToBoolean(DynamicObject::HasPropertyQuery(propertyId));
         BOOL hasProperty = JavascriptOperators::HasProperty(this->GetPrototype(), propertyId);
         *setAttempted = TRUE;
 
@@ -2167,7 +2167,7 @@ LHexError:
 
     BOOL GlobalObject::DeleteProperty(PropertyId propertyId, PropertyOperationFlags flags)
     {
-        if (JavascriptConversion::PropertyQueryFlagsToBoolean(__super::HasPropertyQuery(propertyId, nullptr /*info*/)))
+        if (JavascriptConversion::PropertyQueryFlagsToBoolean(__super::HasPropertyQuery(propertyId)))
         {
             return __super::DeleteProperty(propertyId, flags);
         }

+ 1 - 1
lib/Runtime/Library/GlobalObject.h

@@ -132,7 +132,7 @@ namespace Js
         static Var VEval(JavascriptLibrary* library, FrameDisplay* environment, ModuleID moduleID, bool isStrictMode, bool isIndirect,
             Arguments& args, bool isLibraryCode, bool registerDocument, uint32 additionalGrfscr, ScriptContext* debugEvalScriptContext = nullptr);
 
-        virtual PropertyQueryFlags HasPropertyQuery(PropertyId propertyId, _Inout_opt_ PropertyValueInfo* info) override;
+        virtual PropertyQueryFlags HasPropertyQuery(PropertyId propertyId) override;
         virtual BOOL HasOwnProperty(PropertyId propertyId) override;
         virtual BOOL HasOwnPropertyNoHostObject(PropertyId propertyId) override;
         virtual BOOL UseDynamicObjectForNoHostObjectAccess() override { return TRUE; }

+ 2 - 3
lib/Runtime/Library/JSONStringifier.cpp

@@ -226,7 +226,7 @@ JSONStringifier::ReadValue(_In_ JavascriptString* key, _In_opt_ const PropertyRe
     if (propertyString != nullptr)
     {
         PropertyValueInfo::SetCacheInfo(&info, propertyString, propertyString->GetLdElemInlineCache(), false);
-        if (propertyString->TryGetPropertyFromCache<false /* ownPropertyOnly */, false /* OutputExistence */>(holder, holder, &value, this->scriptContext, &info))
+        if (propertyString->TryGetPropertyFromCache<false /* ownPropertyOnly */>(holder, holder, &value, this->scriptContext, &info))
         {
             return value;
         }
@@ -280,8 +280,7 @@ JSONStringifier::ToJSON(_In_ JavascriptString* key, _In_ RecyclableObject* value
         true,   // CheckTypePropertyCache
         false,  // IsInlineCacheAvailable
         true,   // IsPolymorphicInlineCacheAvailable
-        false,  // ReturnOperationInfo
-        false>  // OutputExistence
+        false>  // ReturnOperationInfo
         (valueObject,
             false,
             valueObject,

+ 2 - 2
lib/Runtime/Library/JavascriptArray.cpp

@@ -11973,7 +11973,7 @@ Case0:
         return DynamicObject::DeleteProperty(propertyNameString, flags);
     }
 
-    PropertyQueryFlags JavascriptArray::HasPropertyQuery(PropertyId propertyId, _Inout_opt_ PropertyValueInfo* info)
+    PropertyQueryFlags JavascriptArray::HasPropertyQuery(PropertyId propertyId)
     {
         if (propertyId == PropertyIds::length)
         {
@@ -11987,7 +11987,7 @@ Case0:
             return JavascriptConversion::BooleanToPropertyQueryFlags(this->HasItem(index));
         }
 
-        return DynamicObject::HasPropertyQuery(propertyId, info);
+        return DynamicObject::HasPropertyQuery(propertyId);
     }
 
     BOOL JavascriptArray::IsEnumerable(PropertyId propertyId)

+ 1 - 1
lib/Runtime/Library/JavascriptArray.h

@@ -333,7 +333,7 @@ namespace Js
 #if DBG
         void DoTypeMutation();
 #endif
-        virtual PropertyQueryFlags HasPropertyQuery(PropertyId propertyId, _Inout_opt_ PropertyValueInfo* info) override;
+        virtual PropertyQueryFlags HasPropertyQuery(PropertyId propertyId) override;
         virtual BOOL DeleteProperty(PropertyId propertyId, PropertyOperationFlags flags) override;
         virtual BOOL DeleteProperty(JavascriptString *propertyNameString, PropertyOperationFlags flags) override;
         virtual BOOL IsEnumerable(PropertyId propertyId) override;

+ 2 - 2
lib/Runtime/Library/JavascriptFunction.cpp

@@ -2488,7 +2488,7 @@ LABEL1:
         return isJsBuiltInCode;
     }
 
-    PropertyQueryFlags JavascriptFunction::HasPropertyQuery(PropertyId propertyId, _Inout_opt_ PropertyValueInfo* info)
+    PropertyQueryFlags JavascriptFunction::HasPropertyQuery(PropertyId propertyId)
     {
         switch (propertyId)
         {
@@ -2506,7 +2506,7 @@ LABEL1:
             }
             break;
         }
-        return DynamicObject::HasPropertyQuery(propertyId, info);
+        return DynamicObject::HasPropertyQuery(propertyId);
     }
 
     BOOL JavascriptFunction::GetAccessors(PropertyId propertyId, Var *getter, Var *setter, ScriptContext * requestContext)

+ 1 - 1
lib/Runtime/Library/JavascriptFunction.h

@@ -202,7 +202,7 @@ namespace Js
 
         virtual bool HasReadOnlyPropertiesInvisibleToTypeHandler() override { return true; }
 
-        virtual PropertyQueryFlags HasPropertyQuery(PropertyId propertyId, _Inout_opt_ PropertyValueInfo* info) override;
+        virtual PropertyQueryFlags HasPropertyQuery(PropertyId propertyId) override;
         virtual PropertyQueryFlags GetPropertyQuery(Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;
         virtual PropertyQueryFlags GetPropertyQuery(Var originalInstance, JavascriptString* propertyNameString, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;
         virtual PropertyQueryFlags GetPropertyReferenceQuery(Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;

+ 3 - 3
lib/Runtime/Library/JavascriptGeneratorFunction.cpp

@@ -256,7 +256,7 @@ namespace Js
         return scriptFunction->EnsureSourceString();
     }
 
-    PropertyQueryFlags JavascriptGeneratorFunction::HasPropertyQuery(PropertyId propertyId, _Inout_opt_ PropertyValueInfo* info)
+    PropertyQueryFlags JavascriptGeneratorFunction::HasPropertyQuery(PropertyId propertyId)
     {
         if (propertyId == PropertyIds::length)
         {
@@ -266,10 +266,10 @@ namespace Js
         if (propertyId == PropertyIds::caller || propertyId == PropertyIds::arguments)
         {
             // JavascriptFunction has special case for caller and arguments; call DynamicObject:: virtual directly to skip that.
-            return DynamicObject::HasPropertyQuery(propertyId, info);
+            return DynamicObject::HasPropertyQuery(propertyId);
         }
 
-        return JavascriptFunction::HasPropertyQuery(propertyId, info);
+        return JavascriptFunction::HasPropertyQuery(propertyId);
     }
 
     PropertyQueryFlags JavascriptGeneratorFunction::GetPropertyQuery(Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext)

+ 1 - 1
lib/Runtime/Library/JavascriptGeneratorFunction.h

@@ -57,7 +57,7 @@ namespace Js
         virtual Var GetSourceString() const;
         virtual Var EnsureSourceString();
 
-        virtual PropertyQueryFlags HasPropertyQuery(PropertyId propertyId, _Inout_opt_ PropertyValueInfo* info) override;
+        virtual PropertyQueryFlags HasPropertyQuery(PropertyId propertyId) override;
         virtual PropertyQueryFlags GetPropertyQuery(Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;
         virtual PropertyQueryFlags GetPropertyQuery(Var originalInstance, JavascriptString* propertyNameString, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;
         virtual PropertyQueryFlags GetPropertyReferenceQuery(Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;

+ 2 - 3
lib/Runtime/Library/JavascriptObject.cpp

@@ -373,8 +373,7 @@ namespace Js
             true,                                       // CheckTypePropertyCache
             !PolymorphicInlineCache::IsPolymorphic,     // IsInlineCacheAvailable
             PolymorphicInlineCache::IsPolymorphic,      // IsPolymorphicInlineCacheAvailable
-            false,                                      // ReturnOperationInfo
-            false>                                      // OutputExistence
+            false>                                      // ReturnOperationInfo
             (thisArg, false, thisArg, toStringTagId, &value, scriptContext, nullptr, &info))
         {
             return value;
@@ -1598,7 +1597,7 @@ namespace Js
             //
             // Whenever possible, our enumerator populates the cache, so we should generally get a cache hit here
             PropertyValueInfo getPropertyInfo;
-            if (propertyString == nullptr || !propertyString->TryGetPropertyFromCache<true /* OwnPropertyOnly */, false /* OutputExistence */>(from, from, &propValue, scriptContext, &getPropertyInfo))
+            if (propertyString == nullptr || !propertyString->TryGetPropertyFromCache<true /* OwnPropertyOnly */>(from, from, &propValue, scriptContext, &getPropertyInfo))
             {
                 if (!JavascriptOperators::GetOwnProperty(from, nextKey, &propValue, scriptContext, &getPropertyInfo))
                 {

+ 2 - 9
lib/Runtime/Library/JavascriptProxy.cpp

@@ -463,14 +463,8 @@ namespace Js
         return hasProperty;
     }
 
-    PropertyQueryFlags JavascriptProxy::HasPropertyQuery(PropertyId propertyId, _Inout_opt_ PropertyValueInfo* info)
+    PropertyQueryFlags JavascriptProxy::HasPropertyQuery(PropertyId propertyId)
     {
-        if (info)
-        {
-            // Prevent caching. See comment in GetPropertyQuery for more detail.
-            PropertyValueInfo::SetNoCache(info, this);
-            PropertyValueInfo::DisablePrototypeCache(info, this);
-        }
         auto fn = [&](RecyclableObject* object)->BOOL {
             return JavascriptOperators::HasProperty(object, propertyId);
         };
@@ -533,7 +527,6 @@ namespace Js
     {
         // We can't cache the property at this time. both target and handler can be changed outside of the proxy, so the inline cache needs to be
         // invalidate when target, handler, or handler prototype has changed. We don't have a way to achieve this yet.
-        // Also, Get and Has operations share a cache, so a trap on either should prevent caching on both.
         PropertyValueInfo::SetNoCache(info, this);
         PropertyValueInfo::DisablePrototypeCache(info, this); // We can't cache prototype property either
         auto fn = [&](RecyclableObject* object)-> BOOL {
@@ -560,7 +553,7 @@ namespace Js
         PropertyValueInfo::SetNoCache(info, this);
         PropertyValueInfo::DisablePrototypeCache(info, this); // We can't cache prototype property either
         auto fn = [&](RecyclableObject* object)-> BOOL {
-            return JavascriptOperators::GetPropertyWPCache<false /* OutputExistence */>(originalInstance, object, propertyNameString, value, requestContext, info);
+            return JavascriptOperators::GetPropertyWPCache(originalInstance, object, propertyNameString, value, requestContext, info);
         };
         auto getPropertyId = [&]()->PropertyId{
             const PropertyRecord* propertyRecord;

+ 1 - 1
lib/Runtime/Library/JavascriptProxy.h

@@ -73,7 +73,7 @@ namespace Js
 
         static DWORD GetOffsetOfTarget() { return offsetof(JavascriptProxy, target); }
 
-        virtual PropertyQueryFlags HasPropertyQuery(PropertyId propertyId, _Inout_opt_ PropertyValueInfo* info) override;
+        virtual PropertyQueryFlags HasPropertyQuery(PropertyId propertyId) override;
         virtual BOOL HasOwnProperty(PropertyId propertyId) override;
         virtual BOOL HasOwnPropertyNoHostObject(PropertyId propertyId) override;
         virtual BOOL HasOwnPropertyCheckNoRedecl(PropertyId propertyId) override;

+ 2 - 2
lib/Runtime/Library/JavascriptRegExpConstructor.cpp

@@ -173,7 +173,7 @@ namespace Js
         PropertyIds::index,
     };
 
-    PropertyQueryFlags JavascriptRegExpConstructor::HasPropertyQuery(PropertyId propertyId, _Inout_opt_ PropertyValueInfo* info)
+    PropertyQueryFlags JavascriptRegExpConstructor::HasPropertyQuery(PropertyId propertyId)
     {
         switch (propertyId)
         {
@@ -199,7 +199,7 @@ namespace Js
         case PropertyIds::$9:
             return PropertyQueryFlags::Property_Found;
         default:
-            return JavascriptFunction::HasPropertyQuery(propertyId, info);
+            return JavascriptFunction::HasPropertyQuery(propertyId);
         }
     }
 

+ 1 - 1
lib/Runtime/Library/JavascriptRegExpConstructor.h

@@ -24,7 +24,7 @@ namespace Js
     public:
         JavascriptRegExpConstructor(DynamicType * type);
 
-        virtual PropertyQueryFlags HasPropertyQuery(PropertyId propertyId, _Inout_opt_ PropertyValueInfo* info) override;
+        virtual PropertyQueryFlags HasPropertyQuery(PropertyId propertyId) override;
         virtual PropertyQueryFlags GetPropertyQuery(Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;
         virtual PropertyQueryFlags GetPropertyQuery(Var originalInstance, JavascriptString* propertyNameString, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;
         virtual PropertyQueryFlags GetPropertyReferenceQuery(Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;

+ 3 - 3
lib/Runtime/Library/JavascriptRegularExpression.cpp

@@ -1098,12 +1098,12 @@ namespace Js
         PropertyIds::sticky
     };
 
-    PropertyQueryFlags JavascriptRegExp::HasPropertyQuery(PropertyId propertyId, _Inout_opt_ PropertyValueInfo* info)
+    PropertyQueryFlags JavascriptRegExp::HasPropertyQuery(PropertyId propertyId)
     {
         const ScriptConfiguration* scriptConfig = this->GetScriptContext()->GetConfig();
 
 #define HAS_PROPERTY(ownProperty) \
-        return (ownProperty ? PropertyQueryFlags::Property_Found : DynamicObject::HasPropertyQuery(propertyId, info));
+        return (ownProperty ? PropertyQueryFlags::Property_Found : DynamicObject::HasPropertyQuery(propertyId));
 
         switch (propertyId)
         {
@@ -1120,7 +1120,7 @@ namespace Js
         case PropertyIds::sticky:
             HAS_PROPERTY(scriptConfig->IsES6RegExStickyEnabled() && !scriptConfig->IsES6RegExPrototypePropertiesEnabled())
         default:
-            return DynamicObject::HasPropertyQuery(propertyId, info);
+            return DynamicObject::HasPropertyQuery(propertyId);
         }
 
 #undef HAS_PROPERTY

+ 1 - 1
lib/Runtime/Library/JavascriptRegularExpression.h

@@ -181,7 +181,7 @@ namespace Js
 
         virtual bool HasReadOnlyPropertiesInvisibleToTypeHandler() override { return true; }
 
-        virtual PropertyQueryFlags HasPropertyQuery(PropertyId propertyId, _Inout_opt_ PropertyValueInfo* info) override;
+        virtual PropertyQueryFlags HasPropertyQuery(PropertyId propertyId) override;
         virtual PropertyQueryFlags GetPropertyQuery(Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;
         virtual PropertyQueryFlags GetPropertyQuery(Var originalInstance, JavascriptString* propertyNameString, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;
         virtual PropertyQueryFlags GetPropertyReferenceQuery(Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;

+ 1 - 1
lib/Runtime/Library/JavascriptString.cpp

@@ -3637,7 +3637,7 @@ case_2:
         return concatString;
     }
 
-    PropertyQueryFlags JavascriptString::HasPropertyQuery(PropertyId propertyId, _Inout_opt_ PropertyValueInfo* info)
+    PropertyQueryFlags JavascriptString::HasPropertyQuery(PropertyId propertyId)
     {
         if (propertyId == PropertyIds::length)
         {

+ 1 - 1
lib/Runtime/Library/JavascriptString.h

@@ -106,7 +106,7 @@ namespace Js
         virtual PropertyQueryFlags GetItemQuery(Var originalInstance, uint32 index, Var* value, ScriptContext * requestContext) override;
         virtual PropertyQueryFlags GetItemReferenceQuery(Var originalInstance, uint32 index, Var* value, ScriptContext * requestContext) override;
         virtual BOOL GetEnumerator(JavascriptStaticEnumerator * enumerator, EnumeratorFlags flags, ScriptContext* requestContext, EnumeratorCache * enumeratorCache = nullptr) override;
-        virtual PropertyQueryFlags HasPropertyQuery(PropertyId propertyId, _Inout_opt_ PropertyValueInfo* info) override;
+        virtual PropertyQueryFlags HasPropertyQuery(PropertyId propertyId) override;
         virtual BOOL IsEnumerable(PropertyId propertyId) override;
         virtual BOOL DeleteProperty(PropertyId propertyId, PropertyOperationFlags propertyOperationFlags) override;
         virtual BOOL DeleteProperty(JavascriptString *propertyNameString, PropertyOperationFlags propertyOperationFlags) override;

+ 4 - 4
lib/Runtime/Library/JavascriptStringObject.cpp

@@ -94,14 +94,14 @@ namespace Js
         return !conditionMetBehavior;
     }
 
-    PropertyQueryFlags JavascriptStringObject::HasPropertyQuery(PropertyId propertyId, _Inout_opt_ PropertyValueInfo* info)
+    PropertyQueryFlags JavascriptStringObject::HasPropertyQuery(PropertyId propertyId)
     {
         if (propertyId == PropertyIds::length)
         {
             return PropertyQueryFlags::Property_Found;
         }
 
-        if (JavascriptConversion::PropertyQueryFlagsToBoolean(DynamicObject::HasPropertyQuery(propertyId, info)))
+        if (JavascriptConversion::PropertyQueryFlagsToBoolean(DynamicObject::HasPropertyQuery(propertyId)))
         {
             return PropertyQueryFlags::Property_Found;
         }
@@ -171,7 +171,7 @@ namespace Js
 
         // From DynamicObject::IsConfigurable we can't tell if the result is from a property or just default
         // value. Call HasProperty to find out.
-        if (JavascriptConversion::PropertyQueryFlagsToBoolean(DynamicObject::HasPropertyQuery(propertyId, nullptr /*info*/)))
+        if (JavascriptConversion::PropertyQueryFlagsToBoolean(DynamicObject::HasPropertyQuery(propertyId)))
         {
             return DynamicObject::IsConfigurable(propertyId);
         }
@@ -199,7 +199,7 @@ namespace Js
 
         // From DynamicObject::IsWritable we can't tell if the result is from a property or just default
         // value. Call HasProperty to find out.
-        if (JavascriptConversion::PropertyQueryFlagsToBoolean(DynamicObject::HasPropertyQuery(propertyId, nullptr /*info*/)))
+        if (JavascriptConversion::PropertyQueryFlagsToBoolean(DynamicObject::HasPropertyQuery(propertyId)))
         {
             return DynamicObject::IsWritable(propertyId);
         }

+ 1 - 1
lib/Runtime/Library/JavascriptStringObject.h

@@ -37,7 +37,7 @@ namespace Js
         virtual bool HasReadOnlyPropertiesInvisibleToTypeHandler() override { return true; }
 
         virtual DescriptorFlags GetItemSetter(uint32 index, Var* setterValue, ScriptContext* requestContext) override;
-        virtual PropertyQueryFlags HasPropertyQuery(PropertyId propertyId, _Inout_opt_ PropertyValueInfo* info) override;
+        virtual PropertyQueryFlags HasPropertyQuery(PropertyId propertyId) override;
         virtual BOOL IsConfigurable(PropertyId propertyId) override;
         virtual BOOL IsEnumerable(PropertyId propertyId) override;
         virtual BOOL IsWritable(PropertyId propertyId) override;

+ 1 - 1
lib/Runtime/Library/JavascriptVariantDate.h

@@ -35,7 +35,7 @@ namespace Js
         double GetValue() { return value; }
 
         virtual BOOL Equals(Var other, BOOL* value, ScriptContext * requestContext) override;
-        virtual PropertyQueryFlags HasPropertyQuery(Js::PropertyId propertyId, _Inout_opt_ PropertyValueInfo* info) override { return PropertyQueryFlags::Property_NotFound; };
+        virtual PropertyQueryFlags HasPropertyQuery(Js::PropertyId propertyId) override { return PropertyQueryFlags::Property_NotFound; };
         virtual PropertyQueryFlags GetPropertyQuery(Js::Var originalInstance, Js::PropertyId propertyId, Js::Var* value, Js::PropertyValueInfo* info, Js::ScriptContext* requestContext) override;
         virtual PropertyQueryFlags GetPropertyQuery(Var originalInstance, JavascriptString* propertyNameString, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;
         virtual PropertyQueryFlags GetPropertyReferenceQuery(Js::Var originalInstance, Js::PropertyId propertyId, Js::Var* value, Js::PropertyValueInfo* info, Js::ScriptContext* requestContext) override;

+ 4 - 4
lib/Runtime/Library/ModuleRoot.cpp

@@ -17,9 +17,9 @@ namespace Js
         __super::SetHostObject(hostObject);
     }
 
-    PropertyQueryFlags ModuleRoot::HasPropertyQuery(PropertyId propertyId, _Inout_opt_ PropertyValueInfo* info)
+    PropertyQueryFlags ModuleRoot::HasPropertyQuery(PropertyId propertyId)
     {
-        if (JavascriptConversion::PropertyQueryFlagsToBoolean(DynamicObject::HasPropertyQuery(propertyId, info)))
+        if (JavascriptConversion::PropertyQueryFlagsToBoolean(DynamicObject::HasPropertyQuery(propertyId)))
         {
             return PropertyQueryFlags::Property_Found;
         }
@@ -27,7 +27,7 @@ namespace Js
         {
             return PropertyQueryFlags::Property_Found;
         }
-        return this->GetLibrary()->GetGlobalObject()->GlobalObject::HasPropertyQuery(propertyId, info);
+        return this->GetLibrary()->GetGlobalObject()->GlobalObject::HasPropertyQuery(propertyId);
     }
 
     BOOL ModuleRoot::EnsureProperty(PropertyId propertyId)
@@ -56,7 +56,7 @@ namespace Js
 
     BOOL ModuleRoot::HasOwnProperty(PropertyId propertyId)
     {
-        return JavascriptConversion::PropertyQueryFlagsToBoolean(DynamicObject::HasPropertyQuery(propertyId, nullptr /*info*/));
+        return JavascriptConversion::PropertyQueryFlagsToBoolean(DynamicObject::HasPropertyQuery(propertyId));
     }
 
     PropertyQueryFlags ModuleRoot::GetPropertyQuery(Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext)

+ 1 - 1
lib/Runtime/Library/ModuleRoot.h

@@ -21,7 +21,7 @@ namespace Js
 
         virtual BOOL InitPropertyScoped(PropertyId propertyId, Var value) override;
         virtual BOOL InitFuncScoped(PropertyId propertyId, Var value) override;
-        virtual PropertyQueryFlags HasPropertyQuery(PropertyId propertyId, _Inout_opt_ PropertyValueInfo* info) override;
+        virtual PropertyQueryFlags HasPropertyQuery(PropertyId propertyId) override;
         virtual BOOL HasOwnProperty(PropertyId propertyId) override;
         virtual BOOL UseDynamicObjectForNoHostObjectAccess() override { return TRUE; }
         virtual PropertyQueryFlags GetPropertyQuery(Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;

+ 65 - 59
lib/Runtime/Library/PropertyRecordUsageCache.h

@@ -43,70 +43,14 @@ namespace Js
             RecyclableObject *const owner /* Object that this usage cache is part of */);
 
 
-        template <
-            bool OwnPropertyOnly,
-            bool OutputExistence /*When set, propertyValue represents whether the property exists on the instance, not its actual value*/>
-        inline bool TryGetPropertyFromCache(
+        template <bool OwnPropertyOnly>
+        bool TryGetPropertyFromCache(
             Var const instance,
             RecyclableObject *const object,
             Var *const propertyValue,
             ScriptContext *const requestContext,
             PropertyValueInfo *const propertyValueInfo,
-            RecyclableObject *const owner /* Object that this usage cache is part of */)
-        {
-            if (ShouldUseCache())
-            {
-                PropertyValueInfo::SetCacheInfo(propertyValueInfo, owner, this, GetLdElemInlineCache(), true /* allowResizing */);
-
-                // Some caches will look at prototype, so GetOwnProperty lookups must not check these
-                bool found = CacheOperators::TryGetProperty<
-                    true,               // CheckLocal
-                    !OwnPropertyOnly,   // CheckProto
-                    !OwnPropertyOnly,   // CheckAccessor
-                    !OwnPropertyOnly,   // CheckMissing
-                    true,               // CheckPolymorphicInlineCache
-                    !OwnPropertyOnly,   // CheckTypePropertyCache
-                    false,              // IsInlineCacheAvailable
-                    true,               // IsPolymorphicInlineCacheAvailable
-                    false,              // ReturnOperationInfo
-                    OutputExistence>    // OutputExistence
-                        (instance,
-                        false, // isRoot
-                        object,
-                        this->propertyRecord->GetPropertyId(),
-                        propertyValue,
-                        requestContext,
-                        nullptr, // operationInfo
-                        propertyValueInfo);
-
-                if (found)
-                {
-                    RegisterCacheHit();
-#ifdef ENABLE_DEBUG_CONFIG_OPTIONS
-                    if (PHASE_TRACE1(PropertyCachePhase))
-                    {
-                        Output::Print(_u("PropertyCache: GetElem cache hit for '%s': type %p\n"),
-                            GetString(),
-                            object->GetType());
-                    }
-#endif
-                    return true;
-                }
-            }
-
-            RegisterCacheMiss();
-#ifdef ENABLE_DEBUG_CONFIG_OPTIONS
-            if (PHASE_TRACE1(PropertyCachePhase))
-            {
-                Output::Print(_u("PropertyCache: GetElem cache miss for '%s': type %p, index %d\n"),
-                    GetString(),
-                    object->GetType(),
-                    GetLdElemInlineCache()->GetInlineCacheIndexForType(object->GetType()));
-                DumpCache(true);
-            }
-#endif
-            return false;
-        }
+            RecyclableObject *const owner /* Object that this usage cache is part of */);
 
 #if ENABLE_DEBUG_CONFIG_OPTIONS
 
@@ -128,4 +72,66 @@ namespace Js
         }
 #endif
     };
+
+    template <bool OwnPropertyOnly> inline
+    bool PropertyRecordUsageCache::TryGetPropertyFromCache(
+        Var const instance,
+        RecyclableObject *const object,
+        Var *const propertyValue,
+        ScriptContext *const requestContext,
+        PropertyValueInfo *const propertyValueInfo,
+        RecyclableObject *const owner /* Object that this usage cache is part of */)
+    {
+        if (ShouldUseCache())
+        {
+            PropertyValueInfo::SetCacheInfo(propertyValueInfo, owner, this, GetLdElemInlineCache(), true /* allowResizing */);
+
+            // Some caches will look at prototype, so GetOwnProperty lookups must not check these
+            bool found = CacheOperators::TryGetProperty<
+                true,               // CheckLocal
+                !OwnPropertyOnly,   // CheckProto
+                !OwnPropertyOnly,   // CheckAccessor
+                !OwnPropertyOnly,   // CheckMissing
+                true,               // CheckPolymorphicInlineCache
+                !OwnPropertyOnly,   // CheckTypePropertyCache
+                false,              // IsInlineCacheAvailable
+                true,               // IsPolymorphicInlineCacheAvailable
+                false>              // ReturnOperationInfo
+                    (instance,
+                    false, // isRoot
+                    object,
+                    this->propertyRecord->GetPropertyId(),
+                    propertyValue,
+                    requestContext,
+                    nullptr, // operationInfo
+                    propertyValueInfo);
+
+            if (found)
+            {
+                RegisterCacheHit();
+#ifdef ENABLE_DEBUG_CONFIG_OPTIONS
+                if (PHASE_TRACE1(PropertyCachePhase))
+                {
+                    Output::Print(_u("PropertyCache: GetElem cache hit for '%s': type %p\n"),
+                        GetString(),
+                        object->GetType());
+                }
+#endif
+                return true;
+            }
+        }
+
+        RegisterCacheMiss();
+#ifdef ENABLE_DEBUG_CONFIG_OPTIONS
+        if (PHASE_TRACE1(PropertyCachePhase))
+        {
+            Output::Print(_u("PropertyCache: GetElem cache miss for '%s': type %p, index %d\n"),
+                GetString(),
+                object->GetType(),
+                GetLdElemInlineCache()->GetInlineCacheIndexForType(object->GetType()));
+            DumpCache(true);
+        }
+#endif
+        return false;
+    }
 }

+ 14 - 8
lib/Runtime/Library/PropertyString.h

@@ -37,18 +37,13 @@ public:
         _Inout_ PropertyValueInfo *const propertyValueInfo);
 
 
-    template <
-        bool OwnPropertyOnly,
-        bool OutputExistence /*When set, propertyValue represents whether the property exists on the instance, not its actual value*/>
-    inline bool TryGetPropertyFromCache(
+    template <bool OwnPropertyOnly>
+    bool TryGetPropertyFromCache(
         Var const instance,
         RecyclableObject *const object,
         Var *const propertyValue,
         ScriptContext *const requestContext,
-        PropertyValueInfo *const propertyValueInfo)
-    {
-        return this->propertyRecordUsageCache.TryGetPropertyFromCache<OwnPropertyOnly, OutputExistence>(instance, object, propertyValue, requestContext, propertyValueInfo, this);
-    }
+        PropertyValueInfo *const propertyValueInfo);
 
     static PropertyString* New(StaticType* type, const Js::PropertyRecord* propertyRecord, Recycler *recycler);
 
@@ -87,4 +82,15 @@ PropertyString * PropertyString::TryFromVar(T var)
         : nullptr;
 }
 
+template <bool OwnPropertyOnly> inline
+bool PropertyString::TryGetPropertyFromCache(
+    Var const instance,
+    RecyclableObject *const object,
+    Var *const propertyValue,
+    ScriptContext *const requestContext,
+    PropertyValueInfo *const propertyValueInfo)
+{
+    return this->propertyRecordUsageCache.TryGetPropertyFromCache<OwnPropertyOnly>(instance, object, propertyValue, requestContext, propertyValueInfo, this);
+}
+
 } // namespace Js

+ 3 - 3
lib/Runtime/Library/TypedArray.cpp

@@ -740,7 +740,7 @@ namespace Js
 
     BOOL TypedArrayBase::HasOwnProperty(PropertyId propertyId)
     {
-        return JavascriptConversion::PropertyQueryFlagsToBoolean(HasPropertyQuery(propertyId, nullptr /*info*/));
+        return JavascriptConversion::PropertyQueryFlagsToBoolean(HasPropertyQuery(propertyId));
     }
 
     inline BOOL TypedArrayBase::CanonicalNumericIndexString(PropertyId propertyId, ScriptContext *scriptContext)
@@ -755,7 +755,7 @@ namespace Js
         return JavascriptConversion::CanonicalNumericIndexString(propertyString, &result, scriptContext);
     }
 
-    PropertyQueryFlags TypedArrayBase::HasPropertyQuery(PropertyId propertyId, _Inout_opt_ PropertyValueInfo* info)
+    PropertyQueryFlags TypedArrayBase::HasPropertyQuery(PropertyId propertyId)
     {
         uint32 index = 0;
         ScriptContext *scriptContext = GetScriptContext();
@@ -770,7 +770,7 @@ namespace Js
             return PropertyQueryFlags::Property_NotFound_NoProto;
         }
 
-        return DynamicObject::HasPropertyQuery(propertyId, info);
+        return DynamicObject::HasPropertyQuery(propertyId);
     }
 
     BOOL TypedArrayBase::DeleteProperty(PropertyId propertyId, PropertyOperationFlags flags)

+ 1 - 1
lib/Runtime/Library/TypedArray.h

@@ -102,7 +102,7 @@ namespace Js
         virtual DescriptorFlags GetSetter(PropertyId propertyId, Var *setterValue, PropertyValueInfo* info, ScriptContext* requestContext) override;
         virtual DescriptorFlags GetSetter(JavascriptString* propertyNameString, Var *setterValue, PropertyValueInfo* info, ScriptContext* requestContext) override;
         virtual DescriptorFlags GetItemSetter(uint32 index, Var* setterValue, ScriptContext* requestContext) override;
-        virtual PropertyQueryFlags HasPropertyQuery(Js::PropertyId propertyId, _Inout_opt_ PropertyValueInfo* info) override;
+        virtual PropertyQueryFlags HasPropertyQuery(Js::PropertyId propertyId) override;
         virtual BOOL HasOwnProperty(Js::PropertyId propertyId) override;
         virtual PropertyQueryFlags GetPropertyQuery(Js::Var originalInstance, Js::PropertyId propertyId, Js::Var* value, Js::PropertyValueInfo* info, Js::ScriptContext* requestContext) override;
         virtual PropertyQueryFlags GetPropertyQuery(Js::Var originalInstance, Js::JavascriptString* propertyNameString, Js::Var* value, Js::PropertyValueInfo* info, Js::ScriptContext* requestContext) override;

+ 3 - 3
lib/Runtime/Types/DeferredTypeHandler.h

@@ -93,7 +93,7 @@ namespace Js
         virtual bool IsObjTypeSpecEquivalent(const Type* type, const EquivalentPropertyEntry* entry) override;
 #endif
         virtual bool EnsureObjectReady(DynamicObject* instance) override;
-        virtual BOOL HasProperty(DynamicObject* instance, PropertyId propertyId, __out_opt bool *noRedecl = nullptr, _Inout_opt_ PropertyValueInfo* info = nullptr) override;
+        virtual BOOL HasProperty(DynamicObject* instance, PropertyId propertyId, __out_opt bool *noRedecl = nullptr) override;
         virtual BOOL HasProperty(DynamicObject* instance, JavascriptString* propertyNameString) override;
         virtual BOOL GetProperty(DynamicObject* instance, Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;
         virtual BOOL GetProperty(DynamicObject* instance, Var originalInstance, JavascriptString* propertyNameString, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;
@@ -247,7 +247,7 @@ namespace Js
     }
 
     template <DeferredTypeInitializer initializer, typename DeferredTypeFilter, bool isPrototypeTemplate, uint16 _inlineSlotCapacity, uint16 _offsetOfInlineSlots>
-    BOOL DeferredTypeHandler<initializer, DeferredTypeFilter, isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots>::HasProperty(DynamicObject* instance, PropertyId propertyId, __out_opt bool *noRedecl, _Inout_opt_ PropertyValueInfo* info)
+    BOOL DeferredTypeHandler<initializer, DeferredTypeFilter, isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots>::HasProperty(DynamicObject* instance, PropertyId propertyId, __out_opt bool *noRedecl)
     {
         if (noRedecl != nullptr)
         {
@@ -264,7 +264,7 @@ namespace Js
             return TRUE;
         }
 
-        return GetCurrentTypeHandler(instance)->HasProperty(instance, propertyId, noRedecl, info);
+        return GetCurrentTypeHandler(instance)->HasProperty(instance, propertyId, noRedecl);
     }
 
     template <DeferredTypeInitializer initializer, typename DeferredTypeFilter, bool isPrototypeTemplate, uint16 _inlineSlotCapacity, uint16 _offsetOfInlineSlots>

+ 33 - 46
lib/Runtime/Types/DictionaryTypeHandler.cpp

@@ -136,7 +136,16 @@ namespace Js
                 if (dataSlot != NoSlots && (attribs & PropertyWritable))
                 {
                     PropertyValueInfo::SetCacheInfo(info, propertyString, propertyString->GetLdElemInlineCache(), false);
-                    SetPropertyValueInfo(info, instance, dataSlot, &descriptor);
+                    SetPropertyValueInfo(info, instance, dataSlot, descriptor.Attributes);
+                    if (descriptor.IsOrMayBecomeFixed())
+                    {
+                        PropertyValueInfo::DisableStoreFieldCache(info);
+                    }
+                    if (descriptor.Attributes & PropertyDeleted)
+                    {
+                        // letconst shadowing a deleted property. don't bother to cache
+                        PropertyValueInfo::SetNoCache(info, instance);
+                    }
                 }
                 else
                 {
@@ -398,20 +407,20 @@ namespace Js
     }
 
     template <typename T>
-    BOOL DictionaryTypeHandlerBase<T>::HasProperty(DynamicObject* instance, PropertyId propertyId, bool *noRedecl, _Inout_opt_ PropertyValueInfo* info)
+    BOOL DictionaryTypeHandlerBase<T>::HasProperty(DynamicObject* instance, PropertyId propertyId, bool *noRedecl)
     {
-        return HasProperty_Internal<false>(instance, propertyId, noRedecl, info, nullptr, nullptr);
+        return HasProperty_Internal<false>(instance, propertyId, noRedecl, nullptr, nullptr);
     }
 
     template <typename T>
     BOOL DictionaryTypeHandlerBase<T>::HasRootProperty(DynamicObject* instance, PropertyId propertyId, bool *noRedecl, bool *pDeclaredProperty, bool *pNonconfigurableProperty)
     {
-        return HasProperty_Internal<true>(instance, propertyId, noRedecl, nullptr /*info*/, pDeclaredProperty, pNonconfigurableProperty);
+        return HasProperty_Internal<true>(instance, propertyId, noRedecl, pDeclaredProperty, pNonconfigurableProperty);
     }
 
     template <typename T>
     template <bool allowLetConstGlobal>
-    BOOL DictionaryTypeHandlerBase<T>::HasProperty_Internal(DynamicObject* instance, PropertyId propertyId, bool *noRedecl, _Inout_opt_ PropertyValueInfo* info, bool *pDeclaredProperty, bool *pNonconfigurableProperty)
+    BOOL DictionaryTypeHandlerBase<T>::HasProperty_Internal(DynamicObject* instance, PropertyId propertyId, bool *noRedecl, bool *pDeclaredProperty, bool *pNonconfigurableProperty)
     {
         // HasProperty is called with NoProperty in JavascriptDispatch.cpp to for undeferral of the
         // deferred type system that DOM objects use.  Allow NoProperty for this reason, but only
@@ -442,23 +451,6 @@ namespace Js
             {
                 *pNonconfigurableProperty = true;
             }
-            if (info)
-            {
-                T dataSlot = descriptor->template GetDataPropertyIndex<allowLetConstGlobal>();
-                if (dataSlot != NoSlots)
-                {
-                    SetPropertyValueInfo(info, instance, dataSlot, descriptor);
-                }
-                else if (descriptor->GetGetterPropertyIndex() != NoSlots)
-                {
-                    // PropertyAttributes is only one byte so it can't carry out data about whether this is an accessor.
-                    // Accessors must be cached differently than normal properties, so if we want to cache this we must
-                    // do so here rather than in the caller. However, caching here would require passing originalInstance and 
-                    // requestContext through a wide variety of call paths to this point (like we do for GetProperty), for
-                    // very little improvement. For now, just block caching this case.
-                    PropertyValueInfo::SetNoCache(info, instance);
-                }
-            }
             return true;
         }
 
@@ -534,12 +526,21 @@ namespace Js
         if (dataSlot != NoSlots)
         {
             *value = instance->GetSlot(dataSlot);
-            SetPropertyValueInfo(info, instance, dataSlot, descriptor);
+            SetPropertyValueInfo(info, instance, dataSlot, descriptor->Attributes);
+            if (descriptor->IsOrMayBecomeFixed())
+            {
+                PropertyValueInfo::DisableStoreFieldCache(info);
+            }
+            if (descriptor->Attributes & PropertyDeleted)
+            {
+                // letconst shadowing a deleted property. don't bother to cache
+                PropertyValueInfo::SetNoCache(info, instance);
+            }
         }
         else if (descriptor->GetGetterPropertyIndex() != NoSlots)
         {
             // We must update cache before calling a getter, because it can invalidate something. Bug# 593815
-            SetPropertyValueInfoNonFixed(info, instance, descriptor->GetGetterPropertyIndex(), descriptor->Attributes);
+            SetPropertyValueInfo(info, instance, descriptor->GetGetterPropertyIndex(), descriptor->Attributes);
             CacheOperators::CachePropertyReadForGetter(info, originalInstance, propertyT, requestContext);
             PropertyValueInfo::SetNoCache(info, instance); // we already cached getter, so we don't have to do it once more
 
@@ -597,28 +598,14 @@ namespace Js
     }
 
     template <typename T>
-    void DictionaryTypeHandlerBase<T>::SetPropertyValueInfo(PropertyValueInfo* info, RecyclableObject* instance, T propIndex, DictionaryPropertyDescriptor<T>* descriptor)
-    {
-        SetPropertyValueInfoNonFixed(info, instance, propIndex, descriptor->Attributes);
-        if (descriptor->IsOrMayBecomeFixed())
-        {
-            PropertyValueInfo::DisableStoreFieldCache(info);
-        }
-        if (descriptor->Attributes & PropertyDeleted)
-        {
-            // letconst shadowing a deleted property. don't bother to cache
-            PropertyValueInfo::SetNoCache(info, instance);
-        }
-    }
-
-    template <typename T>
-    void DictionaryTypeHandlerBase<T>::SetPropertyValueInfoNonFixed(PropertyValueInfo* info, RecyclableObject* instance, T propIndex, PropertyAttributes attributes, InlineCacheFlags flags)
+    void DictionaryTypeHandlerBase<T>::SetPropertyValueInfo(PropertyValueInfo* info, RecyclableObject* instance, T propIndex, PropertyAttributes attributes, InlineCacheFlags flags)
     {
         PropertyValueInfo::Set(info, instance, propIndex, attributes, flags);
     }
 
+
     template <>
-    void DictionaryTypeHandlerBase<BigPropertyIndex>::SetPropertyValueInfoNonFixed(PropertyValueInfo* info, RecyclableObject* instance, BigPropertyIndex propIndex, PropertyAttributes attributes, InlineCacheFlags flags)
+    void DictionaryTypeHandlerBase<BigPropertyIndex>::SetPropertyValueInfo(PropertyValueInfo* info, RecyclableObject* instance, BigPropertyIndex propIndex, PropertyAttributes attributes, InlineCacheFlags flags)
     {
         PropertyValueInfo::SetNoCache(info, instance);
     }
@@ -686,7 +673,7 @@ namespace Js
         else if (descriptor->GetSetterPropertyIndex() != NoSlots)
         {
             *setterValue=((DynamicObject*)instance)->GetSlot(descriptor->GetSetterPropertyIndex());
-            SetPropertyValueInfoNonFixed(info, instance, descriptor->GetSetterPropertyIndex(), descriptor->Attributes, InlineCacheSetterFlag);
+            SetPropertyValueInfo(info, instance, descriptor->GetSetterPropertyIndex(), descriptor->Attributes, InlineCacheSetterFlag);
             return Accessor;
         }
         return None;
@@ -783,7 +770,7 @@ namespace Js
             // when overwriting this property and correctly invalidate any JIT-ed code that hard-coded this method.
             if (!descriptor->IsOrMayBecomeFixed())
             {
-                SetPropertyValueInfoNonFixed(info, instance, dataSlotAllowLetConstGlobal, GetLetConstGlobalPropertyAttributes<allowLetConstGlobal>(descriptor->Attributes));
+                SetPropertyValueInfo(info, instance, dataSlotAllowLetConstGlobal, GetLetConstGlobalPropertyAttributes<allowLetConstGlobal>(descriptor->Attributes));
             }
             else
             {
@@ -800,11 +787,11 @@ namespace Js
             T dataSlot = descriptor->template GetDataPropertyIndex<false>();
             if (dataSlot != NoSlots)
             {
-                SetPropertyValueInfoNonFixed(info, instance, dataSlot, descriptor->Attributes);
+                SetPropertyValueInfo(info, instance, dataSlot, descriptor->Attributes);
             }
             else if (descriptor->GetSetterPropertyIndex() != NoSlots)
             {
-                SetPropertyValueInfoNonFixed(info, instance, descriptor->GetSetterPropertyIndex(), descriptor->Attributes, InlineCacheSetterFlag);
+                SetPropertyValueInfo(info, instance, descriptor->GetSetterPropertyIndex(), descriptor->Attributes, InlineCacheSetterFlag);
             }
         }
         SetPropertyUpdateSideEffect(instance, propertyId, value, SideEffects_Any);
@@ -2205,7 +2192,7 @@ namespace Js
         else
 #endif
         {
-            SetPropertyValueInfoNonFixed(info, instance, index, attributes);
+            SetPropertyValueInfo(info, instance, index, attributes);
         }
 
         // Always invalidate prototype caches when we add a property.  Previously, we only did this if the current

+ 3 - 4
lib/Runtime/Types/DictionaryTypeHandler.h

@@ -85,7 +85,7 @@ namespace Js
         virtual bool IsObjTypeSpecEquivalent(const Type* type, const EquivalentPropertyEntry* entry) override;
 #endif
 
-        virtual BOOL HasProperty(DynamicObject* instance, PropertyId propertyId, bool *noRedecl = nullptr, _Inout_opt_ PropertyValueInfo* info = nullptr) override;
+        virtual BOOL HasProperty(DynamicObject* instance, PropertyId propertyId, bool *noRedecl = nullptr) override;
         virtual BOOL HasProperty(DynamicObject* instance, JavascriptString* propertyNameString) override;
         virtual BOOL GetProperty(DynamicObject* instance, Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;
         virtual BOOL GetProperty(DynamicObject* instance, Var originalInstance, JavascriptString* propertyNameString, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;
@@ -225,11 +225,10 @@ namespace Js
 
         BigDictionaryTypeHandler* ConvertToBigDictionaryTypeHandler(DynamicObject* instance);
 
-        void SetPropertyValueInfo(PropertyValueInfo* info, RecyclableObject* instance, T propIndex, DictionaryPropertyDescriptor<T>* descriptor);
-        void SetPropertyValueInfoNonFixed(PropertyValueInfo* info, RecyclableObject* instance, T propIndex, PropertyAttributes attributes, InlineCacheFlags flags = InlineCacheNoFlags);
+        void SetPropertyValueInfo(PropertyValueInfo* info, RecyclableObject* instance, T propIndex, PropertyAttributes attributes, InlineCacheFlags flags = InlineCacheNoFlags);
 
         template<bool allowLetConstGlobal>
-        inline BOOL HasProperty_Internal(DynamicObject* instance, PropertyId propertyId, bool *noRedecl, _Inout_opt_ PropertyValueInfo* info, bool *pDeclaredProperty, bool *pNonconfigurableProperty);
+        inline BOOL HasProperty_Internal(DynamicObject* instance, PropertyId propertyId, bool *noRedecl, bool *pDeclaredProperty, bool *pNonconfigurableProperty);
         template<bool allowLetConstGlobal>
         inline PropertyIndex GetPropertyIndex_Internal(PropertyRecord const* propertyRecord);
         template<bool allowLetConstGlobal>

+ 1 - 1
lib/Runtime/Types/DynamicObject.h

@@ -227,7 +227,7 @@ namespace Js
         virtual PropertyId GetPropertyId(PropertyIndex index) override;
         virtual PropertyId GetPropertyId(BigPropertyIndex index) override;
         PropertyIndex GetPropertyIndex(PropertyId propertyId) sealed;
-        virtual PropertyQueryFlags HasPropertyQuery(PropertyId propertyId, _Inout_opt_ PropertyValueInfo* info) override;
+        virtual PropertyQueryFlags HasPropertyQuery(PropertyId propertyId) override;
         virtual BOOL HasOwnProperty(PropertyId propertyId) override;
         virtual PropertyQueryFlags GetPropertyQuery(Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;
         virtual PropertyQueryFlags GetPropertyQuery(Var originalInstance, JavascriptString* propertyNameString, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;

+ 2 - 2
lib/Runtime/Types/DynamicType.cpp

@@ -243,12 +243,12 @@ namespace Js
         return GetTypeHandler()->GetPropertyIndex(this->GetScriptContext()->GetPropertyName(propertyId));
     }
 
-    PropertyQueryFlags DynamicObject::HasPropertyQuery(PropertyId propertyId, _Inout_opt_ PropertyValueInfo* info)
+    PropertyQueryFlags DynamicObject::HasPropertyQuery(PropertyId propertyId)
     {
         // HasProperty can be invoked with propertyId = NoProperty in some cases, namely cross-thread and DOM
         // This is done to force creation of a type handler in case the type handler is deferred
         Assert(!Js::IsInternalPropertyId(propertyId) || propertyId == Js::Constants::NoProperty);
-        return JavascriptConversion::BooleanToPropertyQueryFlags(GetTypeHandler()->HasProperty(this, propertyId, nullptr /*pNoRedecl*/, info));
+        return JavascriptConversion::BooleanToPropertyQueryFlags(GetTypeHandler()->HasProperty(this, propertyId));
     }
 
     // HasOwnProperty and HasProperty is the same for most objects except globalobject (moduleroot as well in legacy)

+ 2 - 2
lib/Runtime/Types/ES5ArrayTypeHandler.cpp

@@ -725,7 +725,7 @@ namespace Js
     }
 
     template <class T>
-    BOOL ES5ArrayTypeHandlerBase<T>::HasProperty(DynamicObject* instance, PropertyId propertyId, bool *noRedecl, _Inout_opt_ PropertyValueInfo* info)
+    BOOL ES5ArrayTypeHandlerBase<T>::HasProperty(DynamicObject* instance, PropertyId propertyId, bool *noRedecl)
     {
         ScriptContext* scriptContext = instance->GetScriptContext();
         uint32 index;
@@ -741,7 +741,7 @@ namespace Js
             return ES5ArrayTypeHandlerBase<T>::HasItem(instance, index);
         }
 
-        return __super::HasProperty(instance, propertyId, noRedecl, info);
+        return __super::HasProperty(instance, propertyId, noRedecl);
     }
 
     template <class T>

+ 1 - 1
lib/Runtime/Types/ES5ArrayTypeHandler.h

@@ -158,7 +158,7 @@ namespace Js
         BOOL GetItemAccessors(ES5Array* arr, DynamicObject* instance, uint32 index, Var* getter, Var* setter);
 
     public:
-        virtual BOOL HasProperty(DynamicObject* instance, PropertyId propertyId, bool *noRedecl = nullptr, _Inout_opt_ PropertyValueInfo* info = nullptr) override;
+        virtual BOOL HasProperty(DynamicObject* instance, PropertyId propertyId, bool *noRedecl = nullptr) override;
         virtual BOOL HasProperty(DynamicObject* instance, JavascriptString* propertyNameString) override;
         virtual BOOL GetProperty(DynamicObject* instance, Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;
         virtual BOOL GetProperty(DynamicObject* instance, Var originalInstance, JavascriptString* propertyNameString, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;

+ 1 - 1
lib/Runtime/Types/MissingPropertyTypeHandler.cpp

@@ -56,7 +56,7 @@ namespace Js
     }
 #endif
 
-    BOOL MissingPropertyTypeHandler::HasProperty(DynamicObject* instance, PropertyId propertyId, __out_opt bool *noRedecl, _Inout_opt_ PropertyValueInfo* info)
+    BOOL MissingPropertyTypeHandler::HasProperty(DynamicObject* instance, PropertyId propertyId, __out_opt bool *noRedecl)
     {
         if (noRedecl != nullptr)
         {

+ 1 - 1
lib/Runtime/Types/MissingPropertyTypeHandler.h

@@ -31,7 +31,7 @@ namespace Js
         virtual bool IsObjTypeSpecEquivalent(const Type* type, const TypeEquivalenceRecord& record, uint& failedPropertyIndex) override;
         virtual bool IsObjTypeSpecEquivalent(const Type* type, const EquivalentPropertyEntry* entry) override;
 #endif
-        virtual BOOL HasProperty(DynamicObject* instance, PropertyId propertyId, __out_opt bool *noRedecl = nullptr, _Inout_opt_ PropertyValueInfo* info = nullptr) override;
+        virtual BOOL HasProperty(DynamicObject* instance, PropertyId propertyId, __out_opt bool *noRedecl = nullptr) override;
         virtual BOOL HasProperty(DynamicObject* instance, JavascriptString* propertyNameString) override;
         virtual BOOL GetProperty(DynamicObject* instance, Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;
         virtual BOOL GetProperty(DynamicObject* instance, Var originalInstance, JavascriptString* propertyNameString, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;

+ 1 - 1
lib/Runtime/Types/NullTypeHandler.cpp

@@ -72,7 +72,7 @@ namespace Js
     }
 #endif
 
-    BOOL NullTypeHandlerBase::HasProperty(DynamicObject* instance, PropertyId propertyId, __out_opt bool *noRedecl, _Inout_opt_ PropertyValueInfo* info)
+    BOOL NullTypeHandlerBase::HasProperty(DynamicObject* instance, PropertyId propertyId, __out_opt bool *noRedecl)
     {
         // Check numeric propertyId only if objectArray is available
         uint32 indexVal;

+ 1 - 1
lib/Runtime/Types/NullTypeHandler.h

@@ -35,7 +35,7 @@ namespace Js
         virtual bool IsObjTypeSpecEquivalent(const Type* type, const TypeEquivalenceRecord& record, uint& failedPropertyIndex) override;
         virtual bool IsObjTypeSpecEquivalent(const Type* type, const EquivalentPropertyEntry* entry) override;
 #endif
-        virtual BOOL HasProperty(DynamicObject* instance, PropertyId propertyId, __out_opt bool *noRedecl = nullptr, _Inout_opt_ PropertyValueInfo* info = nullptr) override;
+        virtual BOOL HasProperty(DynamicObject* instance, PropertyId propertyId, __out_opt bool *noRedecl = nullptr) override;
         virtual BOOL HasProperty(DynamicObject* instance, JavascriptString* propertyNameString) override;
         virtual BOOL GetProperty(DynamicObject* instance, Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;
         virtual BOOL GetProperty(DynamicObject* instance, Var originalInstance, JavascriptString* propertyNameString, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;

+ 23 - 56
lib/Runtime/Types/PathTypeHandler.cpp

@@ -312,7 +312,13 @@ namespace Js
                     if ((attr & (ObjectSlotAttr_Writable | ObjectSlotAttr_Accessor)) == ObjectSlotAttr_Writable)
                     {
                         PropertyValueInfo::SetCacheInfo(info, propertyString, propertyString->GetLdElemInlineCache(), false);
-                        SetPropertyValueInfo(info, instance, index, attr);
+                        PropertyValueInfo::Set(info, instance, index, ObjectSlotAttributesToPropertyAttributes(attr));
+#ifdef SUPPORT_FIXED_FIELDS_ON_PATH_TYPES
+                        if (FixPropsOnPathTypes() && (index >= this->GetTypePath()->GetMaxInitializedLength() || this->GetTypePath()->GetIsFixedFieldAt(index, GetPathLength())))
+                        {
+                            PropertyValueInfo::DisableStoreFieldCache(info);
+                        }
+#endif
                     }
                     else
                     {
@@ -581,18 +587,7 @@ namespace Js
     }
 #endif
 
-    void PathTypeHandlerBase::SetPropertyValueInfo(PropertyValueInfo* info, RecyclableObject* instance, PropertyIndex index, ObjectSlotAttributes attributes)
-    {
-        PropertyValueInfo::Set(info, instance, index, ObjectSlotAttributesToPropertyAttributes(attributes));
-#ifdef SUPPORT_FIXED_FIELDS_ON_PATH_TYPES
-        if (FixPropsOnPathTypes() && (index >= this->GetTypePath()->GetMaxInitializedLength() || this->GetTypePath()->GetIsFixedFieldAt(index, GetPathLength())))
-        {
-            PropertyValueInfo::DisableStoreFieldCache(info);
-        }
-#endif
-    }
-
-    BOOL PathTypeHandlerBase::HasProperty(DynamicObject* instance, PropertyId propertyId, __out_opt bool *noRedecl, _Inout_opt_ PropertyValueInfo* info)
+    BOOL PathTypeHandlerBase::HasProperty(DynamicObject* instance, PropertyId propertyId, __out_opt bool *noRedecl)
     {
         uint32 indexVal;
         if (noRedecl != nullptr)
@@ -600,13 +595,8 @@ namespace Js
             *noRedecl = false;
         }
 
-        PropertyIndex propertyIndex = PathTypeHandlerBase::GetPropertyIndex(propertyId);
-        if (propertyIndex != Constants::NoSlot)
+        if (PathTypeHandlerBase::GetPropertyIndex(propertyId) != Constants::NoSlot)
         {
-            if (info)
-            {
-                this->SetPropertyValueInfo(info, instance, propertyIndex);
-            }
             return true;
         }
 
@@ -634,7 +624,13 @@ namespace Js
         if (index != Constants::NoSlot)
         {
             *value = instance->GetSlot(index);
-            SetPropertyValueInfo(info, instance, index);
+            PropertyValueInfo::Set(info, instance, index);
+#ifdef SUPPORT_FIXED_FIELDS_ON_PATH_TYPES
+            if (FixPropsOnPathTypes() && (index >= this->GetTypePath()->GetMaxInitializedLength() || this->GetTypePath()->GetIsFixedFieldAt(index, GetPathLength())))
+            {
+                PropertyValueInfo::DisableStoreFieldCache(info);
+            }
+#endif
             return true;
         }
 
@@ -3578,41 +3574,6 @@ namespace Js
         return GetPropertyCount() - setterCount;
     }
 
-    BOOL PathTypeHandlerWithAttr::HasProperty(DynamicObject* instance, PropertyId propertyId, __out_opt bool *noRedecl, _Inout_opt_ PropertyValueInfo* info)
-    {
-        if (noRedecl != nullptr)
-        {
-            *noRedecl = false;
-        }
-
-        PropertyIndex index = GetTypePath()->LookupInline(propertyId, GetPathLength());
-        if (index == Constants::NoSlot)
-        {
-            return __super::HasProperty(instance, propertyId, noRedecl, info);
-        }
-
-        ObjectSlotAttributes attr = attributes[index];
-
-        if (attr & ObjectSlotAttr_Deleted)
-        {
-            return false;
-        }
-
-        if (attr & ObjectSlotAttr_Accessor)
-        {
-            // PropertyAttributes is only one byte so it can't carry out data about whether this is an accessor.
-            // Accessors must be cached differently than normal properties, so if we want to cache this we must
-            // do so here rather than in the caller. However, caching here would require passing originalInstance and 
-            // requestContext through a wide variety of call paths to this point (like we do for GetProperty), for
-            // very little improvement. For now, just block caching this case.
-            PropertyValueInfo::SetNoCache(info, instance);
-            return true;
-        }
-
-        this->SetPropertyValueInfo(info, instance, index, attr);
-        return true;
-    }
-
     BOOL PathTypeHandlerWithAttr::GetProperty(DynamicObject* instance, Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext)
     {
         PropertyIndex index = GetTypePath()->LookupInline(propertyId, GetPathLength());
@@ -3640,7 +3601,13 @@ namespace Js
         }
 
         *value = instance->GetSlot(index);
-        this->SetPropertyValueInfo(info, instance, index, attr);
+        PropertyValueInfo::Set(info, instance, index, ObjectSlotAttributesToPropertyAttributes(attributes[index]));
+#ifdef SUPPORT_FIXED_FIELDS_ON_PATH_TYPES
+        if (FixPropsOnPathTypes() && (index >= this->GetTypePath()->GetMaxInitializedLength() || this->GetTypePath()->GetIsFixedFieldAt(index, GetPathLength())))
+        {
+            PropertyValueInfo::DisableStoreFieldCache(info);
+        }
+#endif
         return true;
     }
 

+ 1 - 5
lib/Runtime/Types/PathTypeHandler.h

@@ -140,7 +140,7 @@ namespace Js
         virtual bool IsObjTypeSpecEquivalent(const Type* type, const TypeEquivalenceRecord& record, uint& failedPropertyIndex) override;
         virtual bool IsObjTypeSpecEquivalent(const Type* type, const EquivalentPropertyEntry* entry) override;
 #endif
-        virtual BOOL HasProperty(DynamicObject* instance, PropertyId propertyId, __out_opt bool *noRedecl = nullptr, _Inout_opt_ PropertyValueInfo* info = nullptr) override;
+        virtual BOOL HasProperty(DynamicObject* instance, PropertyId propertyId, __out_opt bool *noRedecl = nullptr) override;
         virtual BOOL HasProperty(DynamicObject* instance, JavascriptString* propertyNameString) override;
         virtual BOOL GetProperty(DynamicObject* instance, Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;
         virtual BOOL GetProperty(DynamicObject* instance, Var originalInstance, JavascriptString* propertyNameString, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;
@@ -318,7 +318,6 @@ namespace Js
         PropertyIndex GetPropertyIndex(PropertyId propertyId);
 
         void SetSlotAndCache(DynamicObject* instance, PropertyId propertyId, PropertyRecord const * record, PropertyIndex index, Var value, PropertyValueInfo* info, PropertyOperationFlags flags, SideEffects possibleSideEffects);
-
     protected:
         bool GetSuccessor(const PathTypeSuccessorKey successorKey, RecyclerWeakReference<DynamicType> ** typeWeakRef) const;
         void SetSuccessor(DynamicType * type, const PathTypeSuccessorKey successorKey, RecyclerWeakReference<DynamicType> * typeWeakRef, ScriptContext * scriptContext);
@@ -341,8 +340,6 @@ namespace Js
         virtual void SetSetterSlots(PathTypeSetterSlotIndex * setters) { Assert(false); }
         virtual void SetSetterSlot(PropertyIndex propertyIndex, PathTypeSetterSlotIndex setterSlot) { Assert(false); }
 
-        void SetPropertyValueInfo(PropertyValueInfo* info, RecyclableObject* instance, PropertyIndex index, ObjectSlotAttributes attributes = ObjectSlotAttr_Writable);
-
 #if ENABLE_FIXED_FIELDS
 #ifdef SUPPORT_FIXED_FIELDS_ON_PATH_TYPES
         template<class FMarkAsFixed> void InitializePath(DynamicObject *const object, const PropertyIndex slotIndex, const PropertyIndex objectSlotCount, ScriptContext *const scriptContext, const FMarkAsFixed MarkAsFixed);
@@ -490,7 +487,6 @@ namespace Js
         virtual BOOL SetConfigurable(DynamicObject* instance, PropertyId propertyId, BOOL value) override;
 
         virtual int GetPropertyCountForEnum() override;
-        virtual BOOL HasProperty(DynamicObject* instance, PropertyId propertyId, __out_opt bool *noRedecl, _Inout_opt_ PropertyValueInfo* info) override;
         virtual BOOL GetProperty(DynamicObject* instance, Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;
         virtual BOOL GetProperty(DynamicObject* instance, Var originalInstance, JavascriptString* propertyNameString, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;
         virtual BOOL GetAttributesWithPropertyIndex(DynamicObject * instance, PropertyId propertyId, BigPropertyIndex index, PropertyAttributes * attributes) override;

+ 1 - 1
lib/Runtime/Types/RecyclableObject.cpp

@@ -334,7 +334,7 @@ namespace Js
             /* TODO-ERROR: args.Info.Count > 0? args[0] : nullptr); */);
     }
 
-    PropertyQueryFlags RecyclableObject::HasPropertyQuery(PropertyId propertyId, _Inout_opt_ PropertyValueInfo* info)
+    PropertyQueryFlags RecyclableObject::HasPropertyQuery(PropertyId propertyId)
     {
         return PropertyQueryFlags::Property_NotFound;
     }

+ 1 - 1
lib/Runtime/Types/RecyclableObject.h

@@ -292,7 +292,7 @@ namespace Js {
         virtual PropertyId GetPropertyId(BigPropertyIndex index) { return Constants::NoProperty; }
         virtual PropertyIndex GetPropertyIndex(PropertyId propertyId) { return Constants::NoSlot; }
         virtual int GetPropertyCount() { return 0; }
-        virtual PropertyQueryFlags HasPropertyQuery(PropertyId propertyId, _Inout_opt_ PropertyValueInfo* info);
+        virtual PropertyQueryFlags HasPropertyQuery(PropertyId propertyId);
         virtual BOOL HasOwnProperty( PropertyId propertyId);
         virtual BOOL HasOwnPropertyNoHostObject( PropertyId propertyId);
         virtual BOOL HasOwnPropertyCheckNoRedecl( PropertyId propertyId) { Assert(FALSE); return FALSE; }

+ 1 - 1
lib/Runtime/Types/RecyclableObject.inl

@@ -69,7 +69,7 @@ namespace Js
 
     inline BOOL RecyclableObject::HasProperty(PropertyId propertyId)
     {
-        return JavascriptConversion::PropertyQueryFlagsToBoolean(HasPropertyQuery(propertyId, nullptr /*info*/));
+        return JavascriptConversion::PropertyQueryFlagsToBoolean(HasPropertyQuery(propertyId));
     }
 
     inline BOOL RecyclableObject::GetProperty(Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext)

+ 23 - 28
lib/Runtime/Types/SimpleDictionaryTypeHandler.cpp

@@ -623,7 +623,12 @@ namespace Js
                     if (descriptor.Attributes & PropertyWritable)
                     {
                         PropertyValueInfo::SetCacheInfo(info, propertyString, propertyString->GetLdElemInlineCache(), false);
-                        SetPropertyValueInfo(info, instance, &descriptor);
+                        SetPropertyValueInfo(info, instance, descriptor.propertyIndex, descriptor.Attributes);
+
+                        if (descriptor.IsOrMayBecomeFixed())
+                        {
+                            PropertyValueInfo::DisableStoreFieldCache(info);
+                        }
                     }
                     else
                     {
@@ -1044,20 +1049,20 @@ namespace Js
     }
 
     template <typename TPropertyIndex, typename TMapKey, bool IsNotExtensibleSupported>
-    BOOL SimpleDictionaryTypeHandlerBase<TPropertyIndex, TMapKey, IsNotExtensibleSupported>::HasProperty(DynamicObject* instance, PropertyId propertyId, bool *noRedecl, _Inout_opt_ PropertyValueInfo* info)
+    BOOL SimpleDictionaryTypeHandlerBase<TPropertyIndex, TMapKey, IsNotExtensibleSupported>::HasProperty(DynamicObject* instance, PropertyId propertyId, bool *noRedecl)
     {
-        return HasProperty_Internal<false>(instance, propertyId, noRedecl, info, nullptr, nullptr);
+        return HasProperty_Internal<false>(instance, propertyId, noRedecl, nullptr, nullptr);
     }
 
     template <typename TPropertyIndex, typename TMapKey, bool IsNotExtensibleSupported>
     BOOL SimpleDictionaryTypeHandlerBase<TPropertyIndex, TMapKey, IsNotExtensibleSupported>::HasRootProperty(DynamicObject* instance, PropertyId propertyId, bool *noRedecl, bool *pDeclaredProperty, bool *pNonconfigurableProperty)
     {
-        return HasProperty_Internal<true>(instance, propertyId, noRedecl, nullptr /*info*/, pDeclaredProperty, pNonconfigurableProperty);
+        return HasProperty_Internal<true>(instance, propertyId, noRedecl, pDeclaredProperty, pNonconfigurableProperty);
     }
 
     template <typename TPropertyIndex, typename TMapKey, bool IsNotExtensibleSupported>
     template <bool allowLetConstGlobal>
-    BOOL SimpleDictionaryTypeHandlerBase<TPropertyIndex, TMapKey, IsNotExtensibleSupported>::HasProperty_Internal(DynamicObject* instance, PropertyId propertyId, bool *noRedecl, _Inout_opt_ PropertyValueInfo* info, bool *pDeclaredProperty, bool *pNonconfigurableProperty)
+    BOOL SimpleDictionaryTypeHandlerBase<TPropertyIndex, TMapKey, IsNotExtensibleSupported>::HasProperty_Internal(DynamicObject* instance, PropertyId propertyId, bool *noRedecl, bool *pDeclaredProperty, bool *pNonconfigurableProperty)
     {
         // HasProperty is called with NoProperty in JavascriptDispatch.cpp to for undeferral of the
         // deferred type system that DOM objects use.  Allow NoProperty for this reason, but only
@@ -1088,10 +1093,6 @@ namespace Js
             {
                 *pNonconfigurableProperty = true;
             }
-            if (info && descriptor->propertyIndex != NoSlots)
-            {
-                SetPropertyValueInfo(info, instance, descriptor);
-            }
             return true;
         }
 
@@ -1188,7 +1189,11 @@ namespace Js
         if (descriptor->propertyIndex != NoSlots)
         {
             *value = instance->GetSlot(descriptor->propertyIndex);
-            SetPropertyValueInfo(info, instance, descriptor);
+            SetPropertyValueInfo(info, instance, descriptor->propertyIndex, descriptor->Attributes);
+            if (descriptor->IsOrMayBecomeFixed())
+            {
+                PropertyValueInfo::DisableStoreFieldCache(info);
+            }
         }
         else
         {
@@ -1419,7 +1424,7 @@ namespace Js
 
             if (!descriptor->IsOrMayBecomeFixed())
             {
-                SetPropertyValueInfoNonFixed(info, instance, descriptor->propertyIndex, descriptor->Attributes);
+                SetPropertyValueInfo(info, instance, descriptor->propertyIndex, descriptor->Attributes);
             }
             else
             {
@@ -2464,7 +2469,7 @@ namespace Js
 
                 if (!descriptor->IsOrMayBecomeFixed())
                 {
-                    SetPropertyValueInfoNonFixed(info, instance, descriptor->propertyIndex, descriptor->Attributes);
+                    SetPropertyValueInfo(info, instance, descriptor->propertyIndex, descriptor->Attributes);
                 }
                 else
                 {
@@ -2757,7 +2762,7 @@ namespace Js
         // without us knowing, and b) the inline cache doesn't inadvertently become polymorphic.
         if (markAsInitialized && !markAsFixed)
         {
-            SetPropertyValueInfoNonFixed(info, instance, index, attributes);
+            SetPropertyValueInfo(info, instance, index, attributes);
         }
         else
         {
@@ -3444,38 +3449,28 @@ namespace Js
     }
 
     template <typename TPropertyIndex, typename TMapKey, bool IsNotExtensibleSupported>
-    void SimpleDictionaryTypeHandlerBase<TPropertyIndex, TMapKey, IsNotExtensibleSupported>::SetPropertyValueInfo(PropertyValueInfo* info, RecyclableObject* instance, SimpleDictionaryPropertyDescriptor<TPropertyIndex>* descriptor)
-    {
-        SetPropertyValueInfoNonFixed(info, instance, descriptor->propertyIndex, descriptor->Attributes);
-        if (descriptor->IsOrMayBecomeFixed())
-        {
-            PropertyValueInfo::DisableStoreFieldCache(info);
-        }
-    }
-
-    template <typename TPropertyIndex, typename TMapKey, bool IsNotExtensibleSupported>
-    void SimpleDictionaryTypeHandlerBase<TPropertyIndex, TMapKey, IsNotExtensibleSupported>::SetPropertyValueInfoNonFixed(PropertyValueInfo* info, RecyclableObject* instance, TPropertyIndex propIndex, PropertyAttributes attributes, InlineCacheFlags flags)
+    void SimpleDictionaryTypeHandlerBase<TPropertyIndex, TMapKey, IsNotExtensibleSupported>::SetPropertyValueInfo(PropertyValueInfo* info, RecyclableObject* instance, TPropertyIndex propIndex, PropertyAttributes attributes, InlineCacheFlags flags)
     {
         PropertyValueInfo::Set(info, instance, propIndex, attributes, flags);
     }
 
     template <>
-    void SimpleDictionaryTypeHandlerBase<BigPropertyIndex, const PropertyRecord*, false>::SetPropertyValueInfoNonFixed(PropertyValueInfo* info, RecyclableObject* instance, BigPropertyIndex propIndex, PropertyAttributes attributes, InlineCacheFlags flags)
+    void SimpleDictionaryTypeHandlerBase<BigPropertyIndex, const PropertyRecord*, false>::SetPropertyValueInfo(PropertyValueInfo* info, RecyclableObject* instance, BigPropertyIndex propIndex, PropertyAttributes attributes, InlineCacheFlags flags)
     {
         PropertyValueInfo::SetNoCache(info, instance);
     }
     template <>
-    void SimpleDictionaryTypeHandlerBase<BigPropertyIndex, const PropertyRecord*, true>::SetPropertyValueInfoNonFixed(PropertyValueInfo* info, RecyclableObject* instance, BigPropertyIndex propIndex, PropertyAttributes attributes, InlineCacheFlags flags)
+    void SimpleDictionaryTypeHandlerBase<BigPropertyIndex, const PropertyRecord*, true>::SetPropertyValueInfo(PropertyValueInfo* info, RecyclableObject* instance, BigPropertyIndex propIndex, PropertyAttributes attributes, InlineCacheFlags flags)
     {
         PropertyValueInfo::SetNoCache(info, instance);
     }
     template <>
-    void SimpleDictionaryTypeHandlerBase<BigPropertyIndex, JavascriptString*, false>::SetPropertyValueInfoNonFixed(PropertyValueInfo* info, RecyclableObject* instance, BigPropertyIndex propIndex, PropertyAttributes attributes, InlineCacheFlags flags)
+    void SimpleDictionaryTypeHandlerBase<BigPropertyIndex, JavascriptString*, false>::SetPropertyValueInfo(PropertyValueInfo* info, RecyclableObject* instance, BigPropertyIndex propIndex, PropertyAttributes attributes, InlineCacheFlags flags)
     {
         PropertyValueInfo::SetNoCache(info, instance);
     }
     template <>
-    void SimpleDictionaryTypeHandlerBase<BigPropertyIndex, JavascriptString*, true>::SetPropertyValueInfoNonFixed(PropertyValueInfo* info, RecyclableObject* instance, BigPropertyIndex propIndex, PropertyAttributes attributes, InlineCacheFlags flags)
+    void SimpleDictionaryTypeHandlerBase<BigPropertyIndex, JavascriptString*, true>::SetPropertyValueInfo(PropertyValueInfo* info, RecyclableObject* instance, BigPropertyIndex propIndex, PropertyAttributes attributes, InlineCacheFlags flags)
     {
         PropertyValueInfo::SetNoCache(info, instance);
     }

+ 3 - 4
lib/Runtime/Types/SimpleDictionaryTypeHandler.h

@@ -125,7 +125,7 @@ namespace Js
         virtual BOOL FindNextProperty(ScriptContext* scriptContext, BigPropertyIndex& index, JavascriptString** propertyString,
             PropertyId* propertyId, PropertyAttributes* attributes, Type* type, DynamicType *typeToEnumerate, EnumeratorFlags flags, DynamicObject* instance, PropertyValueInfo* info) override;
 
-        virtual BOOL HasProperty(DynamicObject* instance, PropertyId propertyId, bool *noRedecl = nullptr, _Inout_opt_ PropertyValueInfo* info = nullptr) override;
+        virtual BOOL HasProperty(DynamicObject* instance, PropertyId propertyId, bool *noRedecl = nullptr) override;
         virtual BOOL HasProperty(DynamicObject* instance, JavascriptString* propertyNameString) override;
         virtual BOOL GetProperty(DynamicObject* instance, Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;
         virtual BOOL GetProperty(DynamicObject* instance, Var originalInstance, JavascriptString* propertyNameString, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;
@@ -270,7 +270,7 @@ namespace Js
         virtual BOOL FreezeImpl(DynamicObject* instance, bool isConvertedType) override;
 
         template <bool allowLetConstGlobal>
-        inline BOOL HasProperty_Internal(DynamicObject* instance, PropertyId propertyId, bool *noRedecl, _Inout_opt_ PropertyValueInfo* info, bool *pDeclaredProperty, bool *pNonconfigurableProperty);
+        inline BOOL HasProperty_Internal(DynamicObject* instance, PropertyId propertyId, bool *noRedecl, bool *pDeclaredProperty, bool *pNonconfigurableProperty);
         template <bool allowLetConstGlobal>
         inline PropertyIndex GetPropertyIndex_Internal(const PropertyRecord* propertyRecord);
         template <bool allowLetConstGlobal>
@@ -293,8 +293,7 @@ namespace Js
         BOOL SetProperty_JavascriptString(DynamicObject* instance, JavascriptString* propertyNameString, Var value, PropertyOperationFlags flags, PropertyValueInfo* info, TemplateParameter::Box<JavascriptString*>);
 
         BigSimpleDictionaryTypeHandler* ConvertToBigSimpleDictionaryTypeHandler(DynamicObject* instance);
-        void SetPropertyValueInfo(PropertyValueInfo* info, RecyclableObject* instance, SimpleDictionaryPropertyDescriptor<TPropertyIndex>* descriptor);
-        void SetPropertyValueInfoNonFixed(PropertyValueInfo* info, RecyclableObject* instance, TPropertyIndex propIndex, PropertyAttributes attributes, InlineCacheFlags flags = InlineCacheNoFlags);
+        void SetPropertyValueInfo(PropertyValueInfo* info, RecyclableObject* instance, TPropertyIndex propIndex, PropertyAttributes attributes, InlineCacheFlags flags = InlineCacheNoFlags);
 
         BOOL PreventExtensionsInternal(DynamicObject* instance);
         BOOL SealInternal(DynamicObject* instance);

+ 1 - 6
lib/Runtime/Types/SimpleTypeHandler.cpp

@@ -396,7 +396,7 @@ namespace Js
 #endif
 
     template<size_t size>
-    BOOL SimpleTypeHandler<size>::HasProperty(DynamicObject* instance, PropertyId propertyId, __out_opt bool *noRedecl, _Inout_opt_ PropertyValueInfo* info)
+    BOOL SimpleTypeHandler<size>::HasProperty(DynamicObject* instance, PropertyId propertyId, __out_opt bool *noRedecl)
     {
         if (noRedecl != nullptr)
         {
@@ -415,11 +415,6 @@ namespace Js
                 {
                     *noRedecl = true;
                 }
-
-                if (info)
-                {
-                    PropertyValueInfo::Set(info, instance, static_cast<PropertyIndex>(i), descriptors[i].Attributes);
-                }
                 return true;
             }
         }

+ 1 - 1
lib/Runtime/Types/SimpleTypeHandler.h

@@ -41,7 +41,7 @@ namespace Js
         virtual bool IsObjTypeSpecEquivalent(const Type* type, const TypeEquivalenceRecord& record, uint& failedPropertyIndex) override;
         virtual bool IsObjTypeSpecEquivalent(const Type* type, const EquivalentPropertyEntry* entry) override;
 #endif
-        virtual BOOL HasProperty(DynamicObject* instance, PropertyId propertyId, __out_opt bool *noRedecl = nullptr, _Inout_opt_ PropertyValueInfo* info = nullptr) override;
+        virtual BOOL HasProperty(DynamicObject* instance, PropertyId propertyId, __out_opt bool *noRedecl = nullptr) override;
         virtual BOOL HasProperty(DynamicObject* instance, JavascriptString* propertyNameString) override;
         virtual BOOL GetProperty(DynamicObject* instance, Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;
         virtual BOOL GetProperty(DynamicObject* instance, Var originalInstance, JavascriptString* propertyNameString, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;

+ 1 - 1
lib/Runtime/Types/SpreadArgument.h

@@ -26,7 +26,7 @@ namespace Js
         uint GetArgumentSpreadCount()  const { return iteratorIndices ? iteratorIndices->Count() : 0; }
 
         // A SpreadArgument should never call the Functions defined below this comment
-        virtual PropertyQueryFlags HasPropertyQuery(PropertyId propertyId, _Inout_opt_ PropertyValueInfo* info) override { AssertAndFailFast();  return PropertyQueryFlags::Property_NotFound; };
+        virtual PropertyQueryFlags HasPropertyQuery(PropertyId propertyId) override { AssertAndFailFast();  return PropertyQueryFlags::Property_NotFound; };
         virtual BOOL HasOwnProperty(PropertyId propertyId) override { AssertAndFailFast(); return FALSE; };
         virtual BOOL SetProperty(PropertyId propertyId, Var value, PropertyOperationFlags flags, PropertyValueInfo* info) override { AssertAndFailFast(); return FALSE; };
         virtual PropertyQueryFlags GetPropertyQuery(Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override { AssertAndFailFast(); return PropertyQueryFlags::Property_NotFound; };

+ 1 - 1
lib/Runtime/Types/TypeHandler.h

@@ -441,7 +441,7 @@ namespace Js
 #endif
 
         virtual bool EnsureObjectReady(DynamicObject* instance) { return true; }
-        virtual BOOL HasProperty(DynamicObject* instance, PropertyId propertyId, __out_opt bool *pNoRedecl = nullptr, _Inout_opt_ PropertyValueInfo* info = nullptr) = 0;
+        virtual BOOL HasProperty(DynamicObject* instance, PropertyId propertyId, __out_opt bool *pNoRedecl = nullptr) = 0;
         virtual BOOL HasProperty(DynamicObject* instance, JavascriptString* propertyNameString) = 0;
         virtual BOOL GetProperty(DynamicObject* instance, Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) = 0;
         virtual BOOL GetProperty(DynamicObject* instance, Var originalInstance, JavascriptString* propertyNameString, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) = 0;

+ 17 - 55
lib/Runtime/Types/TypePropertyCache.cpp

@@ -151,7 +151,6 @@ namespace Js
         return true;
     }
 
-    template <bool OutputExistence /*When set, propertyValue represents whether the property exists on the instance, not its actual value*/>
     bool TypePropertyCache::TryGetProperty(
         const bool checkMissing,
         RecyclableObject *const propertyObject,
@@ -212,27 +211,17 @@ namespace Js
                     ->InlineOrAuxSlotIndexToPropertyIndex(propertyIndex, isInlineSlot);
             Assert(typeHandlerPropertyIndex == propertyObject->GetPropertyIndex(propertyId));
         #endif
-            if (OutputExistence)
-            {
-                *propertyValue = JavascriptBoolean::ToVar(!isMissing, requestContext);
-                Assert(isMissing == !JavascriptOperators::HasProperty(propertyObject, propertyId));
-            }
-            else
-            {
-                *propertyValue =
-                    isInlineSlot
-                        ? DynamicObject::FromVar(propertyObject)->GetInlineSlot(propertyIndex)
-                        : DynamicObject::FromVar(propertyObject)->GetAuxSlot(propertyIndex);
-            }
+
+            *propertyValue =
+                isInlineSlot
+                    ? DynamicObject::FromVar(propertyObject)->GetInlineSlot(propertyIndex)
+                    : DynamicObject::FromVar(propertyObject)->GetAuxSlot(propertyIndex);
 
             if(propertyObject->GetScriptContext() == requestContext)
             {
-                if (!OutputExistence)
-                {
-                    DebugOnly(Var getPropertyValue = JavascriptOperators::GetProperty(propertyObject, propertyId, requestContext));
-                    Assert(*propertyValue == getPropertyValue ||
-                        (getPropertyValue == requestContext->GetLibrary()->GetNull() && requestContext->GetThreadContext()->IsDisableImplicitCall() && propertyObject->GetType()->IsExternal()));
-                }
+                DebugOnly(Var getPropertyValue = JavascriptOperators::GetProperty(propertyObject, propertyId, requestContext));
+                Assert(*propertyValue == getPropertyValue ||
+                    (getPropertyValue == requestContext->GetLibrary()->GetNull() && requestContext->GetThreadContext()->IsDisableImplicitCall() && propertyObject->GetType()->IsExternal()));
 
                 CacheOperators::Cache<false, true, false>(
                     false,
@@ -249,9 +238,9 @@ namespace Js
                     requestContext);
                 return true;
             }
-            else if (!OutputExistence)
+            else
             {
-                *propertyValue = CrossSite::MarshalVar(requestContext, *propertyValue);
+            *propertyValue = CrossSite::MarshalVar(requestContext, *propertyValue);
             }
             // Cannot use GetProperty and compare results since they may not compare equal when they're marshaled
 
@@ -284,24 +273,13 @@ namespace Js
         Assert(typeHandlerPropertyIndex == prototypeObjectWithProperty->GetPropertyIndex(propertyId));
     #endif
 
-        if (OutputExistence)
-        {
-            *propertyValue = JavascriptBoolean::ToVar(!isMissing, requestContext);
-            Assert(isMissing == !JavascriptOperators::HasProperty(propertyObject, propertyId));
-        }
-        else
-        {
-            *propertyValue =
-                isInlineSlot
-                    ? prototypeObjectWithProperty->GetInlineSlot(propertyIndex)
-                    : prototypeObjectWithProperty->GetAuxSlot(propertyIndex);
-        }
+        *propertyValue =
+            isInlineSlot
+                ? prototypeObjectWithProperty->GetInlineSlot(propertyIndex)
+                : prototypeObjectWithProperty->GetAuxSlot(propertyIndex);
         if(prototypeObjectWithProperty->GetScriptContext() == requestContext)
         {
-            if (!OutputExistence)
-            {
-                Assert(*propertyValue == JavascriptOperators::GetProperty(propertyObject, propertyId, requestContext));
-            }
+            Assert(*propertyValue == JavascriptOperators::GetProperty(propertyObject, propertyId, requestContext));
 
             if(propertyObject->GetScriptContext() != requestContext)
             {
@@ -323,9 +301,9 @@ namespace Js
                 requestContext);
             return true;
         }
-        else if (!OutputExistence)
+        else
         {
-            *propertyValue = CrossSite::MarshalVar(requestContext, *propertyValue);
+        *propertyValue = CrossSite::MarshalVar(requestContext, *propertyValue);
         }
         // Cannot use GetProperty and compare results since they may not compare equal when they're marshaled
 
@@ -336,22 +314,6 @@ namespace Js
         }
         return true;
     }
-    template bool TypePropertyCache::TryGetProperty<false>(
-        const bool checkMissing,
-        RecyclableObject *const propertyObject,
-        const PropertyId propertyId,
-        Var *const propertyValue,
-        ScriptContext *const requestContext,
-        PropertyCacheOperationInfo *const operationInfo,
-        PropertyValueInfo *const propertyValueInfo);
-    template bool TypePropertyCache::TryGetProperty<true>(
-        const bool checkMissing,
-        RecyclableObject *const propertyObject,
-        const PropertyId propertyId,
-        Var *const propertyValue,
-        ScriptContext *const requestContext,
-        PropertyCacheOperationInfo *const operationInfo,
-        PropertyValueInfo *const propertyValueInfo);
 
     bool TypePropertyCache::TrySetProperty(
         RecyclableObject *const object,

+ 0 - 1
lib/Runtime/Types/TypePropertyCache.h

@@ -58,7 +58,6 @@ namespace Js
         bool TryGetIndexForStore(const PropertyId id, PropertyIndex *const index, bool *const isInlineSlot) const;
 
     public:
-        template <bool OutputExistence /*When set, propertyValue represents whether the property exists on the instance, not its actual value*/>
         bool TryGetProperty(const bool checkMissing, RecyclableObject *const propertyObject, const PropertyId propertyId, Var *const propertyValue, ScriptContext *const requestContext, PropertyCacheOperationInfo *const operationInfo, PropertyValueInfo *const propertyValueInfo);
         bool TrySetProperty(RecyclableObject *const object, const PropertyId propertyId, Var propertyValue, ScriptContext *const requestContext, PropertyCacheOperationInfo *const operationInfo, PropertyValueInfo *const propertyValueInfo);
 

+ 1 - 1
lib/Runtime/Types/WithScopeObject.cpp

@@ -23,7 +23,7 @@ namespace Js
         return static_cast<WithScopeObject*>(aValue);
     }
 
-    PropertyQueryFlags WithScopeObject::HasPropertyQuery(PropertyId propertyId, _Inout_opt_ PropertyValueInfo* info)
+    PropertyQueryFlags WithScopeObject::HasPropertyQuery(PropertyId propertyId)
     {
         return JavascriptConversion::BooleanToPropertyQueryFlags(JavascriptOperators::HasPropertyUnscopables(wrappedObject, propertyId));
     }

+ 1 - 1
lib/Runtime/Types/WithScopeObject.h

@@ -29,7 +29,7 @@ namespace Js
             static WithScopeObject* FromVar(Var value);
             static WithScopeObject* UnsafeFromVar(Var value);
             RecyclableObject *GetWrappedObject() { return wrappedObject; }
-            virtual PropertyQueryFlags HasPropertyQuery(PropertyId propertyId, _Inout_opt_ PropertyValueInfo* info) override;
+            virtual PropertyQueryFlags HasPropertyQuery(PropertyId propertyId) override;
             virtual BOOL HasOwnProperty(PropertyId propertyId) override;
             virtual BOOL SetProperty(PropertyId propertyId, Var value, PropertyOperationFlags flags, PropertyValueInfo* info) override;
             virtual PropertyQueryFlags GetPropertyQuery(Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;