ArrayConventions.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. /*
  2. * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
  3. * Copyright (C) 2003, 2007, 2008, 2009, 2012 Apple Inc. All rights reserved.
  4. *
  5. * This library is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU Lesser General Public
  7. * License as published by the Free Software Foundation; either
  8. * version 2 of the License, or (at your option) any later version.
  9. *
  10. * This library is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * Lesser General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Lesser General Public
  16. * License along with this library; if not, write to the Free Software
  17. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  18. *
  19. */
  20. #ifndef ArrayConventions_h
  21. #define ArrayConventions_h
  22. #include "IndexingHeader.h"
  23. #include "WriteBarrier.h"
  24. namespace JSC {
  25. // Overview of JSArray
  26. //
  27. // Properties of JSArray objects may be stored in one of three locations:
  28. // * The regular JSObject property map.
  29. // * A storage vector.
  30. // * A sparse map of array entries.
  31. //
  32. // Properties with non-numeric identifiers, with identifiers that are not representable
  33. // as an unsigned integer, or where the value is greater than MAX_ARRAY_INDEX
  34. // (specifically, this is only one property - the value 0xFFFFFFFFU as an unsigned 32-bit
  35. // integer) are not considered array indices and will be stored in the JSObject property map.
  36. //
  37. // All properties with a numeric identifer, representable as an unsigned integer i,
  38. // where (i <= MAX_ARRAY_INDEX), are an array index and will be stored in either the
  39. // storage vector or the sparse map. An array index i will be handled in the following
  40. // fashion:
  41. //
  42. // * Where (i < MIN_SPARSE_ARRAY_INDEX) the value will be stored in the storage vector,
  43. // unless the array is in SparseMode in which case all properties go into the map.
  44. // * Where (MIN_SPARSE_ARRAY_INDEX <= i <= MAX_STORAGE_VECTOR_INDEX) the value will either
  45. // be stored in the storage vector or in the sparse array, depending on the density of
  46. // data that would be stored in the vector (a vector being used where at least
  47. // (1 / minDensityMultiplier) of the entries would be populated).
  48. // * Where (MAX_STORAGE_VECTOR_INDEX < i <= MAX_ARRAY_INDEX) the value will always be stored
  49. // in the sparse array.
  50. // Define the maximum storage vector length to be 2^32 / sizeof(JSValue) / 2 to ensure that
  51. // there is no risk of overflow.
  52. #define MAX_STORAGE_VECTOR_LENGTH (static_cast<unsigned>(IndexingHeader::maximumLength))
  53. // These values have to be macros to be used in max() and min() without introducing
  54. // a PIC branch in Mach-O binaries, see <rdar://problem/5971391>.
  55. #define MIN_SPARSE_ARRAY_INDEX 100000U
  56. #define MAX_STORAGE_VECTOR_INDEX (MAX_STORAGE_VECTOR_LENGTH - 1)
  57. // 0xFFFFFFFF is a bit weird -- is not an array index even though it's an integer.
  58. #define MAX_ARRAY_INDEX 0xFFFFFFFEU
  59. // The value BASE_VECTOR_LEN is the maximum number of vector elements we'll allocate
  60. // for an array that was created with a sepcified length (e.g. a = new Array(123))
  61. #define BASE_VECTOR_LEN 4U
  62. // The upper bound to the size we'll grow a zero length array when the first element
  63. // is added.
  64. #define FIRST_VECTOR_GROW 4U
  65. #define MIN_BEYOND_LENGTH_SPARSE_INDEX 1000
  66. // Our policy for when to use a vector and when to use a sparse map.
  67. // For all array indices under MIN_SPARSE_ARRAY_INDEX, we always use a vector.
  68. // When indices greater than MIN_SPARSE_ARRAY_INDEX are involved, we use a vector
  69. // as long as it is 1/8 full. If more sparse than that, we use a map.
  70. static const unsigned minDensityMultiplier = 8;
  71. inline bool isDenseEnoughForVector(unsigned length, unsigned numValues)
  72. {
  73. return length / minDensityMultiplier <= numValues;
  74. }
  75. inline bool indexIsSufficientlyBeyondLengthForSparseMap(unsigned i, unsigned length)
  76. {
  77. return i >= MIN_BEYOND_LENGTH_SPARSE_INDEX && i > length;
  78. }
  79. inline IndexingHeader indexingHeaderForArray(unsigned length, unsigned vectorLength)
  80. {
  81. IndexingHeader result;
  82. result.setPublicLength(length);
  83. result.setVectorLength(vectorLength);
  84. return result;
  85. }
  86. inline IndexingHeader baseIndexingHeaderForArray(unsigned length)
  87. {
  88. return indexingHeaderForArray(length, BASE_VECTOR_LEN);
  89. }
  90. } // namespace JSC
  91. #endif // ArrayConventions_h