LCOV - code coverage report
Current view: top level - src - elements.h (source / functions) Hit Total Coverage
Test: app.info Lines: 10 11 90.9 %
Date: 2017-04-26 Functions: 3 5 60.0 %

          Line data    Source code
       1             : // Copyright 2012 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #ifndef V8_ELEMENTS_H_
       6             : #define V8_ELEMENTS_H_
       7             : 
       8             : #include "src/elements-kind.h"
       9             : #include "src/isolate.h"
      10             : #include "src/keys.h"
      11             : #include "src/objects.h"
      12             : 
      13             : namespace v8 {
      14             : namespace internal {
      15             : 
      16             : // Abstract base class for handles that can operate on objects with differing
      17             : // ElementsKinds.
      18             : class ElementsAccessor {
      19             :  public:
      20     1189220 :   explicit ElementsAccessor(const char* name) : name_(name) { }
      21      648960 :   virtual ~ElementsAccessor() { }
      22             : 
      23             :   const char* name() const { return name_; }
      24             : 
      25             :   // Returns a shared ElementsAccessor for the specified ElementsKind.
      26         321 :   static ElementsAccessor* ForKind(ElementsKind elements_kind) {
      27             :     DCHECK(static_cast<int>(elements_kind) < kElementsKindCount);
      28   515688109 :     return elements_accessors_[elements_kind];
      29             :   }
      30             : 
      31             :   // Checks the elements of an object for consistency, asserting when a problem
      32             :   // is found.
      33             :   virtual void Validate(Handle<JSObject> obj) = 0;
      34             : 
      35             :   // Returns true if a holder contains an element with the specified index
      36             :   // without iterating up the prototype chain.  The caller can optionally pass
      37             :   // in the backing store to use for the check, which must be compatible with
      38             :   // the ElementsKind of the ElementsAccessor. If backing_store is NULL, the
      39             :   // holder->elements() is used as the backing store. If a |filter| is
      40             :   // specified the PropertyAttributes of the element at the given index
      41             :   // are compared to the given |filter|. If they match/overlap the given
      42             :   // index is ignored. Note that only Dictionary elements have custom
      43             :   // PropertyAttributes associated, hence the |filter| argument is ignored for
      44             :   // all but DICTIONARY_ELEMENTS and SLOW_SLOPPY_ARGUMENTS_ELEMENTS.
      45             :   virtual bool HasElement(JSObject* holder, uint32_t index,
      46             :                           FixedArrayBase* backing_store,
      47             :                           PropertyFilter filter = ALL_PROPERTIES) = 0;
      48             : 
      49             :   inline bool HasElement(JSObject* holder, uint32_t index,
      50             :                          PropertyFilter filter = ALL_PROPERTIES) {
      51           0 :     return HasElement(holder, index, holder->elements(), filter);
      52             :   }
      53             : 
      54             :   virtual Handle<Object> Get(Handle<JSObject> holder, uint32_t entry) = 0;
      55             : 
      56             :   virtual PropertyDetails GetDetails(JSObject* holder, uint32_t entry) = 0;
      57             :   virtual bool HasAccessors(JSObject* holder) = 0;
      58             :   virtual uint32_t NumberOfElements(JSObject* holder) = 0;
      59             : 
      60             :   // Modifies the length data property as specified for JSArrays and resizes the
      61             :   // underlying backing store accordingly. The method honors the semantics of
      62             :   // changing array sizes as defined in EcmaScript 5.1 15.4.5.2, i.e. array that
      63             :   // have non-deletable elements can only be shrunk to the size of highest
      64             :   // element that is non-deletable.
      65             :   virtual void SetLength(Handle<JSArray> holder, uint32_t new_length) = 0;
      66             : 
      67             :   // Deletes an element in an object.
      68             :   virtual void Delete(Handle<JSObject> holder, uint32_t entry) = 0;
      69             : 
      70             :   // If kCopyToEnd is specified as the copy_size to CopyElements, it copies all
      71             :   // of elements from source after source_start to the destination array.
      72             :   static const int kCopyToEnd = -1;
      73             :   // If kCopyToEndAndInitializeToHole is specified as the copy_size to
      74             :   // CopyElements, it copies all of elements from source after source_start to
      75             :   // destination array, padding any remaining uninitialized elements in the
      76             :   // destination array with the hole.
      77             :   static const int kCopyToEndAndInitializeToHole = -2;
      78             : 
      79             :   // Copy all indices that have elements from |object| into the given
      80             :   // KeyAccumulator. For Dictionary-based element-kinds we filter out elements
      81             :   // whose PropertyAttribute match |filter|.
      82             :   virtual void CollectElementIndices(Handle<JSObject> object,
      83             :                                      Handle<FixedArrayBase> backing_store,
      84             :                                      KeyAccumulator* keys) = 0;
      85             : 
      86    15169890 :   inline void CollectElementIndices(Handle<JSObject> object,
      87    15169890 :                                     KeyAccumulator* keys) {
      88             :     CollectElementIndices(object, handle(object->elements(), keys->isolate()),
      89    30339780 :                           keys);
      90    15169890 :   }
      91             : 
      92             :   virtual Maybe<bool> CollectValuesOrEntries(
      93             :       Isolate* isolate, Handle<JSObject> object,
      94             :       Handle<FixedArray> values_or_entries, bool get_entries, int* nof_items,
      95             :       PropertyFilter filter = ALL_PROPERTIES) = 0;
      96             : 
      97             :   virtual MaybeHandle<FixedArray> PrependElementIndices(
      98             :       Handle<JSObject> object, Handle<FixedArrayBase> backing_store,
      99             :       Handle<FixedArray> keys, GetKeysConversion convert,
     100             :       PropertyFilter filter = ALL_PROPERTIES) = 0;
     101             : 
     102     1488371 :   inline MaybeHandle<FixedArray> PrependElementIndices(
     103             :       Handle<JSObject> object, Handle<FixedArray> keys,
     104             :       GetKeysConversion convert, PropertyFilter filter = ALL_PROPERTIES) {
     105             :     return PrependElementIndices(object, handle(object->elements()), keys,
     106     2976742 :                                  convert, filter);
     107             :   }
     108             : 
     109             :   virtual void AddElementsToKeyAccumulator(Handle<JSObject> receiver,
     110             :                                            KeyAccumulator* accumulator,
     111             :                                            AddKeyConversion convert) = 0;
     112             : 
     113             :   virtual void TransitionElementsKind(Handle<JSObject> object,
     114             :                                       Handle<Map> map) = 0;
     115             :   virtual void GrowCapacityAndConvert(Handle<JSObject> object,
     116             :                                       uint32_t capacity) = 0;
     117             :   // Unlike GrowCapacityAndConvert do not attempt to convert the backing store
     118             :   // and simply return false in this case.
     119             :   virtual bool GrowCapacity(Handle<JSObject> object, uint32_t index) = 0;
     120             : 
     121             :   static void InitializeOncePerProcess();
     122             :   static void TearDown();
     123             : 
     124             :   virtual void Set(Handle<JSObject> holder, uint32_t entry, Object* value) = 0;
     125             : 
     126             :   virtual void Reconfigure(Handle<JSObject> object,
     127             :                            Handle<FixedArrayBase> backing_store, uint32_t entry,
     128             :                            Handle<Object> value,
     129             :                            PropertyAttributes attributes) = 0;
     130             : 
     131             :   virtual void Add(Handle<JSObject> object, uint32_t index,
     132             :                    Handle<Object> value, PropertyAttributes attributes,
     133             :                    uint32_t new_capacity) = 0;
     134             : 
     135             :   static Handle<JSArray> Concat(Isolate* isolate, Arguments* args,
     136             :                                 uint32_t concat_size, uint32_t result_length);
     137             : 
     138             :   virtual uint32_t Push(Handle<JSArray> receiver, Arguments* args,
     139             :                         uint32_t push_size) = 0;
     140             : 
     141             :   virtual uint32_t Unshift(Handle<JSArray> receiver,
     142             :                            Arguments* args, uint32_t unshift_size) = 0;
     143             : 
     144             :   virtual Handle<JSObject> Slice(Handle<JSObject> receiver, uint32_t start,
     145             :                                  uint32_t end) = 0;
     146             : 
     147             :   virtual Handle<JSObject> Slice(Handle<JSObject> receiver, uint32_t start,
     148             :                                  uint32_t end, Handle<JSObject> result) = 0;
     149             : 
     150             :   virtual Handle<JSArray> Splice(Handle<JSArray> receiver,
     151             :                                  uint32_t start, uint32_t delete_count,
     152             :                                  Arguments* args, uint32_t add_count) = 0;
     153             : 
     154             :   virtual Handle<Object> Pop(Handle<JSArray> receiver) = 0;
     155             : 
     156             :   virtual Handle<Object> Shift(Handle<JSArray> receiver) = 0;
     157             : 
     158             :   virtual Handle<SeededNumberDictionary> Normalize(Handle<JSObject> object) = 0;
     159             : 
     160             :   virtual uint32_t GetCapacity(JSObject* holder,
     161             :                                FixedArrayBase* backing_store) = 0;
     162             : 
     163             :   virtual Object* Fill(Isolate* isolate, Handle<JSObject> receiver,
     164             :                        Handle<Object> obj_value, uint32_t start,
     165             :                        uint32_t end) = 0;
     166             : 
     167             :   // Check an Object's own elements for an element (using SameValueZero
     168             :   // semantics)
     169             :   virtual Maybe<bool> IncludesValue(Isolate* isolate, Handle<JSObject> receiver,
     170             :                                     Handle<Object> value, uint32_t start,
     171             :                                     uint32_t length) = 0;
     172             : 
     173             :   // Check an Object's own elements for the index of an element (using SameValue
     174             :   // semantics)
     175             :   virtual Maybe<int64_t> IndexOfValue(Isolate* isolate,
     176             :                                       Handle<JSObject> receiver,
     177             :                                       Handle<Object> value, uint32_t start,
     178             :                                       uint32_t length) = 0;
     179             : 
     180             :   virtual Maybe<int64_t> LastIndexOfValue(Isolate* isolate,
     181             :                                           Handle<JSObject> receiver,
     182             :                                           Handle<Object> value,
     183             :                                           uint32_t start) = 0;
     184             : 
     185             :   virtual void Reverse(JSObject* receiver) = 0;
     186             : 
     187             :   virtual void CopyElements(Handle<FixedArrayBase> source,
     188             :                             ElementsKind source_kind,
     189             :                             Handle<FixedArrayBase> destination, int size) = 0;
     190             : 
     191             :   virtual Object* CopyElements(Handle<JSReceiver> source,
     192             :                                Handle<JSObject> destination, size_t length) = 0;
     193             : 
     194             :   virtual Handle<FixedArray> CreateListFromArray(Isolate* isolate,
     195             :                                                  Handle<JSArray> array) = 0;
     196             : 
     197             :  protected:
     198             :   friend class LookupIterator;
     199             : 
     200             :   // Element handlers distinguish between entries and indices when they
     201             :   // manipulate elements. Entries refer to elements in terms of their location
     202             :   // in the underlying storage's backing store representation, and are between 0
     203             :   // and GetCapacity. Indices refer to elements in terms of the value that would
     204             :   // be specified in JavaScript to access the element. In most implementations,
     205             :   // indices are equivalent to entries. In the NumberDictionary
     206             :   // ElementsAccessor, entries are mapped to an index using the KeyAt method on
     207             :   // the NumberDictionary.
     208             :   virtual uint32_t GetEntryForIndex(Isolate* isolate, JSObject* holder,
     209             :                                     FixedArrayBase* backing_store,
     210             :                                     uint32_t index) = 0;
     211             : 
     212             :   // NOTE: this method violates the handlified function signature convention:
     213             :   // raw pointer parameter |source_holder| in the function that allocates.
     214             :   // This is done intentionally to avoid ArrayConcat() builtin performance
     215             :   // degradation.
     216             :   virtual void CopyElements(JSObject* source_holder, uint32_t source_start,
     217             :                             ElementsKind source_kind,
     218             :                             Handle<FixedArrayBase> destination,
     219             :                             uint32_t destination_start, int copy_size) = 0;
     220             : 
     221             :  private:
     222             :   static ElementsAccessor** elements_accessors_;
     223             :   const char* name_;
     224             : 
     225             :   DISALLOW_COPY_AND_ASSIGN(ElementsAccessor);
     226             : };
     227             : 
     228             : void CheckArrayAbuse(Handle<JSObject> obj, const char* op, uint32_t index,
     229             :                      bool allow_appending = false);
     230             : 
     231             : MUST_USE_RESULT MaybeHandle<Object> ArrayConstructInitializeElements(
     232             :     Handle<JSArray> array,
     233             :     Arguments* args);
     234             : 
     235             : }  // namespace internal
     236             : }  // namespace v8
     237             : 
     238             : #endif  // V8_ELEMENTS_H_

Generated by: LCOV version 1.10