Revision: 10926
Author:   [email protected]
Date:     Mon Mar  5 08:14:34 2012
Log:      Recfactor core HasElement functionality into ElementsAccessors

Review URL: https://chromiumcodereview.appspot.com/9572014
http://code.google.com/p/v8/source/detail?r=10926

Modified:
 /branches/bleeding_edge/src/elements.cc
 /branches/bleeding_edge/src/elements.h
 /branches/bleeding_edge/src/objects.cc
 /branches/bleeding_edge/src/objects.h

=======================================
--- /branches/bleeding_edge/src/elements.cc     Fri Feb 24 06:34:01 2012
+++ /branches/bleeding_edge/src/elements.cc     Mon Mar  5 08:14:34 2012
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -173,12 +173,12 @@
     if (len1 == 0) return to;

     // Compute how many elements are not in other.
-    int extra = 0;
+    uint32_t extra = 0;
     for (uint32_t y = 0; y < len1; y++) {
-      if (ElementsAccessorSubclass::HasElementAtIndexImpl(
-          backing_store, y, holder, receiver)) {
-        uint32_t key =
-            ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, y);
+      uint32_t key =
+          ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, y);
+      if (ElementsAccessorSubclass::HasElementImpl(
+              backing_store, key, holder, receiver)) {
         MaybeObject* maybe_value =
             ElementsAccessorSubclass::GetImpl(backing_store, key,
                                               holder, receiver);
@@ -210,12 +210,12 @@
       }
     }
     // Fill in the extra values.
-    int index = 0;
+    uint32_t index = 0;
     for (uint32_t y = 0; y < len1; y++) {
-      if (ElementsAccessorSubclass::HasElementAtIndexImpl(
-          backing_store, y, holder, receiver)) {
-        uint32_t key =
-            ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, y);
+      uint32_t key =
+          ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, y);
+      if (ElementsAccessorSubclass::HasElementImpl(
+          backing_store, key, holder, receiver)) {
         MaybeObject* maybe_value =
             ElementsAccessorSubclass::GetImpl(backing_store, key,
                                               holder, receiver);
@@ -241,23 +241,21 @@
         BackingStoreClass::cast(backing_store));
   }

-  static bool HasElementAtIndexImpl(BackingStoreClass* backing_store,
-                                    uint32_t index,
-                                    JSObject* holder,
-                                    Object* receiver) {
-    uint32_t key =
-        ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, index);
+  static bool HasElementImpl(BackingStoreClass* backing_store,
+                             uint32_t key,
+                             JSObject* holder,
+                             Object* receiver) {
     MaybeObject* element =
ElementsAccessorSubclass::GetImpl(backing_store, key, holder, receiver);
     return !element->IsTheHole();
   }

-  virtual bool HasElementAtIndex(FixedArrayBase* backing_store,
-                                 uint32_t index,
-                                 JSObject* holder,
-                                 Object* receiver) {
-    return ElementsAccessorSubclass::HasElementAtIndexImpl(
-        BackingStoreClass::cast(backing_store), index, holder, receiver);
+  virtual bool HasElement(FixedArrayBase* backing_store,
+                          uint32_t key,
+                          JSObject* holder,
+                          Object* receiver) {
+    return ElementsAccessorSubclass::HasElementImpl(
+        BackingStoreClass::cast(backing_store), key, holder, receiver);
   }

   static uint32_t GetKeyForIndexImpl(BackingStoreClass* backing_store,
@@ -266,7 +264,7 @@
   }

   virtual uint32_t GetKeyForIndex(FixedArrayBase* backing_store,
-                                              uint32_t index) {
+                                  uint32_t index) {
     return ElementsAccessorSubclass::GetKeyForIndexImpl(
         BackingStoreClass::cast(backing_store), index);
   }
@@ -441,11 +439,11 @@
     return obj->GetHeap()->true_value();
   }

-  static bool HasElementAtIndexImpl(FixedDoubleArray* backing_store,
-                                    uint32_t index,
-                                    JSObject* holder,
-                                    Object* receiver) {
-    return !backing_store->is_the_hole(index);
+  static bool HasElementImpl(FixedDoubleArray* backing_store,
+                             uint32_t key,
+                             JSObject* holder,
+                             Object* receiver) {
+    return !backing_store->is_the_hole(key);
   }
 };

@@ -484,6 +482,15 @@
     // External arrays always ignore deletes.
     return obj->GetHeap()->true_value();
   }
+
+  static bool HasElementImpl(ExternalArray* backing_store,
+                             uint32_t key,
+                             JSObject* holder,
+                             Object* receiver) {
+    uint32_t capacity =
+        ExternalElementsAccessorSubclass::GetCapacityImpl(backing_store);
+    return key < capacity;
+  }
 };


@@ -676,6 +683,14 @@
     }
     return obj->GetHeap()->the_hole_value();
   }
+
+  static bool HasElementImpl(SeededNumberDictionary* backing_store,
+                             uint32_t key,
+                             JSObject* holder,
+                             Object* receiver) {
+    return backing_store->FindEntry(key) !=
+        SeededNumberDictionary::kNotFound;
+  }

   static uint32_t GetKeyForIndexImpl(SeededNumberDictionary* dict,
                                      uint32_t index) {
@@ -696,7 +711,7 @@
                               uint32_t key,
                               JSObject* obj,
                               Object* receiver) {
-    Object* probe = GetParameterMapArg(parameter_map, key);
+    Object* probe = GetParameterMapArg(obj, parameter_map, key);
     if (!probe->IsTheHole()) {
       Context* context = Context::cast(parameter_map->get(0));
       int context_index = Smi::cast(probe)->value();
@@ -735,7 +750,7 @@
                               uint32_t key,
                               JSReceiver::DeleteMode mode) {
     FixedArray* parameter_map = FixedArray::cast(obj->elements());
-    Object* probe = GetParameterMapArg(parameter_map, key);
+    Object* probe = GetParameterMapArg(obj, parameter_map, key);
     if (!probe->IsTheHole()) {
       // TODO(kmillikin): We could check if this was the last aliased
       // parameter, and revert to normal elements in that case.  That
@@ -763,24 +778,27 @@
     return index;
   }

-  static bool HasElementAtIndexImpl(FixedArray* parameter_map,
-                                    uint32_t index,
-                                    JSObject* holder,
-                                    Object* receiver) {
-    Object* probe = GetParameterMapArg(parameter_map, index);
+  static bool HasElementImpl(FixedArray* parameter_map,
+                             uint32_t key,
+                             JSObject* holder,
+                             Object* receiver) {
+    Object* probe = GetParameterMapArg(holder, parameter_map, key);
     if (!probe->IsTheHole()) {
       return true;
     } else {
FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1));
       ElementsAccessor* accessor = ElementsAccessor::ForArray(arguments);
- return !accessor->Get(arguments, index, holder, receiver)->IsTheHole();
+      return !accessor->Get(arguments, key, holder, receiver)->IsTheHole();
     }
   }

  private:
-  static Object* GetParameterMapArg(FixedArray* parameter_map,
+  static Object* GetParameterMapArg(JSObject* holder,
+                                    FixedArray* parameter_map,
                                     uint32_t key) {
-    uint32_t length = parameter_map->length();
+    uint32_t length = holder->IsJSArray()
+        ? Smi::cast(JSArray::cast(holder)->length())->value()
+        : parameter_map->length();
     return key < (length - 2 )
         ? parameter_map->get(key + 2)
         : parameter_map->GetHeap()->the_hole_value();
=======================================
--- /branches/bleeding_edge/src/elements.h      Fri Dec  9 00:50:19 2011
+++ /branches/bleeding_edge/src/elements.h      Mon Mar  5 08:14:34 2012
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -66,6 +66,11 @@
                               uint32_t key,
                               JSReceiver::DeleteMode mode) = 0;

+  virtual bool HasElement(FixedArrayBase* backing_store,
+                          uint32_t key,
+                          JSObject* holder,
+                          Object* receiver) = 0;
+
   virtual MaybeObject* AddElementsToFixedArray(FixedArrayBase* from,
                                                FixedArray* to,
                                                JSObject* holder,
@@ -86,19 +91,14 @@

   virtual uint32_t GetCapacity(FixedArrayBase* backing_store) = 0;

-  virtual bool HasElementAtIndex(FixedArrayBase* backing_store,
-                                 uint32_t index,
-                                 JSObject* holder,
-                                 Object* receiver) = 0;
-
- // Element handlers distinguish between indexes and keys when the manipulate + // Element handlers distinguish between indexes and keys when they manipulate
   // elements.  Indexes refer to elements in terms of their location in the
-  // underlying storage's backing store representation, and are between 0
+ // underlying storage's backing store representation, and are between 0 and // GetCapacity. Keys refer to elements in terms of the value that would be - // specific in JavaScript to access the element. In most implementations, keys - // are equivalent to indexes, and GetKeyForIndex returns the same value it is - // passed. In the NumberDictionary ElementsAccessor, GetKeyForIndex maps the
-  // index to a key using the KeyAt method on the NumberDictionary.
+ // specified in JavaScript to access the element. In most implementations, + // keys are equivalent to indexes, and GetKeyForIndex returns the same value + // it is passed. In the NumberDictionary ElementsAccessor, GetKeyForIndex maps
+  // the index to a key using the KeyAt method on the NumberDictionary.
   virtual uint32_t GetKeyForIndex(FixedArrayBase* backing_store,
                                   uint32_t index) = 0;

=======================================
--- /branches/bleeding_edge/src/objects.cc      Mon Mar  5 04:11:28 2012
+++ /branches/bleeding_edge/src/objects.cc      Mon Mar  5 08:14:34 2012
@@ -8915,78 +8915,6 @@
       args->arguments() - first_arg - (arg_count - 1),
       arg_count, mode);
 }
-
-
-bool JSObject::HasElementPostInterceptor(JSReceiver* receiver, uint32_t index) {
-  switch (GetElementsKind()) {
-    case FAST_SMI_ONLY_ELEMENTS:
-    case FAST_ELEMENTS: {
-      uint32_t length = IsJSArray() ?
-          static_cast<uint32_t>
-              (Smi::cast(JSArray::cast(this)->length())->value()) :
-          static_cast<uint32_t>(FixedArray::cast(elements())->length());
-      if ((index < length) &&
-          !FixedArray::cast(elements())->get(index)->IsTheHole()) {
-        return true;
-      }
-      break;
-    }
-    case FAST_DOUBLE_ELEMENTS: {
-      uint32_t length = IsJSArray() ?
-          static_cast<uint32_t>
-              (Smi::cast(JSArray::cast(this)->length())->value()) :
- static_cast<uint32_t>(FixedDoubleArray::cast(elements())->length());
-      if ((index < length) &&
-          !FixedDoubleArray::cast(elements())->is_the_hole(index)) {
-        return true;
-      }
-      break;
-    }
-    case EXTERNAL_PIXEL_ELEMENTS: {
-      ExternalPixelArray* pixels = ExternalPixelArray::cast(elements());
-      if (index < static_cast<uint32_t>(pixels->length())) {
-        return true;
-      }
-      break;
-    }
-    case EXTERNAL_BYTE_ELEMENTS:
-    case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
-    case EXTERNAL_SHORT_ELEMENTS:
-    case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
-    case EXTERNAL_INT_ELEMENTS:
-    case EXTERNAL_UNSIGNED_INT_ELEMENTS:
-    case EXTERNAL_FLOAT_ELEMENTS:
-    case EXTERNAL_DOUBLE_ELEMENTS: {
-      ExternalArray* array = ExternalArray::cast(elements());
-      if (index < static_cast<uint32_t>(array->length())) {
-        return true;
-      }
-      break;
-    }
-    case DICTIONARY_ELEMENTS: {
-      if (element_dictionary()->FindEntry(index)
-          != SeededNumberDictionary::kNotFound) {
-        return true;
-      }
-      break;
-    }
-    case NON_STRICT_ARGUMENTS_ELEMENTS:
-      UNREACHABLE();
-      break;
-  }
-
-  // Handle [] on String objects.
-  if (this->IsStringObjectWithCharacterAt(index)) return true;
-
-  Object* pt = GetPrototype();
-  if (pt->IsNull()) return false;
-  if (pt->IsJSProxy()) {
- // We need to follow the spec and simulate a call to [[GetOwnProperty]].
-    return JSProxy::cast(pt)->GetElementAttributeWithHandler(
-        receiver, index) != ABSENT;
-  }
-  return JSObject::cast(pt)->HasElementWithReceiver(receiver, index);
-}


bool JSObject::HasElementWithInterceptor(JSReceiver* receiver, uint32_t index) {
@@ -9028,7 +8956,21 @@
     }
     if (!result.IsEmpty()) return true;
   }
-  return holder_handle->HasElementPostInterceptor(*receiver_handle, index);
+
+  if (holder_handle->GetElementsAccessor()->HasElement(
+ holder_handle->elements(), index, *holder_handle, *receiver_handle)) {
+    return true;
+  }
+
+  if (holder_handle->IsStringObjectWithCharacterAt(index)) return true;
+  Object* pt = holder_handle->GetPrototype();
+  if (pt->IsJSProxy()) {
+ // We need to follow the spec and simulate a call to [[GetOwnProperty]].
+    return JSProxy::cast(pt)->GetElementAttributeWithHandler(
+        receiver, index) != ABSENT;
+  }
+  if (pt->IsNull()) return false;
+ return JSObject::cast(pt)->HasElementWithReceiver(*receiver_handle, index);
 }


@@ -9136,28 +9078,6 @@

   return UNDEFINED_ELEMENT;
 }
-
-
-bool JSObject::HasElementInElements(FixedArray* elements,
-                                    ElementsKind kind,
-                                    uint32_t index) {
-  ASSERT(kind == FAST_ELEMENTS || kind == DICTIONARY_ELEMENTS);
-  if (kind == FAST_ELEMENTS) {
-    int length = IsJSArray()
-        ? Smi::cast(JSArray::cast(this)->length())->value()
-        : elements->length();
-    if (index < static_cast<uint32_t>(length) &&
-        !elements->get(index)->IsTheHole()) {
-      return true;
-    }
-  } else {
-    if (SeededNumberDictionary::cast(elements)->FindEntry(index) !=
-        SeededNumberDictionary::kNotFound) {
-      return true;
-    }
-  }
-  return false;
-}


bool JSObject::HasElementWithReceiver(JSReceiver* receiver, uint32_t index) {
@@ -9175,68 +9095,9 @@
     return HasElementWithInterceptor(receiver, index);
   }

-  ElementsKind kind = GetElementsKind();
-  switch (kind) {
-    case FAST_SMI_ONLY_ELEMENTS:
-    case FAST_ELEMENTS: {
-      uint32_t length = IsJSArray() ?
-          static_cast<uint32_t>
-              (Smi::cast(JSArray::cast(this)->length())->value()) :
-          static_cast<uint32_t>(FixedArray::cast(elements())->length());
-      if ((index < length) &&
- !FixedArray::cast(elements())->get(index)->IsTheHole()) return true;
-      break;
-    }
-    case FAST_DOUBLE_ELEMENTS: {
-      uint32_t length = IsJSArray() ?
-          static_cast<uint32_t>
-              (Smi::cast(JSArray::cast(this)->length())->value()) :
- static_cast<uint32_t>(FixedDoubleArray::cast(elements())->length());
-      if ((index < length) &&
- !FixedDoubleArray::cast(elements())->is_the_hole(index)) return true;
-      break;
-    }
-    case EXTERNAL_PIXEL_ELEMENTS: {
-      ExternalPixelArray* pixels = ExternalPixelArray::cast(elements());
-      if (index < static_cast<uint32_t>(pixels->length())) {
-        return true;
-      }
-      break;
-    }
-    case EXTERNAL_BYTE_ELEMENTS:
-    case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
-    case EXTERNAL_SHORT_ELEMENTS:
-    case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
-    case EXTERNAL_INT_ELEMENTS:
-    case EXTERNAL_UNSIGNED_INT_ELEMENTS:
-    case EXTERNAL_FLOAT_ELEMENTS:
-    case EXTERNAL_DOUBLE_ELEMENTS: {
-      ExternalArray* array = ExternalArray::cast(elements());
-      if (index < static_cast<uint32_t>(array->length())) {
-        return true;
-      }
-      break;
-    }
-    case DICTIONARY_ELEMENTS: {
-      if (element_dictionary()->FindEntry(index)
-          != SeededNumberDictionary::kNotFound) {
-        return true;
-      }
-      break;
-    }
-    case NON_STRICT_ARGUMENTS_ELEMENTS: {
-      FixedArray* parameter_map = FixedArray::cast(elements());
-      uint32_t length = parameter_map->length();
-      Object* probe =
-          (index < length - 2) ? parameter_map->get(index + 2) : NULL;
-      if (probe != NULL && !probe->IsTheHole()) return true;
-
-      // Not a mapped parameter, check the arguments.
-      FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
- kind = arguments->IsDictionary() ? DICTIONARY_ELEMENTS : FAST_ELEMENTS;
-      if (HasElementInElements(arguments, kind, index)) return true;
-      break;
-    }
+  ElementsAccessor* accessor = GetElementsAccessor();
+  if (accessor->HasElement(elements(), index, this, receiver)) {
+    return true;
   }

   // Handle [] on String objects.
=======================================
--- /branches/bleeding_edge/src/objects.h       Mon Mar  5 04:11:28 2012
+++ /branches/bleeding_edge/src/objects.h       Mon Mar  5 08:14:34 2012
@@ -1752,7 +1752,6 @@
   LocalElementType HasLocalElement(uint32_t index);

   bool HasElementWithInterceptor(JSReceiver* receiver, uint32_t index);
-  bool HasElementPostInterceptor(JSReceiver* receiver, uint32_t index);

   MUST_USE_RESULT MaybeObject* SetFastElement(uint32_t index,
                                               Object* value,
@@ -2152,9 +2151,6 @@
   bool ReferencesObjectFromElements(FixedArray* elements,
                                     ElementsKind kind,
                                     Object* object);
-  bool HasElementInElements(FixedArray* elements,
-                            ElementsKind kind,
-                            uint32_t index);

   // Returns true if most of the elements backing storage is used.
   bool HasDenseElements();

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to