~ubuntu-branches/ubuntu/saucy/libv8/saucy

« back to all changes in this revision

Viewing changes to src/objects.h

  • Committer: Package Import Robot
  • Author(s): Jérémy Lal
  • Date: 2012-04-07 16:26:13 UTC
  • mfrom: (15.1.27 sid)
  • Revision ID: package-import@ubuntu.com-20120407162613-dqo1m6w9r3fh8tst
Tags: 3.8.9.16-3
* mipsel build fixes :
  + v8_use_mips_abi_hardfloat=false, this lowers EABI requirements.
  + v8_can_use_fpu_instructions=false, detect if FPU is present.
  + set -Wno-unused-but-set-variable only on mipsel.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// Copyright 2011 the V8 project authors. All rights reserved.
 
1
// Copyright 2012 the V8 project authors. All rights reserved.
2
2
// Redistribution and use in source and binary forms, with or without
3
3
// modification, are permitted provided that the following conditions are
4
4
// met:
107
107
//       - SharedFunctionInfo
108
108
//       - Struct
109
109
//         - AccessorInfo
 
110
//         - AccessorPair
110
111
//         - AccessCheckInfo
111
112
//         - InterceptorInfo
112
113
//         - CallHandlerInfo
162
163
  LAST_ELEMENTS_KIND = EXTERNAL_PIXEL_ELEMENTS
163
164
};
164
165
 
 
166
enum CompareMapMode {
 
167
  REQUIRE_EXACT_MAP,
 
168
  ALLOW_ELEMENT_TRANSITION_MAPS
 
169
};
 
170
 
165
171
const int kElementsKindCount = LAST_ELEMENTS_KIND - FIRST_ELEMENTS_KIND + 1;
166
172
 
167
173
void PrintElementsKind(FILE* out, ElementsKind kind);
211
217
// encoding is considered TWO_BYTE.  It is not mentioned in the name.  ASCII
212
218
// encoding is mentioned explicitly in the name.  Likewise, the default
213
219
// representation is considered sequential.  It is not mentioned in the
214
 
// name.  The other representations (eg, CONS, EXTERNAL) are explicitly
 
220
// name.  The other representations (e.g. CONS, EXTERNAL) are explicitly
215
221
// mentioned.  Finally, the string is either a SYMBOL_TYPE (if it is a
216
222
// symbol) or a STRING_TYPE (if it is not a symbol).
217
223
//
270
276
  V(FILLER_TYPE)                                                               \
271
277
                                                                               \
272
278
  V(ACCESSOR_INFO_TYPE)                                                        \
 
279
  V(ACCESSOR_PAIR_TYPE)                                                        \
273
280
  V(ACCESS_CHECK_INFO_TYPE)                                                    \
274
281
  V(INTERCEPTOR_INFO_TYPE)                                                     \
275
282
  V(CALL_HANDLER_INFO_TYPE)                                                    \
417
424
// manually.
418
425
#define STRUCT_LIST_ALL(V)                                                     \
419
426
  V(ACCESSOR_INFO, AccessorInfo, accessor_info)                                \
 
427
  V(ACCESSOR_PAIR, AccessorPair, accessor_pair)                                \
420
428
  V(ACCESS_CHECK_INFO, AccessCheckInfo, access_check_info)                     \
421
429
  V(INTERCEPTOR_INFO, InterceptorInfo, interceptor_info)                       \
422
430
  V(CALL_HANDLER_INFO, CallHandlerInfo, call_handler_info)                     \
484
492
STATIC_ASSERT(IS_POWER_OF_TWO(kSlicedNotConsMask) && kSlicedNotConsMask != 0);
485
493
 
486
494
// If bit 7 is clear, then bit 3 indicates whether this two-byte
487
 
// string actually contains ascii data.
 
495
// string actually contains ASCII data.
488
496
const uint32_t kAsciiDataHintMask = 0x08;
489
497
const uint32_t kAsciiDataHintTag = 0x08;
490
498
 
570
578
 
571
579
  // Structs.
572
580
  ACCESSOR_INFO_TYPE,
 
581
  ACCESSOR_PAIR_TYPE,
573
582
  ACCESS_CHECK_INFO_TYPE,
574
583
  INTERCEPTOR_INFO_TYPE,
575
584
  CALL_HANDLER_INFO_TYPE,
996
1005
  void SmiVerify();
997
1006
#endif
998
1007
 
999
 
  static const int kMinValue = (-1 << (kSmiValueSize - 1));
 
1008
  static const int kMinValue =
 
1009
      (static_cast<unsigned int>(-1)) << (kSmiValueSize - 1);
1000
1010
  static const int kMaxValue = -(kMinValue + 1);
1001
1011
 
1002
1012
 private:
1077
1087
 
1078
1088
 
1079
1089
// Heap objects typically have a map pointer in their first word.  However,
1080
 
// during GC other data (eg, mark bits, forwarding addresses) is sometimes
 
1090
// during GC other data (e.g. mark bits, forwarding addresses) is sometimes
1081
1091
// encoded in the first word.  The class MapWord is an abstraction of the
1082
1092
// value in a heap object's first word.
1083
1093
class MapWord BASE_EMBEDDED {
1096
1106
 
1097
1107
  // True if this map word is a forwarding address for a scavenge
1098
1108
  // collection.  Only valid during a scavenge collection (specifically,
1099
 
  // when all map words are heap object pointers, ie. not during a full GC).
 
1109
  // when all map words are heap object pointers, i.e. not during a full GC).
1100
1110
  inline bool IsForwardingAddress();
1101
1111
 
1102
1112
  // Create a map word from a forwarding address.
1131
1141
  // information.
1132
1142
  inline Map* map();
1133
1143
  inline void set_map(Map* value);
1134
 
  inline void set_map_unsafe(Map* value);
 
1144
  // The no-write-barrier version.  This is OK if the object is white and in
 
1145
  // new space, or if the value is an immortal immutable object, like the maps
 
1146
  // of primitive (non-JS) objects like strings, heap numbers etc.
 
1147
  inline void set_map_no_write_barrier(Map* value);
1135
1148
 
1136
1149
  // During garbage collection, the map word of a heap object does not
1137
1150
  // necessarily contain a map pointer.
1319
1332
};
1320
1333
 
1321
1334
 
 
1335
enum EnsureElementsMode {
 
1336
  DONT_ALLOW_DOUBLE_ELEMENTS,
 
1337
  ALLOW_COPIED_DOUBLE_ELEMENTS,
 
1338
  ALLOW_CONVERTED_DOUBLE_ELEMENTS
 
1339
};
 
1340
 
 
1341
 
1322
1342
// JSReceiver includes types on which properties can be defined, i.e.,
1323
1343
// JSObject and JSProxy.
1324
1344
class JSReceiver: public HeapObject {
1332
1352
  // Casting.
1333
1353
  static inline JSReceiver* cast(Object* obj);
1334
1354
 
 
1355
  static Handle<Object> SetProperty(Handle<JSReceiver> object,
 
1356
                                    Handle<String> key,
 
1357
                                    Handle<Object> value,
 
1358
                                    PropertyAttributes attributes,
 
1359
                                    StrictModeFlag strict_mode);
1335
1360
  // Can cause GC.
1336
1361
  MUST_USE_RESULT MaybeObject* SetProperty(String* key,
1337
1362
                                           Object* value,
1461
1486
  inline bool HasExternalDoubleElements();
1462
1487
  bool HasFastArgumentsElements();
1463
1488
  bool HasDictionaryArgumentsElements();
1464
 
  inline bool AllowsSetElementsLength();
1465
 
  inline NumberDictionary* element_dictionary();  // Gets slow elements.
 
1489
  inline SeededNumberDictionary* element_dictionary();  // Gets slow elements.
 
1490
 
 
1491
  inline void set_map_and_elements(
 
1492
      Map* map,
 
1493
      FixedArrayBase* value,
 
1494
      WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
1466
1495
 
1467
1496
  // Requires: HasFastElements().
1468
1497
  MUST_USE_RESULT inline MaybeObject* EnsureWritableFastElements();
1507
1536
      Object* value,
1508
1537
      PropertyAttributes attributes,
1509
1538
      StrictModeFlag strict_mode);
 
1539
 
 
1540
  static Handle<Object> SetLocalPropertyIgnoreAttributes(
 
1541
      Handle<JSObject> object,
 
1542
      Handle<String> key,
 
1543
      Handle<Object> value,
 
1544
      PropertyAttributes attributes);
 
1545
 
 
1546
  // Can cause GC.
1510
1547
  MUST_USE_RESULT MaybeObject* SetLocalPropertyIgnoreAttributes(
1511
1548
      String* key,
1512
1549
      Object* value,
1522
1559
 
1523
1560
  // Sets the property value in a normalized object given (key, value, details).
1524
1561
  // Handles the special representation of JS global objects.
 
1562
  static Handle<Object> SetNormalizedProperty(Handle<JSObject> object,
 
1563
                                              Handle<String> key,
 
1564
                                              Handle<Object> value,
 
1565
                                              PropertyDetails details);
 
1566
 
1525
1567
  MUST_USE_RESULT MaybeObject* SetNormalizedProperty(String* name,
1526
1568
                                                     Object* value,
1527
1569
                                                     PropertyDetails details);
1591
1633
  // hidden properties.
1592
1634
 
1593
1635
  // Sets a hidden property on this object. Returns this object if successful,
1594
 
  // undefined if called on a detached proxy, and a failure if a GC
1595
 
  // is required
 
1636
  // undefined if called on a detached proxy.
 
1637
  static Handle<Object> SetHiddenProperty(Handle<JSObject> obj,
 
1638
                                          Handle<String> key,
 
1639
                                          Handle<Object> value);
 
1640
  // Returns a failure if a GC is required.
1596
1641
  MaybeObject* SetHiddenProperty(String* key, Object* value);
1597
1642
  // Gets the value of a hidden property with the given key. Returns undefined
1598
1643
  // if the property doesn't exist (or if called on a detached proxy),
1604
1649
  // Returns true if the object has a property with the hidden symbol as name.
1605
1650
  bool HasHiddenProperties();
1606
1651
 
 
1652
  static int GetIdentityHash(Handle<JSObject> obj);
1607
1653
  MUST_USE_RESULT MaybeObject* GetIdentityHash(CreationFlag flag);
1608
1654
  MUST_USE_RESULT MaybeObject* SetIdentityHash(Object* hash, CreationFlag flag);
1609
1655
 
 
1656
  static Handle<Object> DeleteProperty(Handle<JSObject> obj,
 
1657
                                       Handle<String> name);
1610
1658
  MUST_USE_RESULT MaybeObject* DeleteProperty(String* name, DeleteMode mode);
 
1659
 
 
1660
  static Handle<Object> DeleteElement(Handle<JSObject> obj, uint32_t index);
1611
1661
  MUST_USE_RESULT MaybeObject* DeleteElement(uint32_t index, DeleteMode mode);
1612
1662
 
1613
1663
  inline void ValidateSmiOnlyElements();
1614
1664
 
1615
 
  // Makes sure that this object can contain non-smi Object as elements.
1616
 
  inline MaybeObject* EnsureCanContainNonSmiElements();
 
1665
  // Makes sure that this object can contain HeapObject as elements.
 
1666
  inline MaybeObject* EnsureCanContainHeapObjectElements();
1617
1667
 
1618
1668
  // Makes sure that this object can contain the specified elements.
1619
1669
  inline MaybeObject* EnsureCanContainElements(Object** elements,
1620
 
                                               uint32_t count);
1621
 
  inline MaybeObject* EnsureCanContainElements(FixedArray* elements);
 
1670
                                               uint32_t count,
 
1671
                                               EnsureElementsMode mode);
 
1672
  inline MaybeObject* EnsureCanContainElements(FixedArrayBase* elements,
 
1673
                                               EnsureElementsMode mode);
1622
1674
  MaybeObject* EnsureCanContainElements(Arguments* arguments,
1623
1675
                                        uint32_t first_arg,
1624
 
                                        uint32_t arg_count);
 
1676
                                        uint32_t arg_count,
 
1677
                                        EnsureElementsMode mode);
1625
1678
 
1626
1679
  // Do we want to keep the elements in fast case when increasing the
1627
1680
  // capacity?
1632
1685
  // elements.
1633
1686
  bool ShouldConvertToFastElements();
1634
1687
  // Returns true if the elements of JSObject contains only values that can be
1635
 
  // represented in a FixedDoubleArray.
1636
 
  bool CanConvertToFastDoubleElements();
 
1688
  // represented in a FixedDoubleArray and has at least one value that can only
 
1689
  // be represented as a double and not a Smi.
 
1690
  bool ShouldConvertToFastDoubleElements(bool* has_smi_only_elements);
1637
1691
 
1638
1692
  // Tells whether the index'th element is present.
1639
1693
  bool HasElementWithReceiver(JSReceiver* receiver, uint32_t index);
1683
1737
      StrictModeFlag strict_mode,
1684
1738
      bool check_prototype = true);
1685
1739
 
1686
 
  // Set the index'th array element.
 
1740
 
 
1741
  static Handle<Object> SetOwnElement(Handle<JSObject> object,
 
1742
                                      uint32_t index,
 
1743
                                      Handle<Object> value,
 
1744
                                      StrictModeFlag strict_mode);
 
1745
 
 
1746
  // Empty handle is returned if the element cannot be set to the given value.
 
1747
  static MUST_USE_RESULT Handle<Object> SetElement(Handle<JSObject> object,
 
1748
                                                   uint32_t index,
 
1749
                                                   Handle<Object> value,
 
1750
                                                   StrictModeFlag strict_mode);
 
1751
 
1687
1752
  // A Failure object is returned if GC is needed.
1688
1753
  MUST_USE_RESULT MaybeObject* SetElement(uint32_t index,
1689
1754
                                          Object* value,
1696
1761
 
1697
1762
  enum SetFastElementsCapacityMode {
1698
1763
    kAllowSmiOnlyElements,
 
1764
    kForceSmiOnlyElements,
1699
1765
    kDontAllowSmiOnlyElements
1700
1766
  };
1701
1767
 
1720
1786
  bool HasRealElementProperty(uint32_t index);
1721
1787
  bool HasRealNamedCallbackProperty(String* key);
1722
1788
 
1723
 
  // Initializes the array to a certain length
1724
 
  MUST_USE_RESULT MaybeObject* SetElementsLength(Object* length);
1725
 
 
1726
1789
  // Get the header size for a JSObject.  Used to compute the index of
1727
1790
  // internal fields as well as the number of internal fields.
1728
1791
  inline int GetHeaderSize();
1795
1858
  MUST_USE_RESULT MaybeObject* GetElementsTransitionMap(
1796
1859
      ElementsKind elements_kind);
1797
1860
 
 
1861
  static Handle<Object> TransitionElementsKind(Handle<JSObject> object,
 
1862
                                               ElementsKind to_kind);
 
1863
 
1798
1864
  MUST_USE_RESULT MaybeObject* TransitionElementsKind(ElementsKind to_kind);
1799
1865
 
1800
1866
  // Converts a descriptor of any other type to a real field,
1835
1901
  // representation. If the object is expected to have additional properties
1836
1902
  // added this number can be indicated to have the backing store allocated to
1837
1903
  // an initial capacity for holding these properties.
 
1904
  static void NormalizeProperties(Handle<JSObject> object,
 
1905
                                  PropertyNormalizationMode mode,
 
1906
                                  int expected_additional_properties);
 
1907
 
1838
1908
  MUST_USE_RESULT MaybeObject* NormalizeProperties(
1839
1909
      PropertyNormalizationMode mode,
1840
1910
      int expected_additional_properties);
1841
1911
 
1842
 
  // Convert and update the elements backing store to be a NumberDictionary
1843
 
  // dictionary.  Returns the backing after conversion.
 
1912
  // Convert and update the elements backing store to be a
 
1913
  // SeededNumberDictionary dictionary.  Returns the backing after conversion.
 
1914
  static Handle<SeededNumberDictionary> NormalizeElements(
 
1915
      Handle<JSObject> object);
 
1916
 
1844
1917
  MUST_USE_RESULT MaybeObject* NormalizeElements();
1845
1918
 
1846
1919
  static void UpdateMapCodeCache(Handle<JSObject> object,
1851
1924
 
1852
1925
  // Transform slow named properties to fast variants.
1853
1926
  // Returns failure if allocation failed.
 
1927
  static void TransformToFastProperties(Handle<JSObject> object,
 
1928
                                        int unused_property_fields);
 
1929
 
1854
1930
  MUST_USE_RESULT MaybeObject* TransformToFastProperties(
1855
1931
      int unused_property_fields);
1856
1932
 
1882
1958
  static inline JSObject* cast(Object* obj);
1883
1959
 
1884
1960
  // Disalow further properties to be added to the object.
 
1961
  static Handle<Object> PreventExtensions(Handle<JSObject> object);
1885
1962
  MUST_USE_RESULT MaybeObject* PreventExtensions();
1886
1963
 
1887
1964
 
1935
2012
#endif
1936
2013
  Object* SlowReverseLookup(Object* value);
1937
2014
 
1938
 
  // Getters and setters are stored in a fixed array property.
1939
 
  // These are constants for their indices.
1940
 
  static const int kGetterIndex = 0;
1941
 
  static const int kSetterIndex = 1;
1942
 
 
1943
2015
  // Maximal number of fast properties for the JSObject. Used to
1944
2016
  // restrict the number of map transitions to avoid an explosion in
1945
2017
  // the number of maps for objects used as dictionaries.
2121
2193
  // Gives access to raw memory which stores the array's data.
2122
2194
  inline Object** data_start();
2123
2195
 
 
2196
  inline Object** GetFirstElementAddress();
 
2197
  inline bool ContainsOnlySmisOrHoles();
 
2198
 
2124
2199
  // Copy operations.
2125
2200
  MUST_USE_RESULT inline MaybeObject* Copy();
2126
2201
  MUST_USE_RESULT MaybeObject* CopySize(int new_length);
2187
2262
                                       int index,
2188
2263
                                       Object* value);
2189
2264
 
 
2265
  // Set operation on FixedArray without incremental write barrier. Can
 
2266
  // only be used if the object is guaranteed to be white (whiteness witness
 
2267
  // is present).
 
2268
  static inline void NoIncrementalWriteBarrierSet(FixedArray* array,
 
2269
                                                  int index,
 
2270
                                                  Object* value);
 
2271
 
2190
2272
 private:
2191
2273
  DISALLOW_IMPLICIT_CONSTRUCTORS(FixedArray);
2192
2274
};
2197
2279
 public:
2198
2280
  inline void Initialize(FixedArray* from);
2199
2281
  inline void Initialize(FixedDoubleArray* from);
2200
 
  inline void Initialize(NumberDictionary* from);
 
2282
  inline void Initialize(SeededNumberDictionary* from);
2201
2283
 
2202
2284
  // Setter and getter for elements.
2203
2285
  inline double get_scalar(int index);
2465
2547
        NULL_DESCRIPTOR;
2466
2548
  }
2467
2549
  // Swap operation on FixedArray without using write barriers.
2468
 
  static inline void NoWriteBarrierSwap(FixedArray* array,
2469
 
                                        int first,
2470
 
                                        int second);
 
2550
  static inline void NoIncrementalWriteBarrierSwap(
 
2551
      FixedArray* array, int first, int second);
2471
2552
 
2472
2553
  // Swap descriptor first and second.
2473
 
  inline void NoWriteBarrierSwapDescriptors(int first, int second);
 
2554
  inline void NoIncrementalWriteBarrierSwapDescriptors(
 
2555
      int first, int second);
2474
2556
 
2475
2557
  FixedArray* GetContentArray() {
2476
2558
    return FixedArray::cast(get(kContentArrayIndex));
2512
2594
// beginning of the backing storage that can be used for non-element
2513
2595
// information by subclasses.
2514
2596
 
 
2597
template<typename Key>
 
2598
class BaseShape {
 
2599
 public:
 
2600
  static const bool UsesSeed = false;
 
2601
  static uint32_t Hash(Key key) { return 0; }
 
2602
  static uint32_t SeededHash(Key key, uint32_t seed) {
 
2603
    ASSERT(UsesSeed);
 
2604
    return Hash(key);
 
2605
  }
 
2606
  static uint32_t HashForObject(Key key, Object* object) { return 0; }
 
2607
  static uint32_t SeededHashForObject(Key key, uint32_t seed, Object* object) {
 
2608
    ASSERT(UsesSeed);
 
2609
    return HashForObject(key, object);
 
2610
  }
 
2611
};
 
2612
 
2515
2613
template<typename Shape, typename Key>
2516
2614
class HashTable: public FixedArray {
2517
2615
 public:
 
2616
  // Wrapper methods
 
2617
  inline uint32_t Hash(Key key) {
 
2618
    if (Shape::UsesSeed) {
 
2619
      return Shape::SeededHash(key,
 
2620
          GetHeap()->HashSeed());
 
2621
    } else {
 
2622
      return Shape::Hash(key);
 
2623
    }
 
2624
  }
 
2625
 
 
2626
  inline uint32_t HashForObject(Key key, Object* object) {
 
2627
    if (Shape::UsesSeed) {
 
2628
      return Shape::SeededHashForObject(key,
 
2629
          GetHeap()->HashSeed(), object);
 
2630
    } else {
 
2631
      return Shape::HashForObject(key, object);
 
2632
    }
 
2633
  }
 
2634
 
2518
2635
  // Returns the number of elements in the hash table.
2519
2636
  int NumberOfElements() {
2520
2637
    return Smi::cast(get(kNumberOfElementsIndex))->value();
2656
2773
};
2657
2774
 
2658
2775
 
2659
 
 
2660
2776
// HashTableKey is an abstract superclass for virtual key behavior.
2661
2777
class HashTableKey {
2662
2778
 public:
2673
2789
  virtual ~HashTableKey() {}
2674
2790
};
2675
2791
 
2676
 
class SymbolTableShape {
 
2792
 
 
2793
class SymbolTableShape : public BaseShape<HashTableKey*> {
2677
2794
 public:
2678
2795
  static inline bool IsMatch(HashTableKey* key, Object* value) {
2679
2796
    return key->IsMatch(value);
2732
2849
};
2733
2850
 
2734
2851
 
2735
 
class MapCacheShape {
 
2852
class MapCacheShape : public BaseShape<HashTableKey*> {
2736
2853
 public:
2737
2854
  static inline bool IsMatch(HashTableKey* key, Object* value) {
2738
2855
    return key->IsMatch(value);
2888
3005
};
2889
3006
 
2890
3007
 
2891
 
class StringDictionaryShape {
 
3008
class StringDictionaryShape : public BaseShape<String*> {
2892
3009
 public:
2893
3010
  static inline bool IsMatch(String* key, Object* other);
2894
3011
  static inline uint32_t Hash(String* key);
2921
3038
};
2922
3039
 
2923
3040
 
2924
 
class NumberDictionaryShape {
 
3041
class NumberDictionaryShape : public BaseShape<uint32_t> {
2925
3042
 public:
2926
3043
  static inline bool IsMatch(uint32_t key, Object* other);
 
3044
  MUST_USE_RESULT static inline MaybeObject* AsObject(uint32_t key);
 
3045
  static const int kEntrySize = 3;
 
3046
  static const bool kIsEnumerable = false;
 
3047
};
 
3048
 
 
3049
 
 
3050
class SeededNumberDictionaryShape : public NumberDictionaryShape {
 
3051
 public:
 
3052
  static const bool UsesSeed = true;
 
3053
  static const int kPrefixSize = 2;
 
3054
 
 
3055
  static inline uint32_t SeededHash(uint32_t key, uint32_t seed);
 
3056
  static inline uint32_t SeededHashForObject(uint32_t key,
 
3057
                                             uint32_t seed,
 
3058
                                             Object* object);
 
3059
};
 
3060
 
 
3061
 
 
3062
class UnseededNumberDictionaryShape : public NumberDictionaryShape {
 
3063
 public:
 
3064
  static const int kPrefixSize = 0;
 
3065
 
2927
3066
  static inline uint32_t Hash(uint32_t key);
2928
3067
  static inline uint32_t HashForObject(uint32_t key, Object* object);
2929
 
  MUST_USE_RESULT static inline MaybeObject* AsObject(uint32_t key);
2930
 
  static const int kPrefixSize = 2;
2931
 
  static const int kEntrySize = 3;
2932
 
  static const bool kIsEnumerable = false;
2933
3068
};
2934
3069
 
2935
3070
 
2936
 
class NumberDictionary: public Dictionary<NumberDictionaryShape, uint32_t> {
 
3071
class SeededNumberDictionary
 
3072
    : public Dictionary<SeededNumberDictionaryShape, uint32_t> {
2937
3073
 public:
2938
 
  static NumberDictionary* cast(Object* obj) {
 
3074
  static SeededNumberDictionary* cast(Object* obj) {
2939
3075
    ASSERT(obj->IsDictionary());
2940
 
    return reinterpret_cast<NumberDictionary*>(obj);
 
3076
    return reinterpret_cast<SeededNumberDictionary*>(obj);
2941
3077
  }
2942
3078
 
2943
3079
  // Type specific at put (default NONE attributes is used when adding).
2947
3083
                                              PropertyDetails details);
2948
3084
 
2949
3085
  // Set an existing entry or add a new one if needed.
 
3086
  // Return the updated dictionary.
 
3087
  MUST_USE_RESULT static Handle<SeededNumberDictionary> Set(
 
3088
      Handle<SeededNumberDictionary> dictionary,
 
3089
      uint32_t index,
 
3090
      Handle<Object> value,
 
3091
      PropertyDetails details);
 
3092
 
2950
3093
  MUST_USE_RESULT MaybeObject* Set(uint32_t key,
2951
3094
                                   Object* value,
2952
3095
                                   PropertyDetails details);
2973
3116
};
2974
3117
 
2975
3118
 
 
3119
class UnseededNumberDictionary
 
3120
    : public Dictionary<UnseededNumberDictionaryShape, uint32_t> {
 
3121
 public:
 
3122
  static UnseededNumberDictionary* cast(Object* obj) {
 
3123
    ASSERT(obj->IsDictionary());
 
3124
    return reinterpret_cast<UnseededNumberDictionary*>(obj);
 
3125
  }
 
3126
 
 
3127
  // Type specific at put (default NONE attributes is used when adding).
 
3128
  MUST_USE_RESULT MaybeObject* AtNumberPut(uint32_t key, Object* value);
 
3129
  MUST_USE_RESULT MaybeObject* AddNumberEntry(uint32_t key, Object* value);
 
3130
 
 
3131
  // Set an existing entry or add a new one if needed.
 
3132
  // Return the updated dictionary.
 
3133
  MUST_USE_RESULT static Handle<UnseededNumberDictionary> Set(
 
3134
      Handle<UnseededNumberDictionary> dictionary,
 
3135
      uint32_t index,
 
3136
      Handle<Object> value);
 
3137
 
 
3138
  MUST_USE_RESULT MaybeObject* Set(uint32_t key, Object* value);
 
3139
};
 
3140
 
 
3141
 
2976
3142
template <int entrysize>
2977
 
class ObjectHashTableShape {
 
3143
class ObjectHashTableShape : public BaseShape<Object*> {
2978
3144
 public:
2979
3145
  static inline bool IsMatch(Object* key, Object* other);
2980
3146
  static inline uint32_t Hash(Object* key);
3885
4051
  // [deoptimization_data]: Array containing data for deopt.
3886
4052
  DECL_ACCESSORS(deoptimization_data, FixedArray)
3887
4053
 
3888
 
  // [code_flushing_candidate]: Field only used during garbage
3889
 
  // collection to hold code flushing candidates. The contents of this
 
4054
  // [gc_metadata]: Field used to hold GC related metadata. The contents of this
3890
4055
  // field does not have to be traced during garbage collection since
3891
4056
  // it is only used by the garbage collector itself.
3892
 
  DECL_ACCESSORS(next_code_flushing_candidate, Object)
 
4057
  DECL_ACCESSORS(gc_metadata, Object)
3893
4058
 
3894
4059
  // Unchecked accessors to be used during GC.
3895
4060
  inline ByteArray* unchecked_relocation_info();
4113
4278
  static const int kHandlerTableOffset = kRelocationInfoOffset + kPointerSize;
4114
4279
  static const int kDeoptimizationDataOffset =
4115
4280
      kHandlerTableOffset + kPointerSize;
4116
 
  static const int kNextCodeFlushingCandidateOffset =
4117
 
      kDeoptimizationDataOffset + kPointerSize;
4118
 
  static const int kFlagsOffset =
4119
 
      kNextCodeFlushingCandidateOffset + kPointerSize;
 
4281
  static const int kGCMetadataOffset = kDeoptimizationDataOffset + kPointerSize;
 
4282
  static const int kFlagsOffset = kGCMetadataOffset + kPointerSize;
4120
4283
 
4121
4284
  static const int kKindSpecificFlagsOffset = kFlagsOffset + kIntSize;
4122
4285
  static const int kKindSpecificFlagsSize = 2 * kIntSize;
4327
4490
    return elements_kind() == DICTIONARY_ELEMENTS;
4328
4491
  }
4329
4492
 
 
4493
  inline bool has_slow_elements_kind() {
 
4494
    return elements_kind() == DICTIONARY_ELEMENTS
 
4495
        || elements_kind() == NON_STRICT_ARGUMENTS_ELEMENTS;
 
4496
  }
 
4497
 
4330
4498
  static bool IsValidElementsTransition(ElementsKind from_kind,
4331
4499
                                        ElementsKind to_kind);
4332
4500
 
4765
4933
  V(Math, atan, MathATan)                           \
4766
4934
  V(Math, exp, MathExp)                             \
4767
4935
  V(Math, sqrt, MathSqrt)                           \
4768
 
  V(Math, pow, MathPow)
 
4936
  V(Math, pow, MathPow)                             \
 
4937
  V(Math, random, MathRandom)                       \
 
4938
  V(Math, max, MathMax)                             \
 
4939
  V(Math, min, MathMin)
4769
4940
 
4770
4941
 
4771
4942
enum BuiltinFunctionId {
5886
6057
};
5887
6058
 
5888
6059
 
5889
 
class CompilationCacheShape {
 
6060
class CompilationCacheShape : public BaseShape<HashTableKey*> {
5890
6061
 public:
5891
6062
  static inline bool IsMatch(HashTableKey* key, Object* value) {
5892
6063
    return key->IsMatch(value);
5990
6161
};
5991
6162
 
5992
6163
 
5993
 
class CodeCacheHashTableShape {
 
6164
class CodeCacheHashTableShape : public BaseShape<HashTableKey*> {
5994
6165
 public:
5995
6166
  static inline bool IsMatch(HashTableKey* key, Object* value) {
5996
6167
    return key->IsMatch(value);
6091
6262
 
6092
6263
class StringHasher {
6093
6264
 public:
6094
 
  explicit inline StringHasher(int length);
 
6265
  explicit inline StringHasher(int length, uint32_t seed);
6095
6266
 
6096
6267
  // Returns true if the hash of this string can be computed without
6097
6268
  // looking at the contents.
6122
6293
  // value is represented decimal value.
6123
6294
  static uint32_t MakeArrayIndexHash(uint32_t value, int length);
6124
6295
 
 
6296
  // No string is allowed to have a hash of zero.  That value is reserved
 
6297
  // for internal properties.  If the hash calculation yields zero then we
 
6298
  // use 27 instead.
 
6299
  static const int kZeroHash = 27;
 
6300
 
6125
6301
 private:
6126
6302
  uint32_t array_index() {
6127
6303
    ASSERT(is_array_index());
6142
6318
 
6143
6319
// Calculates string hash.
6144
6320
template <typename schar>
6145
 
inline uint32_t HashSequentialString(const schar* chars, int length);
 
6321
inline uint32_t HashSequentialString(const schar* chars,
 
6322
                                     int length,
 
6323
                                     uint32_t seed);
6146
6324
 
6147
6325
 
6148
6326
// The characteristics of a string are stored in its map.  Retrieving these
6314
6492
  inline String* GetUnderlying();
6315
6493
 
6316
6494
  // Mark the string as an undetectable object. It only applies to
6317
 
  // ascii and two byte string types.
 
6495
  // ASCII and two byte string types.
6318
6496
  bool MarkAsUndetectable();
6319
6497
 
6320
6498
  // Return a substring.
6365
6543
  inline uint32_t Hash();
6366
6544
 
6367
6545
  static uint32_t ComputeHashField(unibrow::CharacterStream* buffer,
6368
 
                                   int length);
 
6546
                                   int length,
 
6547
                                   uint32_t seed);
6369
6548
 
6370
6549
  static bool ComputeArrayIndex(unibrow::CharacterStream* buffer,
6371
6550
                                uint32_t* index,
6410
6589
  // value into an array index.
6411
6590
  static const int kMaxArrayIndexSize = 10;
6412
6591
 
6413
 
  // Max ascii char code.
 
6592
  // Max ASCII char code.
6414
6593
  static const int kMaxAsciiCharCode = unibrow::Utf8::kMaxOneByteChar;
6415
6594
  static const unsigned kMaxAsciiCharCodeU = unibrow::Utf8::kMaxOneByteChar;
6416
6595
  static const int kMaxUC16CharCode = 0xffff;
6417
6596
 
6418
 
  // Minimum length for a cons string.
6419
 
  static const int kMinNonFlatLength = 13;
6420
 
 
6421
6597
  // Mask constant for checking if a string has a computed hash code
6422
6598
  // and if it is an array index.  The least significant bit indicates
6423
6599
  // whether a hash code has been computed.  If the hash code has been
6430
6606
  // Shift constant retrieving hash code from hash field.
6431
6607
  static const int kHashShift = kNofHashBitFields;
6432
6608
 
 
6609
  // Only these bits are relevant in the hash, since the top two are shifted
 
6610
  // out.
 
6611
  static const uint32_t kHashBitMask = 0xffffffffu >> kHashShift;
 
6612
 
6433
6613
  // Array index strings this short can keep their index in the hash
6434
6614
  // field.
6435
6615
  static const int kMaxCachedArrayIndexLength = 7;
6592
6772
};
6593
6773
 
6594
6774
 
6595
 
// The AsciiString class captures sequential ascii string objects.
6596
 
// Each character in the AsciiString is an ascii character.
 
6775
// The AsciiString class captures sequential ASCII string objects.
 
6776
// Each character in the AsciiString is an ASCII character.
6597
6777
class SeqAsciiString: public SeqString {
6598
6778
 public:
6599
6779
  static const bool kHasAsciiEncoding = true;
7043
7223
  static const byte kUndefined = 5;
7044
7224
  static const byte kOther = 6;
7045
7225
 
7046
 
  // The ToNumber value of a hidden oddball is a negative smi.
7047
 
  static const int kLeastHiddenOddballNumber = -5;
7048
 
 
7049
7226
  typedef FixedBodyDescriptor<kToStringOffset,
7050
7227
                              kToNumberOffset + kPointerSize,
7051
7228
                              kSize> BodyDescriptor;
7375
7552
  // capacity is non-zero.
7376
7553
  MUST_USE_RESULT MaybeObject* Initialize(int capacity);
7377
7554
 
 
7555
  // Initializes the array to a certain length.
 
7556
  inline bool AllowsSetElementsLength();
 
7557
  MUST_USE_RESULT MaybeObject* SetElementsLength(Object* length);
 
7558
 
7378
7559
  // Set the content of the array to the content of storage.
7379
 
  inline MaybeObject* SetContent(FixedArray* storage);
 
7560
  inline MaybeObject* SetContent(FixedArrayBase* storage);
7380
7561
 
7381
7562
  // Casting.
7382
7563
  static inline JSArray* cast(Object* obj);
7491
7672
};
7492
7673
 
7493
7674
 
 
7675
// Support for JavaScript accessors: A pair of a getter and a setter. Each
 
7676
// accessor can either be
 
7677
//   * a pointer to a JavaScript function or proxy: a real accessor
 
7678
//   * undefined: considered an accessor by the spec, too, strangely enough
 
7679
//   * the hole: an accessor which has not been set
 
7680
//   * a pointer to a map: a transition used to ensure map sharing
 
7681
class AccessorPair: public Struct {
 
7682
 public:
 
7683
  DECL_ACCESSORS(getter, Object)
 
7684
  DECL_ACCESSORS(setter, Object)
 
7685
 
 
7686
  static inline AccessorPair* cast(Object* obj);
 
7687
 
 
7688
#ifdef OBJECT_PRINT
 
7689
  void AccessorPairPrint(FILE* out = stdout);
 
7690
#endif
 
7691
#ifdef DEBUG
 
7692
  void AccessorPairVerify();
 
7693
#endif
 
7694
 
 
7695
  static const int kGetterOffset = HeapObject::kHeaderSize;
 
7696
  static const int kSetterOffset = kGetterOffset + kPointerSize;
 
7697
  static const int kSize = kSetterOffset + kPointerSize;
 
7698
 
 
7699
 private:
 
7700
  DISALLOW_IMPLICIT_CONSTRUCTORS(AccessorPair);
 
7701
};
 
7702
 
 
7703
 
7494
7704
class AccessCheckInfo: public Struct {
7495
7705
 public:
7496
7706
  DECL_ACCESSORS(named_callback, Object)
7591
7801
  static const int kTagOffset          = HeapObject::kHeaderSize;
7592
7802
  static const int kPropertyListOffset = kTagOffset + kPointerSize;
7593
7803
  static const int kHeaderSize         = kPropertyListOffset + kPointerSize;
7594
 
 protected:
 
7804
 
 
7805
 private:
7595
7806
  DISALLOW_IMPLICIT_CONSTRUCTORS(TemplateInfo);
7596
7807
};
7597
7808
 
7857
8068
#undef DECL_BOOLEAN_ACCESSORS
7858
8069
#undef DECL_ACCESSORS
7859
8070
 
 
8071
#define VISITOR_SYNCHRONIZATION_TAGS_LIST(V)                            \
 
8072
  V(kSymbolTable, "symbol_table", "(Symbols)")                          \
 
8073
  V(kExternalStringsTable, "external_strings_table", "(External strings)") \
 
8074
  V(kStrongRootList, "strong_root_list", "(Strong roots)")              \
 
8075
  V(kSymbol, "symbol", "(Symbol)")                                      \
 
8076
  V(kBootstrapper, "bootstrapper", "(Bootstrapper)")                    \
 
8077
  V(kTop, "top", "(Isolate)")                                           \
 
8078
  V(kRelocatable, "relocatable", "(Relocatable)")                       \
 
8079
  V(kDebug, "debug", "(Debugger)")                                      \
 
8080
  V(kCompilationCache, "compilationcache", "(Compilation cache)")       \
 
8081
  V(kHandleScope, "handlescope", "(Handle scope)")                      \
 
8082
  V(kBuiltins, "builtins", "(Builtins)")                                \
 
8083
  V(kGlobalHandles, "globalhandles", "(Global handles)")                \
 
8084
  V(kThreadManager, "threadmanager", "(Thread manager)")                \
 
8085
  V(kExtensions, "Extensions", "(Extensions)")
 
8086
 
 
8087
class VisitorSynchronization : public AllStatic {
 
8088
 public:
 
8089
#define DECLARE_ENUM(enum_item, ignore1, ignore2) enum_item,
 
8090
  enum SyncTag {
 
8091
    VISITOR_SYNCHRONIZATION_TAGS_LIST(DECLARE_ENUM)
 
8092
    kNumberOfSyncTags
 
8093
  };
 
8094
#undef DECLARE_ENUM
 
8095
 
 
8096
  static const char* const kTags[kNumberOfSyncTags];
 
8097
  static const char* const kTagNames[kNumberOfSyncTags];
 
8098
};
7860
8099
 
7861
8100
// Abstract base class for visiting, and optionally modifying, the
7862
8101
// pointers contained in Objects. Used in GC and serialization/deserialization.
7912
8151
  // Visits a handle that has an embedder-assigned class ID.
7913
8152
  virtual void VisitEmbedderReference(Object** p, uint16_t class_id) {}
7914
8153
 
7915
 
#ifdef DEBUG
7916
8154
  // Intended for serialization/deserialization checking: insert, or
7917
8155
  // check for the presence of, a tag at this position in the stream.
7918
 
  virtual void Synchronize(const char* tag) {}
7919
 
#else
7920
 
  inline void Synchronize(const char* tag) {}
7921
 
#endif
 
8156
  // Also used for marking up GC roots in heap snapshots.
 
8157
  virtual void Synchronize(VisitorSynchronization::SyncTag tag) {}
7922
8158
};
7923
8159
 
7924
8160