Commit 0c919c45 authored by Zhang, Shiyu's avatar Zhang, Shiyu Committed by Commit Bot

[builtins] Fix correctness failure for GetOwnPropertyNames builtin

.. by moving the element check forward. So that we skip try_fast path
when we have elements on the receiver.


Bug: chromium:977870,chromium:983982
Change-Id: Ib26fb3df215ffc5e0ac0c7e344a4239b845fe129
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1697042
Commit-Queue: Shiyu Zhang <shiyu.zhang@intel.com>
Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#62796}
parent e7585a44
......@@ -590,27 +590,30 @@ TF_BUILTIN(ObjectGetOwnPropertyNames, ObjectBuiltinsAssembler) {
VARIABLE(var_length, MachineRepresentation::kTagged);
VARIABLE(var_elements, MachineRepresentation::kTagged);
Label if_empty(this, Label::kDeferred), if_empty_elements(this),
if_fast(this), if_slow(this, Label::kDeferred), if_join(this);
if_fast(this), try_fast(this, Label::kDeferred),
if_slow(this, Label::kDeferred), if_join(this);
// Check if the {object} has a usable enum cache.
// Take the slow path if the {object} IsCustomElementsReceiverInstanceType or
// has any elements.
GotoIf(TaggedIsSmi(object), &if_slow);
Node* object_map = LoadMap(object);
TNode<Int32T> instance_type = LoadMapInstanceType(object_map);
GotoIf(IsCustomElementsReceiverInstanceType(instance_type), &if_slow);
Node* object_elements = LoadElements(object);
GotoIf(IsEmptyFixedArray(object_elements), &if_empty_elements);
Branch(IsEmptySlowElementDictionary(object_elements), &if_empty_elements,
&if_slow);
// Check if the {object} has a usable enum cache.
BIND(&if_empty_elements);
Node* object_bit_field3 = LoadMapBitField3(object_map);
Node* object_enum_length =
DecodeWordFromWord32<Map::EnumLengthBits>(object_bit_field3);
GotoIf(
WordEqual(object_enum_length, IntPtrConstant(kInvalidEnumCacheSentinel)),
&if_slow);
// Ensure that the {object} doesn't have any elements.
CSA_ASSERT(this, IsJSObjectMap(object_map));
Node* object_elements = LoadElements(object);
GotoIf(IsEmptyFixedArray(object_elements), &if_empty_elements);
Branch(IsEmptySlowElementDictionary(object_elements), &if_empty_elements,
&if_slow);
&try_fast);
// Check whether all own properties are enumerable.
BIND(&if_empty_elements);
Node* number_descriptors =
DecodeWordFromWord32<Map::NumberOfOwnDescriptorsBits>(object_bit_field3);
GotoIfNot(WordEqual(object_enum_length, number_descriptors), &if_slow);
......@@ -643,6 +646,16 @@ TF_BUILTIN(ObjectGetOwnPropertyNames, ObjectBuiltinsAssembler) {
Return(array);
}
BIND(&try_fast);
{
// Let the runtime compute the elements and try initializing enum cache.
Node* elements = CallRuntime(Runtime::kObjectGetOwnPropertyNamesTryFast,
context, object);
var_length.Bind(LoadObjectField(elements, FixedArray::kLengthOffset));
var_elements.Bind(elements);
Goto(&if_join);
}
BIND(&if_empty);
{
// The {object} doesn't have any enumerable keys.
......
......@@ -311,6 +311,7 @@ bool IntrinsicHasNoSideEffect(Runtime::FunctionId id) {
V(ObjectValues) \
V(ObjectValuesSkipFastPath) \
V(ObjectGetOwnPropertyNames) \
V(ObjectGetOwnPropertyNamesTryFast) \
V(ObjectIsExtensible) \
V(RegExpInitializeAndCompile) \
V(StackGuard) \
......
......@@ -228,6 +228,36 @@ RUNTIME_FUNCTION(Runtime_ObjectGetOwnPropertyNames) {
return *keys;
}
RUNTIME_FUNCTION(Runtime_ObjectGetOwnPropertyNamesTryFast) {
HandleScope scope(isolate);
Handle<Object> object = args.at(0);
// Convert the {object} to a proper {receiver}.
Handle<JSReceiver> receiver;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver,
Object::ToObject(isolate, object));
Handle<Map> map(receiver->map(), isolate);
int nod = map->NumberOfOwnDescriptors();
Handle<FixedArray> keys;
if (nod != 0 && map->NumberOfEnumerableProperties() == nod) {
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, keys,
KeyAccumulator::GetKeys(receiver, KeyCollectionMode::kOwnOnly,
ENUMERABLE_STRINGS,
GetKeysConversion::kConvertToString));
} else {
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, keys,
KeyAccumulator::GetKeys(receiver, KeyCollectionMode::kOwnOnly,
SKIP_SYMBOLS,
GetKeysConversion::kConvertToString));
}
return *keys;
}
// ES6 19.1.3.2
RUNTIME_FUNCTION(Runtime_ObjectHasOwnProperty) {
HandleScope scope(isolate);
......
......@@ -310,6 +310,7 @@ namespace internal {
F(ObjectEntries, 1, 1) \
F(ObjectEntriesSkipFastPath, 1, 1) \
F(ObjectGetOwnPropertyNames, 1, 1) \
F(ObjectGetOwnPropertyNamesTryFast, 1, 1) \
F(ObjectHasOwnProperty, 2, 1) \
F(ObjectIsExtensible, 1, 1) \
F(ObjectKeys, 1, 1) \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment