Index: src/builtins.cc |
diff --git a/src/builtins.cc b/src/builtins.cc |
index 806f8d6bd6bf8031b0ca22ae248432a9e1290577..7cc65cdabbb7c9433c3a9612d109d6349b2c1f00 100644 |
--- a/src/builtins.cc |
+++ b/src/builtins.cc |
@@ -1766,13 +1766,37 @@ BUILTIN(ObjectKeys) { |
Handle<JSReceiver> receiver; |
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver, |
Object::ToObject(isolate, object)); |
+ |
Handle<FixedArray> keys; |
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
- isolate, keys, JSReceiver::GetKeys(receiver, OWN_ONLY, ENUMERABLE_STRINGS, |
- CONVERT_TO_STRING)); |
- return *isolate->factory()->NewJSArrayWithElements(keys); |
-} |
+ int enum_length = receiver->map()->EnumLength(); |
+ if (enum_length != kInvalidEnumCacheSentinel) { |
+ DCHECK(receiver->IsJSObject()); |
+ Handle<JSObject> js_object = Handle<JSObject>::cast(receiver); |
+ DCHECK(!js_object->HasNamedInterceptor()); |
+ DCHECK(!js_object->IsAccessCheckNeeded()); |
+ DCHECK(!js_object->map()->has_hidden_prototype()); |
+ DCHECK(js_object->HasFastProperties()); |
+ if (js_object->elements() == isolate->heap()->empty_fixed_array()) { |
+ keys = isolate->factory()->NewFixedArray(enum_length); |
+ if (enum_length != 0) { |
+ Handle<FixedArray> cache( |
+ js_object->map()->instance_descriptors()->GetEnumCache()); |
+ keys = isolate->factory()->NewFixedArray(enum_length); |
+ for (int i = 0; i < enum_length; i++) { |
+ keys->set(i, cache->get(i)); |
+ } |
+ } |
+ } |
+ } |
+ if (keys.is_null()) { |
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
+ isolate, keys, |
+ JSReceiver::GetKeys(receiver, OWN_ONLY, ENUMERABLE_STRINGS, |
+ CONVERT_TO_STRING)); |
+ } |
+ return *isolate->factory()->NewJSArrayWithElements(keys, FAST_ELEMENTS); |
+} |
BUILTIN(ObjectValues) { |
HandleScope scope(isolate); |