Index: src/handles.cc |
=================================================================== |
--- src/handles.cc (revision 3386) |
+++ src/handles.cc (working copy) |
@@ -548,6 +548,12 @@ |
Handle<FixedArray> GetKeysInFixedArrayFor(Handle<JSObject> object, |
KeyCollectionType type) { |
Handle<FixedArray> content = Factory::empty_fixed_array(); |
+ Handle<JSObject> arguments_boilerplate = |
+ Handle<JSObject>( |
+ Top::context()->global_context()->arguments_boilerplate()); |
+ Handle<JSFunction> arguments_function = |
+ Handle<JSFunction>( |
+ JSFunction::cast(arguments_boilerplate->map()->constructor())); |
// Only collect keys if access is permitted. |
for (Handle<Object> p = object; |
@@ -577,8 +583,21 @@ |
content = AddKeysFromJSArray(content, v8::Utils::OpenHandle(*result)); |
} |
- // Compute the property keys. |
- content = UnionOfKeys(content, GetEnumPropertyKeys(current)); |
+ // We can cache the computed property keys if access checks are |
+ // not needed and no interceptors are involved. |
+ // |
+ // We do not use the cache if the object has elements and |
+ // therefore it does not make sense to cache the property names |
+ // for arguments objects. Arguments objects will always have |
+ // elements. |
+ bool cache_enum_keys = |
+ ((current->map()->constructor() != *arguments_function) && |
+ !current->IsAccessCheckNeeded() && |
+ !current->HasNamedInterceptor() && |
+ !current->HasIndexedInterceptor()); |
+ // Compute the property keys and cache them if possible. |
+ content = |
+ UnionOfKeys(content, GetEnumPropertyKeys(current, cache_enum_keys)); |
// Add the property keys from the interceptor. |
if (current->HasNamedInterceptor()) { |
@@ -605,7 +624,8 @@ |
} |
-Handle<FixedArray> GetEnumPropertyKeys(Handle<JSObject> object) { |
+Handle<FixedArray> GetEnumPropertyKeys(Handle<JSObject> object, |
+ bool cache_result) { |
int index = 0; |
if (object->HasFastProperties()) { |
if (object->map()->instance_descriptors()->HasEnumCache()) { |
@@ -628,10 +648,12 @@ |
} |
} |
(*storage)->SortPairs(*sort_array, sort_array->length()); |
- Handle<FixedArray> bridge_storage = |
- Factory::NewFixedArray(DescriptorArray::kEnumCacheBridgeLength); |
- DescriptorArray* desc = object->map()->instance_descriptors(); |
- desc->SetEnumCache(*bridge_storage, *storage); |
+ if (cache_result) { |
+ Handle<FixedArray> bridge_storage = |
+ Factory::NewFixedArray(DescriptorArray::kEnumCacheBridgeLength); |
+ DescriptorArray* desc = object->map()->instance_descriptors(); |
+ desc->SetEnumCache(*bridge_storage, *storage); |
+ } |
ASSERT(storage->length() == index); |
return storage; |
} else { |