-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Share types on objects with getter/setter properties. #4283
Conversation
3789e94
to
92a20f1
Compare
Updated this PR, merging in current state of master. |
0a49a2b
to
a848a47
Compare
lib/Runtime/Language/InlineCache.inl
Outdated
} | ||
else | ||
{ | ||
function = RecyclableObject::UnsafeFromVar(DynamicObject::FromVar(propertyObject)->GetInlineSlot(u.accessor.slotIndex)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FromVar [](start = 74, length = 7)
I think you can use UnsafeFromVar here since 'type' is the same as the cached type. #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool. Thanks. #Resolved
Good catch of "isOnProto." Thanks. |
{ | ||
PropertyIndex getterIndex = currentTypeHandler->GetPropertyIndex(currentPropertyRecord->GetPropertyId()); | ||
Assert(getterIndex != Constants::NoSlot); | ||
if (currentTypeHandler->GetAttributes(getterIndex) & ObjectSlotAttr_Accessor) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
currentTypeHandler->GetAttributes(getterIndex) & ObjectSlotAttr_Accessor [](start = 20, length = 72)
Wouldn't this condition be always true? #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Weirdly, no. In an object literal, for instance, you can initialize "get x", followed by a data property x, followed by "set x". #Resolved
@@ -211,14 +211,24 @@ namespace Js | |||
while (true) | |||
{ | |||
const PropertyRecord *currentPropertyRecord = GetTypePath()->GetPropertyIdUnchecked(currentSlotIndex); | |||
currentType = currentTypeHandler->PromoteType<false>(currentType, PathTypeSuccessorKey(currentPropertyRecord->GetPropertyId(), currentAttributes), false, scriptContext, instance, ¤tSlotIndex); | |||
PropertyIndex index; | |||
currentType = currentTypeHandler->PromoteType<false>(currentType, PathTypeSuccessorKey(currentPropertyRecord->GetPropertyId(), currentAttributes), false, scriptContext, instance, &index); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
index [](start = 192, length = 5)
Call to InitializePath below was using the currentSlotIndex
updated in PromoteType. Was that a bug all along? #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIRC, the difference between currentSlotIndex and this local "index" only becomes possible when we start supporting accessors here, because of the extra slot we make for the setter. #Resolved
} | ||
if (getter != nullptr) | ||
{ | ||
newTypeHandler->SetSlotUnchecked(instance, propertyIndex, CanonicalizeAccessor(getter, library)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SetSlotUnchecked [](start = 32, length = 16)
Would we possibly want to call SetSlotAndCache instead of SetSlotUnchecked?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're not currently set up to use PropertyValueInfo on this path, so we can't use SetSlotAndCache. Currently DictionaryTypeHandler::SetAccessors is the only path for setting/adding accessors to a type handler, and it calls SetSlotUnchecked.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BTW, we're setting accessor inline caches at LdFld/StFld that call the accessors, so we're covered. We enter this method at defineProperty/object literal/etc., so setting an inline cache here isn't probably appropriate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed. But AddPropertyInternal in the 'if' clause above ends up calling SetSlotAndCache.
In reply to: 169468872 [](ancestors = 169468872)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Discussed this offline. The gist is that in a non-add-property case the cache only needs to be updated when the type is changing, under SetAttributesHelper. We should investigate what we can do to make that path update the cache.
… bit is set in a property's attributes, that indicates the property is a Getter. The Setter is stored in another slot. Use an array of indices to find the setter associated with a given Getter. Add the option of increasing a TypePath's path length without adding another property ID to its property map. Fix the way we use the accessor inline cache, in both runtime code and jitted code. We need to look at th isOnProto bit to determine which object to get the property from, the object pointed to by the cache (if isOnProto is set) or the current local instance. (This wasn't necessary when objects with accessors didn't share types.) While I was in there, I deleted all the machine-dependent lowering code related to flag caches and added code in Lower.cpp for everyone to share.
…rties. Merge pull request #4283 from pleath:sharesetters If the Accessor bit is set in a property's attributes, that indicates the property is a Getter. The Setter is stored in another slot. Use an array of indices to find the setter associated with a given Getter. Add the option of increasing a TypePath's path length without adding another property ID to its property map. Fix the way we use the accessor inline cache, in both runtime code and jitted code. We need to look at th isOnProto bit to determine which object to get the property from, the object pointed to by the cache (if isOnProto is set) or the current local instance. (This wasn't necessary when objects with accessors didn't share types.) While I was in there, I deleted all the machine-dependent lowering code related to flag caches and added code in Lower.cpp for everyone to share.
If the Accessor bit is set in a property's attributes, that indicates the property is a Getter. The Setter is stored in another slot. Use an array of indices to find the setter associated with a given Getter. Add the option of increasing a TypePath's path length without adding another property ID to its property map. Fix the way we use the accessor inline cache, in both runtime code and jitted code. We need to look at th isOnProto bit to determine which object to get the property from, the object pointed to by the cache (if isOnProto is set) or the current local instance. (This wasn't necessary when objects with accessors didn't share types.) While I was in there, I deleted all the machine-dependent lowering code related to flag caches and added code in Lower.cpp for everyone to share.