Skip to content
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

Merged
merged 1 commit into from
Feb 21, 2018

Conversation

pleath
Copy link
Contributor

@pleath pleath commented Nov 20, 2017

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.

@pleath pleath force-pushed the sharesetters branch 3 times, most recently from 3789e94 to 92a20f1 Compare November 21, 2017 22:40
@pleath
Copy link
Contributor Author

pleath commented Feb 10, 2018

Updated this PR, merging in current state of master.

@pleath pleath force-pushed the sharesetters branch 2 times, most recently from 0a49a2b to a848a47 Compare February 11, 2018 02:08
@rajatd
Copy link
Contributor

rajatd commented Feb 14, 2018

    propertyOwnerType = localCache.u.accessor.object->GetType();

Missing check for isOnProto here? #Resolved


Refers to: lib/Backend/ObjTypeSpecFldInfo.cpp:303 in a848a47. [](commit_id = a848a47, deletion_comment = False)

}
else
{
function = RecyclableObject::UnsafeFromVar(DynamicObject::FromVar(propertyObject)->GetInlineSlot(u.accessor.slotIndex));
Copy link
Contributor

@rajatd rajatd Feb 14, 2018

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

Copy link
Contributor Author

@pleath pleath Feb 15, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool. Thanks. #Resolved

@pleath
Copy link
Contributor Author

pleath commented Feb 15, 2018

Good catch of "isOnProto." Thanks.

{
PropertyIndex getterIndex = currentTypeHandler->GetPropertyIndex(currentPropertyRecord->GetPropertyId());
Assert(getterIndex != Constants::NoSlot);
if (currentTypeHandler->GetAttributes(getterIndex) & ObjectSlotAttr_Accessor)
Copy link
Contributor

@rajatd rajatd Feb 15, 2018

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

Copy link
Contributor Author

@pleath pleath Feb 15, 2018

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, &currentSlotIndex);
PropertyIndex index;
currentType = currentTypeHandler->PromoteType<false>(currentType, PathTypeSuccessorKey(currentPropertyRecord->GetPropertyId(), currentAttributes), false, scriptContext, instance, &index);
Copy link
Contributor

@rajatd rajatd Feb 15, 2018

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

Copy link
Contributor Author

@pleath pleath Feb 15, 2018

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));
Copy link
Contributor

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?

Copy link
Contributor Author

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.

Copy link
Contributor Author

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.

Copy link
Contributor

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)

Copy link
Contributor Author

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.
@chakrabot chakrabot merged commit 83f8af8 into chakra-core:master Feb 21, 2018
chakrabot pushed a commit that referenced this pull request Feb 21, 2018
…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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants