Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(117)

Unified Diff: src/runtime/runtime-forin.cc

Issue 1631583002: [for-in] Further refactorings and unification around for-in. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/runtime/runtime-forin.cc
diff --git a/src/runtime/runtime-forin.cc b/src/runtime/runtime-forin.cc
index e6c9cca20f341349774da3a12e72eb41b7c438de..57a05f6f3b6a84d48bf0c9cd38d470c54ede9e57 100644
--- a/src/runtime/runtime-forin.cc
+++ b/src/runtime/runtime-forin.cc
@@ -12,32 +12,70 @@
namespace v8 {
namespace internal {
-RUNTIME_FUNCTION_RETURN_TRIPLE(Runtime_ForInPrepare) {
+namespace {
+
+// Returns either a FixedArray or, if the given {receiver} has an enum cache
+// that contains all enumerable properties of the {receiver} and its prototypes
+// have none, the map of the {receiver}. This is used to speed up the check for
+// deletions during a for-in.
+MaybeHandle<HeapObject> Enumerate(Handle<JSReceiver> receiver) {
+ Isolate* const isolate = receiver->GetIsolate();
+ // Test if we have an enum cache for {receiver}.
+ if (!receiver->IsSimpleEnum()) {
+ Handle<FixedArray> keys;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, keys, JSReceiver::GetKeys(receiver, JSReceiver::INCLUDE_PROTOS,
+ ENUMERABLE_STRINGS),
+ HeapObject);
+ // Test again, since cache may have been built by GetKeys() calls above.
+ if (!receiver->IsSimpleEnum()) return keys;
+ }
+ return handle(receiver->map(), isolate);
+}
+
+
+MaybeHandle<Object> Filter(Handle<JSReceiver> receiver, Handle<Object> key) {
+ Isolate* const isolate = receiver->GetIsolate();
+ // TODO(turbofan): Fast case for array indices.
+ Handle<Name> name;
+ ASSIGN_RETURN_ON_EXCEPTION(isolate, name, Object::ToName(isolate, key),
+ Object);
+ Maybe<bool> result = JSReceiver::HasProperty(receiver, name);
+ MAYBE_RETURN_NULL(result);
+ if (result.FromJust()) return name;
+ return isolate->factory()->undefined_value();
+}
+
+} // namespace
+
+
+RUNTIME_FUNCTION(Runtime_ForInEnumerate) {
HandleScope scope(isolate);
DCHECK_EQ(1, args.length());
+ CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
+ Handle<HeapObject> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, Enumerate(receiver));
+ return *result;
+}
- if (!args[0]->IsJSReceiver()) {
- return MakeTriple(isolate->ThrowIllegalOperation(), nullptr, nullptr);
- }
- Handle<JSReceiver> receiver = args.at<JSReceiver>(0);
- Object* property_names = Runtime_GetPropertyNamesFast(
- 1, Handle<Object>::cast(receiver).location(), isolate);
- if (isolate->has_pending_exception()) {
- return MakeTriple(property_names, nullptr, nullptr);
+RUNTIME_FUNCTION_RETURN_TRIPLE(Runtime_ForInPrepare) {
+ HandleScope scope(isolate);
+ DCHECK_EQ(1, args.length());
+ Handle<JSReceiver> receiver = args.at<JSReceiver>(0);
+ Handle<Object> cache_type;
+ if (!Enumerate(receiver).ToHandle(&cache_type)) {
+ return MakeTriple(isolate->heap()->exception(), nullptr, nullptr);
}
-
- Handle<Object> cache_type(property_names, isolate);
Handle<FixedArray> cache_array;
int cache_length;
-
if (cache_type->IsMap()) {
- Handle<Map> cache_type_map = Handle<Map>::cast(cache_type);
- int const enum_length = cache_type_map->EnumLength();
- DescriptorArray* descriptors = cache_type_map->instance_descriptors();
- if (enum_length && descriptors->HasEnumCache()) {
+ Handle<Map> cache_map = Handle<Map>::cast(cache_type);
+ Handle<DescriptorArray> descriptors(cache_map->instance_descriptors(),
+ isolate);
+ cache_length = cache_map->EnumLength();
+ if (cache_length && descriptors->HasEnumCache()) {
cache_array = handle(descriptors->GetEnumCache(), isolate);
- cache_length = enum_length;
} else {
cache_array = isolate->factory()->empty_fixed_array();
cache_length = 0;
@@ -45,10 +83,8 @@ RUNTIME_FUNCTION_RETURN_TRIPLE(Runtime_ForInPrepare) {
} else {
cache_array = Handle<FixedArray>::cast(cache_type);
cache_length = cache_array->length();
- // Cache type of SMI one entails slow check.
- cache_type = Handle<Object>(Smi::FromInt(1), isolate);
+ cache_type = handle(Smi::FromInt(1), isolate);
}
-
return MakeTriple(*cache_type, *cache_array, Smi::FromInt(cache_length));
}
@@ -69,15 +105,9 @@ RUNTIME_FUNCTION(Runtime_ForInFilter) {
DCHECK_EQ(2, args.length());
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
- // TODO(turbofan): Fast case for array indices.
- Handle<Name> name;
- if (!Object::ToName(isolate, key).ToHandle(&name)) {
- return isolate->heap()->exception();
- }
- Maybe<bool> result = JSReceiver::HasProperty(receiver, name);
- if (!result.IsJust()) return isolate->heap()->exception();
- if (result.FromJust()) return *name;
- return isolate->heap()->undefined_value();
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, Filter(receiver, key));
+ return *result;
}
@@ -89,20 +119,13 @@ RUNTIME_FUNCTION(Runtime_ForInNext) {
CONVERT_ARG_HANDLE_CHECKED(Object, cache_type, 2);
CONVERT_SMI_ARG_CHECKED(index, 3);
Handle<Object> key = handle(cache_array->get(index), isolate);
- // Don't need filtering if expected map still matches that of the receiver,
- // and neither for proxies.
- if (receiver->map() == *cache_type || *cache_type == Smi::FromInt(0)) {
+ // Don't need filtering if expected map still matches that of the receiver.
+ if (receiver->map() == *cache_type) {
return *key;
}
- // TODO(turbofan): Fast case for array indices.
- Handle<Name> name;
- if (!Object::ToName(isolate, key).ToHandle(&name)) {
- return isolate->heap()->exception();
- }
- Maybe<bool> result = JSReceiver::HasProperty(receiver, name);
- if (!result.IsJust()) return isolate->heap()->exception();
- if (result.FromJust()) return *name;
- return isolate->heap()->undefined_value();
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, Filter(receiver, key));
+ return *result;
}
« no previous file with comments | « src/runtime/runtime.h ('k') | src/runtime/runtime-object.cc » ('j') | src/types.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698