Don't use OwnPrototypeChainLength in GetOwnPropertyNames

BUG=
R=ishell@chromium.org

Review URL: https://codereview.chromium.org/574753002

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@23997 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
verwaest@chromium.org 2014-09-17 09:56:51 +00:00
parent ac1b9b11dc
commit d0ad526359
3 changed files with 37 additions and 72 deletions

View File

@ -13346,23 +13346,24 @@ void FixedArray::SortPairs(FixedArray* numbers, uint32_t len) {
// Fill in the names of own properties into the supplied storage. The main
// purpose of this function is to provide reflection information for the object
// mirrors.
void JSObject::GetOwnPropertyNames(
FixedArray* storage, int index, PropertyAttributes filter) {
int JSObject::GetOwnPropertyNames(FixedArray* storage, int index,
PropertyAttributes filter) {
DCHECK(storage->length() >= (NumberOfOwnProperties(filter) - index));
if (HasFastProperties()) {
int offset = 0;
int real_size = map()->NumberOfOwnDescriptors();
DescriptorArray* descs = map()->instance_descriptors();
for (int i = 0; i < real_size; i++) {
if ((descs->GetDetails(i).attributes() & filter) == 0 &&
!FilterKey(descs->GetKey(i), filter)) {
storage->set(index++, descs->GetKey(i));
storage->set(index + offset, descs->GetKey(i));
offset++;
}
}
return offset;
} else {
property_dictionary()->CopyKeysTo(storage,
index,
filter,
NameDictionary::UNSORTED);
return property_dictionary()->CopyKeysTo(storage, index, filter,
NameDictionary::UNSORTED);
}
}
@ -14055,13 +14056,11 @@ template Handle<SeededNumberDictionary>
HashTable<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>::
Shrink(Handle<SeededNumberDictionary>, uint32_t);
template void Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >::
CopyKeysTo(
FixedArray*,
int,
PropertyAttributes,
Dictionary<
NameDictionary, NameDictionaryShape, Handle<Name> >::SortMode);
template int
Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >::CopyKeysTo(
FixedArray*, int, PropertyAttributes,
Dictionary<NameDictionary, NameDictionaryShape,
Handle<Name> >::SortMode);
template int
Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >::
@ -15208,27 +15207,28 @@ void NameDictionary::CopyEnumKeysTo(FixedArray* storage) {
}
template<typename Derived, typename Shape, typename Key>
void Dictionary<Derived, Shape, Key>::CopyKeysTo(
FixedArray* storage,
int index,
PropertyAttributes filter,
template <typename Derived, typename Shape, typename Key>
int Dictionary<Derived, Shape, Key>::CopyKeysTo(
FixedArray* storage, int index, PropertyAttributes filter,
typename Dictionary<Derived, Shape, Key>::SortMode sort_mode) {
DCHECK(storage->length() >= NumberOfElementsFilterAttributes(filter));
int capacity = DerivedHashTable::Capacity();
int offset = 0;
for (int i = 0; i < capacity; i++) {
Object* k = DerivedHashTable::KeyAt(i);
if (DerivedHashTable::IsKey(k) && !FilterKey(k, filter)) {
PropertyDetails details = DetailsAt(i);
if (details.IsDeleted()) continue;
PropertyAttributes attr = details.attributes();
if ((attr & filter) == 0) storage->set(index++, k);
if ((attr & filter) == 0) storage->set(index + offset, k);
offset++;
}
}
if (sort_mode == Dictionary::SORTED) {
storage->SortPairs(storage, index);
storage->SortPairs(storage, index + offset);
}
DCHECK(storage->length() >= index);
DCHECK(storage->length() >= index + offset);
return offset;
}

View File

@ -2328,9 +2328,9 @@ class JSObject: public JSReceiver {
// with the specified attributes (ignoring interceptors).
int NumberOfOwnProperties(PropertyAttributes filter = NONE);
// Fill in details for properties into storage starting at the specified
// index.
void GetOwnPropertyNames(
FixedArray* storage, int index, PropertyAttributes filter = NONE);
// index. Returns the number of properties that were added.
int GetOwnPropertyNames(FixedArray* storage, int index,
PropertyAttributes filter = NONE);
// Returns the number of properties on this object filtering out properties
// with the specified attributes (ignoring interceptors).
@ -3863,10 +3863,8 @@ class Dictionary: public HashTable<Derived, Shape, Key> {
PropertyAttributes filter,
SortMode sort_mode);
// Fill in details for properties into storage.
void CopyKeysTo(FixedArray* storage,
int index,
PropertyAttributes filter,
SortMode sort_mode);
int CopyKeysTo(FixedArray* storage, int index, PropertyAttributes filter,
SortMode sort_mode);
// Accessors for next enumeration index.
void SetNextEnumerationIndex(int index) {

View File

@ -5744,19 +5744,6 @@ RUNTIME_FUNCTION(Runtime_GetPropertyNamesFast) {
}
// Find the length of the prototype chain that is to be handled as one. If a
// prototype object is hidden it is to be viewed as part of the the object it
// is prototype for.
static int OwnPrototypeChainLength(JSObject* obj) {
int count = 1;
for (PrototypeIterator iter(obj->GetIsolate(), obj);
!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN); iter.Advance()) {
count++;
}
return count;
}
// Return the names of the own named properties.
// args[0]: object
// args[1]: PropertyAttributes as int
@ -5770,30 +5757,12 @@ RUNTIME_FUNCTION(Runtime_GetOwnPropertyNames) {
CONVERT_SMI_ARG_CHECKED(filter_value, 1);
PropertyAttributes filter = static_cast<PropertyAttributes>(filter_value);
// Skip the global proxy as it has no properties and always delegates to the
// real global object.
if (obj->IsJSGlobalProxy()) {
// Only collect names if access is permitted.
if (obj->IsAccessCheckNeeded() &&
!isolate->MayNamedAccess(
obj, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) {
isolate->ReportFailedAccessCheck(obj, v8::ACCESS_KEYS);
RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
return *isolate->factory()->NewJSArray(0);
}
PrototypeIterator iter(isolate, obj);
obj = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
}
// Find the number of objects making up this.
int length = OwnPrototypeChainLength(*obj);
// Find the number of own properties for each of the objects.
ScopedVector<int> own_property_count(length);
int total_property_count = 0;
{
PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER);
for (int i = 0; i < length; i++) {
for (; !iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN);
iter.Advance()) {
DCHECK(!iter.IsAtEnd());
Handle<JSObject> jsproto =
Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
@ -5808,9 +5777,7 @@ RUNTIME_FUNCTION(Runtime_GetOwnPropertyNames) {
}
int n;
n = jsproto->NumberOfOwnProperties(filter);
own_property_count[i] = n;
total_property_count += n;
iter.Advance();
}
}
@ -5823,17 +5790,18 @@ RUNTIME_FUNCTION(Runtime_GetOwnPropertyNames) {
int hidden_strings = 0;
{
PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER);
for (int i = 0; i < length; i++) {
DCHECK(!iter.IsAtEnd());
for (; !iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN);
iter.Advance()) {
Handle<JSObject> jsproto =
Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
jsproto->GetOwnPropertyNames(*names, next_copy_index, filter);
if (i > 0) {
int own_property_count =
jsproto->GetOwnPropertyNames(*names, next_copy_index, filter);
if (!jsproto.is_identical_to(obj)) {
// Names from hidden prototypes may already have been added
// for inherited function template instances. Count the duplicates
// and stub them out; the final copy pass at the end ignores holes.
for (int j = next_copy_index;
j < next_copy_index + own_property_count[i]; j++) {
for (int j = next_copy_index; j < next_copy_index + own_property_count;
j++) {
Object* name_from_hidden_proto = names->get(j);
for (int k = 0; k < next_copy_index; k++) {
if (names->get(k) != isolate->heap()->hidden_string()) {
@ -5847,13 +5815,12 @@ RUNTIME_FUNCTION(Runtime_GetOwnPropertyNames) {
}
}
}
next_copy_index += own_property_count[i];
next_copy_index += own_property_count;
// Hidden properties only show up if the filter does not skip strings.
if ((filter & STRING) == 0 && JSObject::HasHiddenProperties(jsproto)) {
hidden_strings++;
}
iter.Advance();
}
}