libv8 3.10.8.0 → 3.11.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (215) hide show
  1. data/Rakefile +10 -3
  2. data/ext/libv8/compiler.rb +46 -0
  3. data/ext/libv8/extconf.rb +5 -1
  4. data/ext/libv8/make.rb +13 -0
  5. data/lib/libv8/version.rb +1 -1
  6. data/patches/add-freebsd9-and-freebsd10-to-gyp-GetFlavor.patch +11 -0
  7. data/patches/src_platform-freebsd.cc.patch +10 -0
  8. data/vendor/v8/ChangeLog +124 -0
  9. data/vendor/v8/DEPS +27 -0
  10. data/vendor/v8/Makefile +7 -0
  11. data/vendor/v8/SConstruct +15 -2
  12. data/vendor/v8/build/common.gypi +129 -157
  13. data/vendor/v8/build/gyp_v8 +11 -25
  14. data/vendor/v8/build/standalone.gypi +9 -3
  15. data/vendor/v8/include/v8.h +5 -3
  16. data/vendor/v8/src/SConscript +1 -0
  17. data/vendor/v8/src/api.cc +4 -33
  18. data/vendor/v8/src/api.h +2 -2
  19. data/vendor/v8/src/arm/builtins-arm.cc +5 -4
  20. data/vendor/v8/src/arm/code-stubs-arm.cc +21 -14
  21. data/vendor/v8/src/arm/codegen-arm.cc +2 -2
  22. data/vendor/v8/src/arm/debug-arm.cc +3 -1
  23. data/vendor/v8/src/arm/full-codegen-arm.cc +3 -102
  24. data/vendor/v8/src/arm/ic-arm.cc +30 -33
  25. data/vendor/v8/src/arm/lithium-arm.cc +20 -7
  26. data/vendor/v8/src/arm/lithium-arm.h +10 -4
  27. data/vendor/v8/src/arm/lithium-codegen-arm.cc +106 -60
  28. data/vendor/v8/src/arm/macro-assembler-arm.cc +49 -39
  29. data/vendor/v8/src/arm/macro-assembler-arm.h +5 -4
  30. data/vendor/v8/src/arm/regexp-macro-assembler-arm.cc +115 -55
  31. data/vendor/v8/src/arm/regexp-macro-assembler-arm.h +7 -6
  32. data/vendor/v8/src/arm/simulator-arm.h +6 -6
  33. data/vendor/v8/src/arm/stub-cache-arm.cc +64 -19
  34. data/vendor/v8/src/array.js +7 -3
  35. data/vendor/v8/src/ast.cc +11 -6
  36. data/vendor/v8/src/bootstrapper.cc +9 -11
  37. data/vendor/v8/src/builtins.cc +61 -31
  38. data/vendor/v8/src/code-stubs.cc +23 -9
  39. data/vendor/v8/src/code-stubs.h +1 -0
  40. data/vendor/v8/src/codegen.h +3 -3
  41. data/vendor/v8/src/compiler.cc +1 -1
  42. data/vendor/v8/src/contexts.h +2 -18
  43. data/vendor/v8/src/d8.cc +94 -93
  44. data/vendor/v8/src/d8.h +1 -1
  45. data/vendor/v8/src/debug-agent.cc +3 -3
  46. data/vendor/v8/src/debug.cc +41 -1
  47. data/vendor/v8/src/debug.h +50 -0
  48. data/vendor/v8/src/elements-kind.cc +134 -0
  49. data/vendor/v8/src/elements-kind.h +210 -0
  50. data/vendor/v8/src/elements.cc +356 -190
  51. data/vendor/v8/src/elements.h +36 -28
  52. data/vendor/v8/src/factory.cc +44 -4
  53. data/vendor/v8/src/factory.h +11 -7
  54. data/vendor/v8/src/flag-definitions.h +3 -0
  55. data/vendor/v8/src/frames.h +3 -0
  56. data/vendor/v8/src/full-codegen.cc +2 -1
  57. data/vendor/v8/src/func-name-inferrer.h +2 -0
  58. data/vendor/v8/src/globals.h +3 -0
  59. data/vendor/v8/src/heap-inl.h +16 -4
  60. data/vendor/v8/src/heap.cc +38 -32
  61. data/vendor/v8/src/heap.h +3 -17
  62. data/vendor/v8/src/hydrogen-instructions.cc +28 -5
  63. data/vendor/v8/src/hydrogen-instructions.h +142 -44
  64. data/vendor/v8/src/hydrogen.cc +160 -55
  65. data/vendor/v8/src/hydrogen.h +2 -0
  66. data/vendor/v8/src/ia32/assembler-ia32.h +3 -0
  67. data/vendor/v8/src/ia32/builtins-ia32.cc +5 -4
  68. data/vendor/v8/src/ia32/code-stubs-ia32.cc +22 -16
  69. data/vendor/v8/src/ia32/codegen-ia32.cc +2 -2
  70. data/vendor/v8/src/ia32/debug-ia32.cc +29 -2
  71. data/vendor/v8/src/ia32/full-codegen-ia32.cc +8 -101
  72. data/vendor/v8/src/ia32/ic-ia32.cc +23 -19
  73. data/vendor/v8/src/ia32/lithium-codegen-ia32.cc +126 -80
  74. data/vendor/v8/src/ia32/lithium-codegen-ia32.h +2 -1
  75. data/vendor/v8/src/ia32/lithium-ia32.cc +15 -9
  76. data/vendor/v8/src/ia32/lithium-ia32.h +14 -6
  77. data/vendor/v8/src/ia32/macro-assembler-ia32.cc +50 -40
  78. data/vendor/v8/src/ia32/macro-assembler-ia32.h +5 -4
  79. data/vendor/v8/src/ia32/regexp-macro-assembler-ia32.cc +113 -43
  80. data/vendor/v8/src/ia32/regexp-macro-assembler-ia32.h +9 -4
  81. data/vendor/v8/src/ia32/simulator-ia32.h +4 -4
  82. data/vendor/v8/src/ia32/stub-cache-ia32.cc +52 -14
  83. data/vendor/v8/src/ic.cc +77 -20
  84. data/vendor/v8/src/ic.h +18 -2
  85. data/vendor/v8/src/incremental-marking-inl.h +21 -5
  86. data/vendor/v8/src/incremental-marking.cc +35 -8
  87. data/vendor/v8/src/incremental-marking.h +12 -3
  88. data/vendor/v8/src/isolate.cc +12 -2
  89. data/vendor/v8/src/isolate.h +1 -1
  90. data/vendor/v8/src/jsregexp.cc +66 -26
  91. data/vendor/v8/src/jsregexp.h +60 -31
  92. data/vendor/v8/src/list-inl.h +8 -0
  93. data/vendor/v8/src/list.h +3 -0
  94. data/vendor/v8/src/lithium.cc +5 -2
  95. data/vendor/v8/src/liveedit.cc +57 -5
  96. data/vendor/v8/src/mark-compact-inl.h +17 -11
  97. data/vendor/v8/src/mark-compact.cc +100 -143
  98. data/vendor/v8/src/mark-compact.h +44 -20
  99. data/vendor/v8/src/messages.js +131 -99
  100. data/vendor/v8/src/mips/builtins-mips.cc +5 -4
  101. data/vendor/v8/src/mips/code-stubs-mips.cc +23 -15
  102. data/vendor/v8/src/mips/codegen-mips.cc +2 -2
  103. data/vendor/v8/src/mips/debug-mips.cc +3 -1
  104. data/vendor/v8/src/mips/full-codegen-mips.cc +4 -102
  105. data/vendor/v8/src/mips/ic-mips.cc +34 -36
  106. data/vendor/v8/src/mips/lithium-codegen-mips.cc +116 -68
  107. data/vendor/v8/src/mips/lithium-mips.cc +20 -7
  108. data/vendor/v8/src/mips/lithium-mips.h +11 -4
  109. data/vendor/v8/src/mips/macro-assembler-mips.cc +50 -39
  110. data/vendor/v8/src/mips/macro-assembler-mips.h +5 -4
  111. data/vendor/v8/src/mips/regexp-macro-assembler-mips.cc +110 -50
  112. data/vendor/v8/src/mips/regexp-macro-assembler-mips.h +6 -5
  113. data/vendor/v8/src/mips/simulator-mips.h +5 -5
  114. data/vendor/v8/src/mips/stub-cache-mips.cc +66 -20
  115. data/vendor/v8/src/mksnapshot.cc +5 -1
  116. data/vendor/v8/src/objects-debug.cc +103 -6
  117. data/vendor/v8/src/objects-inl.h +215 -116
  118. data/vendor/v8/src/objects-printer.cc +13 -8
  119. data/vendor/v8/src/objects.cc +608 -331
  120. data/vendor/v8/src/objects.h +129 -94
  121. data/vendor/v8/src/parser.cc +16 -4
  122. data/vendor/v8/src/platform-freebsd.cc +1 -0
  123. data/vendor/v8/src/platform-linux.cc +9 -30
  124. data/vendor/v8/src/platform-posix.cc +28 -7
  125. data/vendor/v8/src/platform-win32.cc +15 -3
  126. data/vendor/v8/src/platform.h +2 -1
  127. data/vendor/v8/src/profile-generator-inl.h +25 -2
  128. data/vendor/v8/src/profile-generator.cc +300 -822
  129. data/vendor/v8/src/profile-generator.h +97 -214
  130. data/vendor/v8/src/regexp-macro-assembler-irregexp.cc +2 -1
  131. data/vendor/v8/src/regexp-macro-assembler-irregexp.h +2 -2
  132. data/vendor/v8/src/regexp-macro-assembler-tracer.cc +6 -5
  133. data/vendor/v8/src/regexp-macro-assembler-tracer.h +1 -1
  134. data/vendor/v8/src/regexp-macro-assembler.cc +7 -3
  135. data/vendor/v8/src/regexp-macro-assembler.h +10 -2
  136. data/vendor/v8/src/regexp.js +6 -0
  137. data/vendor/v8/src/runtime.cc +265 -212
  138. data/vendor/v8/src/runtime.h +6 -5
  139. data/vendor/v8/src/scopes.cc +20 -0
  140. data/vendor/v8/src/scopes.h +6 -3
  141. data/vendor/v8/src/spaces.cc +0 -2
  142. data/vendor/v8/src/string-stream.cc +2 -2
  143. data/vendor/v8/src/v8-counters.h +0 -2
  144. data/vendor/v8/src/v8natives.js +2 -2
  145. data/vendor/v8/src/v8utils.h +6 -3
  146. data/vendor/v8/src/version.cc +1 -1
  147. data/vendor/v8/src/x64/assembler-x64.h +2 -1
  148. data/vendor/v8/src/x64/builtins-x64.cc +5 -4
  149. data/vendor/v8/src/x64/code-stubs-x64.cc +25 -16
  150. data/vendor/v8/src/x64/codegen-x64.cc +2 -2
  151. data/vendor/v8/src/x64/debug-x64.cc +14 -1
  152. data/vendor/v8/src/x64/disasm-x64.cc +1 -1
  153. data/vendor/v8/src/x64/full-codegen-x64.cc +10 -106
  154. data/vendor/v8/src/x64/ic-x64.cc +20 -16
  155. data/vendor/v8/src/x64/lithium-codegen-x64.cc +156 -79
  156. data/vendor/v8/src/x64/lithium-codegen-x64.h +2 -1
  157. data/vendor/v8/src/x64/lithium-x64.cc +18 -8
  158. data/vendor/v8/src/x64/lithium-x64.h +7 -2
  159. data/vendor/v8/src/x64/macro-assembler-x64.cc +50 -40
  160. data/vendor/v8/src/x64/macro-assembler-x64.h +5 -4
  161. data/vendor/v8/src/x64/regexp-macro-assembler-x64.cc +122 -51
  162. data/vendor/v8/src/x64/regexp-macro-assembler-x64.h +17 -8
  163. data/vendor/v8/src/x64/simulator-x64.h +4 -4
  164. data/vendor/v8/src/x64/stub-cache-x64.cc +55 -17
  165. data/vendor/v8/test/cctest/cctest.status +1 -0
  166. data/vendor/v8/test/cctest/test-api.cc +24 -0
  167. data/vendor/v8/test/cctest/test-func-name-inference.cc +38 -0
  168. data/vendor/v8/test/cctest/test-heap-profiler.cc +21 -77
  169. data/vendor/v8/test/cctest/test-heap.cc +164 -3
  170. data/vendor/v8/test/cctest/test-list.cc +12 -0
  171. data/vendor/v8/test/cctest/test-mark-compact.cc +5 -5
  172. data/vendor/v8/test/cctest/test-regexp.cc +14 -8
  173. data/vendor/v8/test/cctest/testcfg.py +2 -0
  174. data/vendor/v8/test/mjsunit/accessor-map-sharing.js +176 -0
  175. data/vendor/v8/test/mjsunit/array-construct-transition.js +3 -3
  176. data/vendor/v8/test/mjsunit/array-literal-transitions.js +10 -10
  177. data/vendor/v8/test/mjsunit/big-array-literal.js +3 -0
  178. data/vendor/v8/test/mjsunit/compiler/inline-construct.js +4 -2
  179. data/vendor/v8/test/mjsunit/debug-liveedit-stack-padding.js +88 -0
  180. data/vendor/v8/test/mjsunit/elements-kind.js +4 -4
  181. data/vendor/v8/test/mjsunit/elements-transition-hoisting.js +2 -2
  182. data/vendor/v8/test/mjsunit/elements-transition.js +5 -5
  183. data/vendor/v8/test/mjsunit/error-constructors.js +68 -33
  184. data/vendor/v8/test/mjsunit/harmony/proxies.js +14 -6
  185. data/vendor/v8/test/mjsunit/mjsunit.status +1 -0
  186. data/vendor/v8/test/mjsunit/packed-elements.js +112 -0
  187. data/vendor/v8/test/mjsunit/regexp-capture-3.js +6 -0
  188. data/vendor/v8/test/mjsunit/regexp-global.js +132 -0
  189. data/vendor/v8/test/mjsunit/regexp.js +11 -0
  190. data/vendor/v8/test/mjsunit/regress/regress-117409.js +52 -0
  191. data/vendor/v8/test/mjsunit/regress/regress-126412.js +33 -0
  192. data/vendor/v8/test/mjsunit/regress/regress-128018.js +35 -0
  193. data/vendor/v8/test/mjsunit/regress/regress-128146.js +33 -0
  194. data/vendor/v8/test/mjsunit/regress/regress-1639-2.js +4 -1
  195. data/vendor/v8/test/mjsunit/regress/regress-1639.js +14 -8
  196. data/vendor/v8/test/mjsunit/regress/regress-1849.js +3 -3
  197. data/vendor/v8/test/mjsunit/regress/regress-1878.js +2 -2
  198. data/vendor/v8/test/mjsunit/regress/regress-2071.js +79 -0
  199. data/vendor/v8/test/mjsunit/regress/regress-2153.js +32 -0
  200. data/vendor/v8/test/mjsunit/regress/regress-crbug-122271.js +4 -4
  201. data/vendor/v8/test/mjsunit/regress/regress-crbug-126414.js +32 -0
  202. data/vendor/v8/test/mjsunit/regress/regress-smi-only-concat.js +2 -2
  203. data/vendor/v8/test/mjsunit/regress/regress-transcendental.js +49 -0
  204. data/vendor/v8/test/mjsunit/stack-traces.js +14 -0
  205. data/vendor/v8/test/mjsunit/unbox-double-arrays.js +4 -3
  206. data/vendor/v8/test/test262/testcfg.py +6 -1
  207. data/vendor/v8/tools/check-static-initializers.sh +11 -3
  208. data/vendor/v8/tools/fuzz-harness.sh +92 -0
  209. data/vendor/v8/tools/grokdump.py +658 -67
  210. data/vendor/v8/tools/gyp/v8.gyp +21 -39
  211. data/vendor/v8/tools/js2c.py +3 -3
  212. data/vendor/v8/tools/jsmin.py +2 -2
  213. data/vendor/v8/tools/presubmit.py +2 -1
  214. data/vendor/v8/tools/test-wrapper-gypbuild.py +25 -11
  215. metadata +624 -612
@@ -621,7 +621,7 @@ class Heap {
621
621
  MUST_USE_RESULT MaybeObject* AllocateMap(
622
622
  InstanceType instance_type,
623
623
  int instance_size,
624
- ElementsKind elements_kind = FAST_ELEMENTS);
624
+ ElementsKind elements_kind = TERMINAL_FAST_ELEMENTS_KIND);
625
625
 
626
626
  // Allocates a partial map for bootstrapping.
627
627
  MUST_USE_RESULT MaybeObject* AllocatePartialMap(InstanceType instance_type,
@@ -1342,7 +1342,7 @@ class Heap {
1342
1342
  PretenureFlag pretenure);
1343
1343
 
1344
1344
  inline intptr_t PromotedTotalSize() {
1345
- return PromotedSpaceSize() + PromotedExternalMemorySize();
1345
+ return PromotedSpaceSizeOfObjects() + PromotedExternalMemorySize();
1346
1346
  }
1347
1347
 
1348
1348
  // True if we have reached the allocation limit in the old generation that
@@ -1363,19 +1363,6 @@ class Heap {
1363
1363
  static const intptr_t kMinimumAllocationLimit =
1364
1364
  8 * (Page::kPageSize > MB ? Page::kPageSize : MB);
1365
1365
 
1366
- // When we sweep lazily we initially guess that there is no garbage on the
1367
- // heap and set the limits for the next GC accordingly. As we sweep we find
1368
- // out that some of the pages contained garbage and we have to adjust
1369
- // downwards the size of the heap. This means the limits that control the
1370
- // timing of the next GC also need to be adjusted downwards.
1371
- void LowerOldGenLimits(intptr_t adjustment) {
1372
- size_of_old_gen_at_last_old_space_gc_ -= adjustment;
1373
- old_gen_promotion_limit_ =
1374
- OldGenPromotionLimit(size_of_old_gen_at_last_old_space_gc_);
1375
- old_gen_allocation_limit_ =
1376
- OldGenAllocationLimit(size_of_old_gen_at_last_old_space_gc_);
1377
- }
1378
-
1379
1366
  intptr_t OldGenPromotionLimit(intptr_t old_gen_size) {
1380
1367
  const int divisor = FLAG_stress_compaction ? 10 : 3;
1381
1368
  intptr_t limit =
@@ -1468,7 +1455,7 @@ class Heap {
1468
1455
  intptr_t adjusted_allocation_limit =
1469
1456
  old_gen_allocation_limit_ - new_space_.Capacity() / 5;
1470
1457
 
1471
- if (PromotedSpaceSize() >= adjusted_allocation_limit) return true;
1458
+ if (PromotedSpaceSizeOfObjects() >= adjusted_allocation_limit) return true;
1472
1459
 
1473
1460
  return false;
1474
1461
  }
@@ -1506,7 +1493,6 @@ class Heap {
1506
1493
  GCTracer* tracer() { return tracer_; }
1507
1494
 
1508
1495
  // Returns the size of objects residing in non new spaces.
1509
- intptr_t PromotedSpaceSize();
1510
1496
  intptr_t PromotedSpaceSizeOfObjects();
1511
1497
 
1512
1498
  double total_regexp_code_generated() { return total_regexp_code_generated_; }
@@ -1603,6 +1603,7 @@ HLoadNamedFieldPolymorphic::HLoadNamedFieldPolymorphic(HValue* context,
1603
1603
  SetOperandAt(1, object);
1604
1604
  set_representation(Representation::Tagged());
1605
1605
  SetGVNFlag(kDependsOnMaps);
1606
+ int map_transitions = 0;
1606
1607
  for (int i = 0;
1607
1608
  i < types->length() && types_.length() < kMaxLoadPolymorphism;
1608
1609
  ++i) {
@@ -1624,13 +1625,20 @@ HLoadNamedFieldPolymorphic::HLoadNamedFieldPolymorphic(HValue* context,
1624
1625
  case CONSTANT_FUNCTION:
1625
1626
  types_.Add(types->at(i));
1626
1627
  break;
1628
+ case MAP_TRANSITION:
1629
+ // We should just ignore these since they are not relevant to a load
1630
+ // operation. This means we will deopt if we actually see this map
1631
+ // from optimized code.
1632
+ map_transitions++;
1633
+ break;
1627
1634
  default:
1628
1635
  break;
1629
1636
  }
1630
1637
  }
1631
1638
  }
1632
1639
 
1633
- if (types_.length() == types->length() && FLAG_deoptimize_uncommon_cases) {
1640
+ if (types_.length() + map_transitions == types->length() &&
1641
+ FLAG_deoptimize_uncommon_cases) {
1634
1642
  SetFlag(kUseGVN);
1635
1643
  } else {
1636
1644
  SetAllSideEffects();
@@ -1677,6 +1685,9 @@ void HLoadKeyedFastElement::PrintDataTo(StringStream* stream) {
1677
1685
  stream->Add("[");
1678
1686
  key()->PrintNameTo(stream);
1679
1687
  stream->Add("]");
1688
+ if (hole_check_mode_ == PERFORM_HOLE_CHECK) {
1689
+ stream->Add(" check_hole");
1690
+ }
1680
1691
  }
1681
1692
 
1682
1693
 
@@ -1728,7 +1739,7 @@ HValue* HLoadKeyedGeneric::Canonicalize() {
1728
1739
  HInstruction* index = new(block()->zone()) HLoadKeyedFastElement(
1729
1740
  index_cache,
1730
1741
  key_load->key(),
1731
- HLoadKeyedFastElement::OMIT_HOLE_CHECK);
1742
+ OMIT_HOLE_CHECK);
1732
1743
  HLoadFieldByIndex* load = new(block()->zone()) HLoadFieldByIndex(
1733
1744
  object(), index);
1734
1745
  map_check->InsertBefore(this);
@@ -1776,8 +1787,11 @@ void HLoadKeyedSpecializedArrayElement::PrintDataTo(
1776
1787
  stream->Add("pixel");
1777
1788
  break;
1778
1789
  case FAST_ELEMENTS:
1779
- case FAST_SMI_ONLY_ELEMENTS:
1790
+ case FAST_SMI_ELEMENTS:
1780
1791
  case FAST_DOUBLE_ELEMENTS:
1792
+ case FAST_HOLEY_ELEMENTS:
1793
+ case FAST_HOLEY_SMI_ELEMENTS:
1794
+ case FAST_HOLEY_DOUBLE_ELEMENTS:
1781
1795
  case DICTIONARY_ELEMENTS:
1782
1796
  case NON_STRICT_ARGUMENTS_ELEMENTS:
1783
1797
  UNREACHABLE();
@@ -1874,9 +1888,12 @@ void HStoreKeyedSpecializedArrayElement::PrintDataTo(
1874
1888
  case EXTERNAL_PIXEL_ELEMENTS:
1875
1889
  stream->Add("pixel");
1876
1890
  break;
1877
- case FAST_SMI_ONLY_ELEMENTS:
1891
+ case FAST_SMI_ELEMENTS:
1878
1892
  case FAST_ELEMENTS:
1879
1893
  case FAST_DOUBLE_ELEMENTS:
1894
+ case FAST_HOLEY_SMI_ELEMENTS:
1895
+ case FAST_HOLEY_ELEMENTS:
1896
+ case FAST_HOLEY_DOUBLE_ELEMENTS:
1880
1897
  case DICTIONARY_ELEMENTS:
1881
1898
  case NON_STRICT_ARGUMENTS_ELEMENTS:
1882
1899
  UNREACHABLE();
@@ -1891,7 +1908,13 @@ void HStoreKeyedSpecializedArrayElement::PrintDataTo(
1891
1908
 
1892
1909
  void HTransitionElementsKind::PrintDataTo(StringStream* stream) {
1893
1910
  object()->PrintNameTo(stream);
1894
- stream->Add(" %p -> %p", *original_map(), *transitioned_map());
1911
+ ElementsKind from_kind = original_map()->elements_kind();
1912
+ ElementsKind to_kind = transitioned_map()->elements_kind();
1913
+ stream->Add(" %p [%s] -> %p [%s]",
1914
+ *original_map(),
1915
+ ElementsAccessor::ForKind(from_kind)->name(),
1916
+ *transitioned_map(),
1917
+ ElementsAccessor::ForKind(to_kind)->name());
1895
1918
  }
1896
1919
 
1897
1920
 
@@ -2083,28 +2083,21 @@ class HCheckMaps: public HTemplateInstruction<2> {
2083
2083
  HCheckMaps* check_map = new HCheckMaps(object, map);
2084
2084
  SmallMapList* map_set = check_map->map_set();
2085
2085
 
2086
- // If the map to check has the untransitioned elements, it can be hoisted
2087
- // above TransitionElements instructions.
2088
- if (map->has_fast_smi_only_elements()) {
2089
- check_map->ClearGVNFlag(kDependsOnElementsKind);
2090
- }
2091
-
2092
- Map* transitioned_fast_element_map =
2093
- map->LookupElementsTransitionMap(FAST_ELEMENTS, NULL);
2094
- ASSERT(transitioned_fast_element_map == NULL ||
2095
- map->elements_kind() != FAST_ELEMENTS);
2096
- if (transitioned_fast_element_map != NULL) {
2097
- map_set->Add(Handle<Map>(transitioned_fast_element_map));
2098
- }
2099
- Map* transitioned_double_map =
2100
- map->LookupElementsTransitionMap(FAST_DOUBLE_ELEMENTS, NULL);
2101
- ASSERT(transitioned_double_map == NULL ||
2102
- map->elements_kind() == FAST_SMI_ONLY_ELEMENTS);
2103
- if (transitioned_double_map != NULL) {
2104
- map_set->Add(Handle<Map>(transitioned_double_map));
2105
- }
2086
+ // Since transitioned elements maps of the initial map don't fail the map
2087
+ // check, the CheckMaps instruction doesn't need to depend on ElementsKinds.
2088
+ check_map->ClearGVNFlag(kDependsOnElementsKind);
2089
+
2090
+ ElementsKind kind = map->elements_kind();
2091
+ bool packed = IsFastPackedElementsKind(kind);
2092
+ while (CanTransitionToMoreGeneralFastElementsKind(kind, packed)) {
2093
+ kind = GetNextMoreGeneralFastElementsKind(kind, packed);
2094
+ Map* transitioned_map =
2095
+ map->LookupElementsTransitionMap(kind, NULL);
2096
+ if (transitioned_map) {
2097
+ map_set->Add(Handle<Map>(transitioned_map));
2098
+ }
2099
+ };
2106
2100
  map_set->Sort();
2107
-
2108
2101
  return check_map;
2109
2102
  }
2110
2103
 
@@ -3946,15 +3939,28 @@ class HLoadFunctionPrototype: public HUnaryOperation {
3946
3939
  virtual bool DataEquals(HValue* other) { return true; }
3947
3940
  };
3948
3941
 
3949
-
3950
- class HLoadKeyedFastElement: public HTemplateInstruction<2> {
3942
+ class ArrayInstructionInterface {
3951
3943
  public:
3952
- enum HoleCheckMode { PERFORM_HOLE_CHECK, OMIT_HOLE_CHECK };
3944
+ virtual HValue* GetKey() = 0;
3945
+ virtual void SetKey(HValue* key) = 0;
3946
+ virtual void SetIndexOffset(uint32_t index_offset) = 0;
3947
+ virtual bool IsDehoisted() = 0;
3948
+ virtual void SetDehoisted(bool is_dehoisted) = 0;
3949
+ virtual ~ArrayInstructionInterface() { };
3950
+ };
3951
+
3953
3952
 
3953
+ enum HoleCheckMode { PERFORM_HOLE_CHECK, OMIT_HOLE_CHECK };
3954
+
3955
+ class HLoadKeyedFastElement
3956
+ : public HTemplateInstruction<2>, public ArrayInstructionInterface {
3957
+ public:
3954
3958
  HLoadKeyedFastElement(HValue* obj,
3955
3959
  HValue* key,
3956
3960
  HoleCheckMode hole_check_mode = PERFORM_HOLE_CHECK)
3957
- : hole_check_mode_(hole_check_mode) {
3961
+ : hole_check_mode_(hole_check_mode),
3962
+ index_offset_(0),
3963
+ is_dehoisted_(false) {
3958
3964
  SetOperandAt(0, obj);
3959
3965
  SetOperandAt(1, key);
3960
3966
  set_representation(Representation::Tagged());
@@ -3964,6 +3970,12 @@ class HLoadKeyedFastElement: public HTemplateInstruction<2> {
3964
3970
 
3965
3971
  HValue* object() { return OperandAt(0); }
3966
3972
  HValue* key() { return OperandAt(1); }
3973
+ uint32_t index_offset() { return index_offset_; }
3974
+ void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; }
3975
+ HValue* GetKey() { return key(); }
3976
+ void SetKey(HValue* key) { SetOperandAt(1, key); }
3977
+ bool IsDehoisted() { return is_dehoisted_; }
3978
+ void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; }
3967
3979
 
3968
3980
  virtual Representation RequiredInputRepresentation(int index) {
3969
3981
  // The key is supposed to be Integer32.
@@ -3982,26 +3994,43 @@ class HLoadKeyedFastElement: public HTemplateInstruction<2> {
3982
3994
  virtual bool DataEquals(HValue* other) {
3983
3995
  if (!other->IsLoadKeyedFastElement()) return false;
3984
3996
  HLoadKeyedFastElement* other_load = HLoadKeyedFastElement::cast(other);
3997
+ if (is_dehoisted_ && index_offset_ != other_load->index_offset_)
3998
+ return false;
3985
3999
  return hole_check_mode_ == other_load->hole_check_mode_;
3986
4000
  }
3987
4001
 
3988
4002
  private:
3989
4003
  HoleCheckMode hole_check_mode_;
4004
+ uint32_t index_offset_;
4005
+ bool is_dehoisted_;
3990
4006
  };
3991
4007
 
3992
4008
 
3993
- class HLoadKeyedFastDoubleElement: public HTemplateInstruction<2> {
4009
+ class HLoadKeyedFastDoubleElement
4010
+ : public HTemplateInstruction<2>, public ArrayInstructionInterface {
3994
4011
  public:
3995
- HLoadKeyedFastDoubleElement(HValue* elements, HValue* key) {
3996
- SetOperandAt(0, elements);
3997
- SetOperandAt(1, key);
3998
- set_representation(Representation::Double());
4012
+ HLoadKeyedFastDoubleElement(
4013
+ HValue* elements,
4014
+ HValue* key,
4015
+ HoleCheckMode hole_check_mode = PERFORM_HOLE_CHECK)
4016
+ : index_offset_(0),
4017
+ is_dehoisted_(false),
4018
+ hole_check_mode_(hole_check_mode) {
4019
+ SetOperandAt(0, elements);
4020
+ SetOperandAt(1, key);
4021
+ set_representation(Representation::Double());
3999
4022
  SetGVNFlag(kDependsOnDoubleArrayElements);
4000
4023
  SetFlag(kUseGVN);
4001
- }
4024
+ }
4002
4025
 
4003
4026
  HValue* elements() { return OperandAt(0); }
4004
4027
  HValue* key() { return OperandAt(1); }
4028
+ uint32_t index_offset() { return index_offset_; }
4029
+ void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; }
4030
+ HValue* GetKey() { return key(); }
4031
+ void SetKey(HValue* key) { SetOperandAt(1, key); }
4032
+ bool IsDehoisted() { return is_dehoisted_; }
4033
+ void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; }
4005
4034
 
4006
4035
  virtual Representation RequiredInputRepresentation(int index) {
4007
4036
  // The key is supposed to be Integer32.
@@ -4010,21 +4039,38 @@ class HLoadKeyedFastDoubleElement: public HTemplateInstruction<2> {
4010
4039
  : Representation::Integer32();
4011
4040
  }
4012
4041
 
4042
+ bool RequiresHoleCheck() {
4043
+ return hole_check_mode_ == PERFORM_HOLE_CHECK;
4044
+ }
4045
+
4013
4046
  virtual void PrintDataTo(StringStream* stream);
4014
4047
 
4015
4048
  DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastDoubleElement)
4016
4049
 
4017
4050
  protected:
4018
- virtual bool DataEquals(HValue* other) { return true; }
4051
+ virtual bool DataEquals(HValue* other) {
4052
+ if (!other->IsLoadKeyedFastDoubleElement()) return false;
4053
+ HLoadKeyedFastDoubleElement* other_load =
4054
+ HLoadKeyedFastDoubleElement::cast(other);
4055
+ return hole_check_mode_ == other_load->hole_check_mode_;
4056
+ }
4057
+
4058
+ private:
4059
+ uint32_t index_offset_;
4060
+ bool is_dehoisted_;
4061
+ HoleCheckMode hole_check_mode_;
4019
4062
  };
4020
4063
 
4021
4064
 
4022
- class HLoadKeyedSpecializedArrayElement: public HTemplateInstruction<2> {
4065
+ class HLoadKeyedSpecializedArrayElement
4066
+ : public HTemplateInstruction<2>, public ArrayInstructionInterface {
4023
4067
  public:
4024
4068
  HLoadKeyedSpecializedArrayElement(HValue* external_elements,
4025
4069
  HValue* key,
4026
4070
  ElementsKind elements_kind)
4027
- : elements_kind_(elements_kind) {
4071
+ : elements_kind_(elements_kind),
4072
+ index_offset_(0),
4073
+ is_dehoisted_(false) {
4028
4074
  SetOperandAt(0, external_elements);
4029
4075
  SetOperandAt(1, key);
4030
4076
  if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
@@ -4052,6 +4098,12 @@ class HLoadKeyedSpecializedArrayElement: public HTemplateInstruction<2> {
4052
4098
  HValue* external_pointer() { return OperandAt(0); }
4053
4099
  HValue* key() { return OperandAt(1); }
4054
4100
  ElementsKind elements_kind() const { return elements_kind_; }
4101
+ uint32_t index_offset() { return index_offset_; }
4102
+ void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; }
4103
+ HValue* GetKey() { return key(); }
4104
+ void SetKey(HValue* key) { SetOperandAt(1, key); }
4105
+ bool IsDehoisted() { return is_dehoisted_; }
4106
+ void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; }
4055
4107
 
4056
4108
  virtual Range* InferRange(Zone* zone);
4057
4109
 
@@ -4067,6 +4119,8 @@ class HLoadKeyedSpecializedArrayElement: public HTemplateInstruction<2> {
4067
4119
 
4068
4120
  private:
4069
4121
  ElementsKind elements_kind_;
4122
+ uint32_t index_offset_;
4123
+ bool is_dehoisted_;
4070
4124
  };
4071
4125
 
4072
4126
 
@@ -4144,6 +4198,10 @@ class HStoreNamedField: public HTemplateInstruction<2> {
4144
4198
  ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator());
4145
4199
  }
4146
4200
 
4201
+ bool NeedsWriteBarrierForMap() {
4202
+ return ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator());
4203
+ }
4204
+
4147
4205
  private:
4148
4206
  Handle<String> name_;
4149
4207
  bool is_in_object_;
@@ -4188,11 +4246,12 @@ class HStoreNamedGeneric: public HTemplateInstruction<3> {
4188
4246
  };
4189
4247
 
4190
4248
 
4191
- class HStoreKeyedFastElement: public HTemplateInstruction<3> {
4249
+ class HStoreKeyedFastElement
4250
+ : public HTemplateInstruction<3>, public ArrayInstructionInterface {
4192
4251
  public:
4193
4252
  HStoreKeyedFastElement(HValue* obj, HValue* key, HValue* val,
4194
4253
  ElementsKind elements_kind = FAST_ELEMENTS)
4195
- : elements_kind_(elements_kind) {
4254
+ : elements_kind_(elements_kind), index_offset_(0), is_dehoisted_(false) {
4196
4255
  SetOperandAt(0, obj);
4197
4256
  SetOperandAt(1, key);
4198
4257
  SetOperandAt(2, val);
@@ -4210,8 +4269,14 @@ class HStoreKeyedFastElement: public HTemplateInstruction<3> {
4210
4269
  HValue* key() { return OperandAt(1); }
4211
4270
  HValue* value() { return OperandAt(2); }
4212
4271
  bool value_is_smi() {
4213
- return elements_kind_ == FAST_SMI_ONLY_ELEMENTS;
4272
+ return IsFastSmiElementsKind(elements_kind_);
4214
4273
  }
4274
+ uint32_t index_offset() { return index_offset_; }
4275
+ void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; }
4276
+ HValue* GetKey() { return key(); }
4277
+ void SetKey(HValue* key) { SetOperandAt(1, key); }
4278
+ bool IsDehoisted() { return is_dehoisted_; }
4279
+ void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; }
4215
4280
 
4216
4281
  bool NeedsWriteBarrier() {
4217
4282
  if (value_is_smi()) {
@@ -4227,14 +4292,18 @@ class HStoreKeyedFastElement: public HTemplateInstruction<3> {
4227
4292
 
4228
4293
  private:
4229
4294
  ElementsKind elements_kind_;
4295
+ uint32_t index_offset_;
4296
+ bool is_dehoisted_;
4230
4297
  };
4231
4298
 
4232
4299
 
4233
- class HStoreKeyedFastDoubleElement: public HTemplateInstruction<3> {
4300
+ class HStoreKeyedFastDoubleElement
4301
+ : public HTemplateInstruction<3>, public ArrayInstructionInterface {
4234
4302
  public:
4235
4303
  HStoreKeyedFastDoubleElement(HValue* elements,
4236
4304
  HValue* key,
4237
- HValue* val) {
4305
+ HValue* val)
4306
+ : index_offset_(0), is_dehoisted_(false) {
4238
4307
  SetOperandAt(0, elements);
4239
4308
  SetOperandAt(1, key);
4240
4309
  SetOperandAt(2, val);
@@ -4254,6 +4323,12 @@ class HStoreKeyedFastDoubleElement: public HTemplateInstruction<3> {
4254
4323
  HValue* elements() { return OperandAt(0); }
4255
4324
  HValue* key() { return OperandAt(1); }
4256
4325
  HValue* value() { return OperandAt(2); }
4326
+ uint32_t index_offset() { return index_offset_; }
4327
+ void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; }
4328
+ HValue* GetKey() { return key(); }
4329
+ void SetKey(HValue* key) { SetOperandAt(1, key); }
4330
+ bool IsDehoisted() { return is_dehoisted_; }
4331
+ void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; }
4257
4332
 
4258
4333
  bool NeedsWriteBarrier() {
4259
4334
  return StoringValueNeedsWriteBarrier(value());
@@ -4264,16 +4339,21 @@ class HStoreKeyedFastDoubleElement: public HTemplateInstruction<3> {
4264
4339
  virtual void PrintDataTo(StringStream* stream);
4265
4340
 
4266
4341
  DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastDoubleElement)
4342
+
4343
+ private:
4344
+ uint32_t index_offset_;
4345
+ bool is_dehoisted_;
4267
4346
  };
4268
4347
 
4269
4348
 
4270
- class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> {
4349
+ class HStoreKeyedSpecializedArrayElement
4350
+ : public HTemplateInstruction<3>, public ArrayInstructionInterface {
4271
4351
  public:
4272
4352
  HStoreKeyedSpecializedArrayElement(HValue* external_elements,
4273
4353
  HValue* key,
4274
4354
  HValue* val,
4275
4355
  ElementsKind elements_kind)
4276
- : elements_kind_(elements_kind) {
4356
+ : elements_kind_(elements_kind), index_offset_(0), is_dehoisted_(false) {
4277
4357
  SetGVNFlag(kChangesSpecializedArrayElements);
4278
4358
  SetOperandAt(0, external_elements);
4279
4359
  SetOperandAt(1, key);
@@ -4301,11 +4381,19 @@ class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> {
4301
4381
  HValue* key() { return OperandAt(1); }
4302
4382
  HValue* value() { return OperandAt(2); }
4303
4383
  ElementsKind elements_kind() const { return elements_kind_; }
4384
+ uint32_t index_offset() { return index_offset_; }
4385
+ void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; }
4386
+ HValue* GetKey() { return key(); }
4387
+ void SetKey(HValue* key) { SetOperandAt(1, key); }
4388
+ bool IsDehoisted() { return is_dehoisted_; }
4389
+ void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; }
4304
4390
 
4305
4391
  DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement)
4306
4392
 
4307
4393
  private:
4308
4394
  ElementsKind elements_kind_;
4395
+ uint32_t index_offset_;
4396
+ bool is_dehoisted_;
4309
4397
  };
4310
4398
 
4311
4399
 
@@ -4352,9 +4440,19 @@ class HTransitionElementsKind: public HTemplateInstruction<1> {
4352
4440
  transitioned_map_(transitioned_map) {
4353
4441
  SetOperandAt(0, object);
4354
4442
  SetFlag(kUseGVN);
4443
+ // Don't set GVN DependOn flags here. That would defeat GVN's detection of
4444
+ // congruent HTransitionElementsKind instructions. Instruction hoisting
4445
+ // handles HTransitionElementsKind instruction specially, explicitly adding
4446
+ // DependsOn flags during its dependency calculations.
4355
4447
  SetGVNFlag(kChangesElementsKind);
4356
- SetGVNFlag(kChangesElementsPointer);
4357
- SetGVNFlag(kChangesNewSpacePromotion);
4448
+ if (original_map->has_fast_double_elements()) {
4449
+ SetGVNFlag(kChangesElementsPointer);
4450
+ SetGVNFlag(kChangesNewSpacePromotion);
4451
+ }
4452
+ if (transitioned_map->has_fast_double_elements()) {
4453
+ SetGVNFlag(kChangesElementsPointer);
4454
+ SetGVNFlag(kChangesNewSpacePromotion);
4455
+ }
4358
4456
  set_representation(Representation::Tagged());
4359
4457
  }
4360
4458
 
@@ -4592,7 +4690,7 @@ class HArrayLiteral: public HMaterializedLiteral<1> {
4592
4690
  HValue* context() { return OperandAt(0); }
4593
4691
  ElementsKind boilerplate_elements_kind() const {
4594
4692
  if (!boilerplate_object_->IsJSObject()) {
4595
- return FAST_ELEMENTS;
4693
+ return TERMINAL_FAST_ELEMENTS_KIND;
4596
4694
  }
4597
4695
  return Handle<JSObject>::cast(boilerplate_object_)->GetElementsKind();
4598
4696
  }