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
@@ -769,25 +769,25 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
769
769
  __ CompareRoot(r9, Heap::kHeapNumberMapRootIndex);
770
770
  __ j(not_equal, &non_double_value);
771
771
 
772
- // Value is a double. Transition FAST_SMI_ONLY_ELEMENTS ->
772
+ // Value is a double. Transition FAST_SMI_ELEMENTS ->
773
773
  // FAST_DOUBLE_ELEMENTS and complete the store.
774
- __ LoadTransitionedArrayMapConditional(FAST_SMI_ONLY_ELEMENTS,
774
+ __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
775
775
  FAST_DOUBLE_ELEMENTS,
776
776
  rbx,
777
777
  rdi,
778
778
  &slow);
779
- ElementsTransitionGenerator::GenerateSmiOnlyToDouble(masm, &slow);
779
+ ElementsTransitionGenerator::GenerateSmiToDouble(masm, &slow);
780
780
  __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
781
781
  __ jmp(&fast_double_without_map_check);
782
782
 
783
783
  __ bind(&non_double_value);
784
- // Value is not a double, FAST_SMI_ONLY_ELEMENTS -> FAST_ELEMENTS
785
- __ LoadTransitionedArrayMapConditional(FAST_SMI_ONLY_ELEMENTS,
784
+ // Value is not a double, FAST_SMI_ELEMENTS -> FAST_ELEMENTS
785
+ __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
786
786
  FAST_ELEMENTS,
787
787
  rbx,
788
788
  rdi,
789
789
  &slow);
790
- ElementsTransitionGenerator::GenerateSmiOnlyToObject(masm);
790
+ ElementsTransitionGenerator::GenerateMapChangeElementsTransition(masm);
791
791
  __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
792
792
  __ jmp(&finish_object_store);
793
793
 
@@ -1642,7 +1642,7 @@ void KeyedStoreIC::GenerateTransitionElementsSmiToDouble(MacroAssembler* masm) {
1642
1642
  // Must return the modified receiver in eax.
1643
1643
  if (!FLAG_trace_elements_transitions) {
1644
1644
  Label fail;
1645
- ElementsTransitionGenerator::GenerateSmiOnlyToDouble(masm, &fail);
1645
+ ElementsTransitionGenerator::GenerateSmiToDouble(masm, &fail);
1646
1646
  __ movq(rax, rdx);
1647
1647
  __ Ret();
1648
1648
  __ bind(&fail);
@@ -1741,11 +1741,11 @@ void CompareIC::UpdateCaches(Handle<Object> x, Handle<Object> y) {
1741
1741
 
1742
1742
  // Activate inlined smi code.
1743
1743
  if (previous_state == UNINITIALIZED) {
1744
- PatchInlinedSmiCode(address());
1744
+ PatchInlinedSmiCode(address(), ENABLE_INLINED_SMI_CHECK);
1745
1745
  }
1746
1746
  }
1747
1747
 
1748
- void PatchInlinedSmiCode(Address address) {
1748
+ void PatchInlinedSmiCode(Address address, InlinedSmiCheck check) {
1749
1749
  // The address of the instruction following the call.
1750
1750
  Address test_instruction_address =
1751
1751
  address + Assembler::kCallTargetAddressOffset;
@@ -1766,14 +1766,18 @@ void PatchInlinedSmiCode(Address address) {
1766
1766
  address, test_instruction_address, delta);
1767
1767
  }
1768
1768
 
1769
- // Patch with a short conditional jump. There must be a
1770
- // short jump-if-carry/not-carry at this position.
1769
+ // Patch with a short conditional jump. Enabling means switching from a short
1770
+ // jump-if-carry/not-carry to jump-if-zero/not-zero, whereas disabling is the
1771
+ // reverse operation of that.
1771
1772
  Address jmp_address = test_instruction_address - delta;
1772
- ASSERT(*jmp_address == Assembler::kJncShortOpcode ||
1773
- *jmp_address == Assembler::kJcShortOpcode);
1774
- Condition cc = *jmp_address == Assembler::kJncShortOpcode
1775
- ? not_zero
1776
- : zero;
1773
+ ASSERT((check == ENABLE_INLINED_SMI_CHECK)
1774
+ ? (*jmp_address == Assembler::kJncShortOpcode ||
1775
+ *jmp_address == Assembler::kJcShortOpcode)
1776
+ : (*jmp_address == Assembler::kJnzShortOpcode ||
1777
+ *jmp_address == Assembler::kJzShortOpcode));
1778
+ Condition cc = (check == ENABLE_INLINED_SMI_CHECK)
1779
+ ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero)
1780
+ : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry);
1777
1781
  *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc);
1778
1782
  }
1779
1783
 
@@ -2223,41 +2223,35 @@ void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) {
2223
2223
  Register result = ToRegister(instr->result());
2224
2224
 
2225
2225
  int map_count = instr->hydrogen()->types()->length();
2226
- Handle<String> name = instr->hydrogen()->name();
2226
+ bool need_generic = instr->hydrogen()->need_generic();
2227
2227
 
2228
- if (map_count == 0) {
2229
- ASSERT(instr->hydrogen()->need_generic());
2230
- __ Move(rcx, instr->hydrogen()->name());
2231
- Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
2232
- CallCode(ic, RelocInfo::CODE_TARGET, instr);
2233
- } else {
2234
- Label done;
2235
- for (int i = 0; i < map_count - 1; ++i) {
2236
- Handle<Map> map = instr->hydrogen()->types()->at(i);
2228
+ if (map_count == 0 && !need_generic) {
2229
+ DeoptimizeIf(no_condition, instr->environment());
2230
+ return;
2231
+ }
2232
+ Handle<String> name = instr->hydrogen()->name();
2233
+ Label done;
2234
+ for (int i = 0; i < map_count; ++i) {
2235
+ bool last = (i == map_count - 1);
2236
+ Handle<Map> map = instr->hydrogen()->types()->at(i);
2237
+ __ Cmp(FieldOperand(object, HeapObject::kMapOffset), map);
2238
+ if (last && !need_generic) {
2239
+ DeoptimizeIf(not_equal, instr->environment());
2240
+ EmitLoadFieldOrConstantFunction(result, object, map, name);
2241
+ } else {
2237
2242
  Label next;
2238
- __ Cmp(FieldOperand(object, HeapObject::kMapOffset), map);
2239
2243
  __ j(not_equal, &next, Label::kNear);
2240
2244
  EmitLoadFieldOrConstantFunction(result, object, map, name);
2241
2245
  __ jmp(&done, Label::kNear);
2242
2246
  __ bind(&next);
2243
2247
  }
2244
- Handle<Map> map = instr->hydrogen()->types()->last();
2245
- __ Cmp(FieldOperand(object, HeapObject::kMapOffset), map);
2246
- if (instr->hydrogen()->need_generic()) {
2247
- Label generic;
2248
- __ j(not_equal, &generic, Label::kNear);
2249
- EmitLoadFieldOrConstantFunction(result, object, map, name);
2250
- __ jmp(&done, Label::kNear);
2251
- __ bind(&generic);
2252
- __ Move(rcx, instr->hydrogen()->name());
2253
- Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
2254
- CallCode(ic, RelocInfo::CODE_TARGET, instr);
2255
- } else {
2256
- DeoptimizeIf(not_equal, instr->environment());
2257
- EmitLoadFieldOrConstantFunction(result, object, map, name);
2258
- }
2259
- __ bind(&done);
2260
2248
  }
2249
+ if (need_generic) {
2250
+ __ Move(rcx, name);
2251
+ Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
2252
+ CallCode(ic, RelocInfo::CODE_TARGET, instr);
2253
+ }
2254
+ __ bind(&done);
2261
2255
  }
2262
2256
 
2263
2257
 
@@ -2330,8 +2324,10 @@ void LCodeGen::DoLoadElements(LLoadElements* instr) {
2330
2324
  __ movzxbq(temp, FieldOperand(temp, Map::kBitField2Offset));
2331
2325
  __ and_(temp, Immediate(Map::kElementsKindMask));
2332
2326
  __ shr(temp, Immediate(Map::kElementsKindShift));
2333
- __ cmpl(temp, Immediate(FAST_ELEMENTS));
2334
- __ j(equal, &ok, Label::kNear);
2327
+ __ cmpl(temp, Immediate(GetInitialFastElementsKind()));
2328
+ __ j(less, &fail, Label::kNear);
2329
+ __ cmpl(temp, Immediate(TERMINAL_FAST_ELEMENTS_KIND));
2330
+ __ j(less_equal, &ok, Label::kNear);
2335
2331
  __ cmpl(temp, Immediate(FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND));
2336
2332
  __ j(less, &fail, Label::kNear);
2337
2333
  __ cmpl(temp, Immediate(LAST_EXTERNAL_ARRAY_ELEMENTS_KIND));
@@ -2375,11 +2371,20 @@ void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
2375
2371
  void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) {
2376
2372
  Register result = ToRegister(instr->result());
2377
2373
 
2374
+ if (instr->hydrogen()->IsDehoisted() && !instr->key()->IsConstantOperand()) {
2375
+ // Sign extend key because it could be a 32 bit negative value
2376
+ // and the dehoisted address computation happens in 64 bits.
2377
+ Register key_reg = ToRegister(instr->key());
2378
+ __ movsxlq(key_reg, key_reg);
2379
+ }
2380
+
2378
2381
  // Load the result.
2379
2382
  __ movq(result,
2380
- BuildFastArrayOperand(instr->elements(), instr->key(),
2383
+ BuildFastArrayOperand(instr->elements(),
2384
+ instr->key(),
2381
2385
  FAST_ELEMENTS,
2382
- FixedArray::kHeaderSize - kHeapObjectTag));
2386
+ FixedArray::kHeaderSize - kHeapObjectTag,
2387
+ instr->additional_index()));
2383
2388
 
2384
2389
  // Check for the hole value.
2385
2390
  if (instr->hydrogen()->RequiresHoleCheck()) {
@@ -2393,19 +2398,32 @@ void LCodeGen::DoLoadKeyedFastDoubleElement(
2393
2398
  LLoadKeyedFastDoubleElement* instr) {
2394
2399
  XMMRegister result(ToDoubleRegister(instr->result()));
2395
2400
 
2396
- int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag +
2397
- sizeof(kHoleNanLower32);
2398
- Operand hole_check_operand = BuildFastArrayOperand(
2401
+ if (instr->hydrogen()->IsDehoisted() && !instr->key()->IsConstantOperand()) {
2402
+ // Sign extend key because it could be a 32 bit negative value
2403
+ // and the dehoisted address computation happens in 64 bits
2404
+ Register key_reg = ToRegister(instr->key());
2405
+ __ movsxlq(key_reg, key_reg);
2406
+ }
2407
+
2408
+ if (instr->hydrogen()->RequiresHoleCheck()) {
2409
+ int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag +
2410
+ sizeof(kHoleNanLower32);
2411
+ Operand hole_check_operand = BuildFastArrayOperand(
2412
+ instr->elements(),
2413
+ instr->key(),
2414
+ FAST_DOUBLE_ELEMENTS,
2415
+ offset,
2416
+ instr->additional_index());
2417
+ __ cmpl(hole_check_operand, Immediate(kHoleNanUpper32));
2418
+ DeoptimizeIf(equal, instr->environment());
2419
+ }
2420
+
2421
+ Operand double_load_operand = BuildFastArrayOperand(
2399
2422
  instr->elements(),
2400
2423
  instr->key(),
2401
2424
  FAST_DOUBLE_ELEMENTS,
2402
- offset);
2403
- __ cmpl(hole_check_operand, Immediate(kHoleNanUpper32));
2404
- DeoptimizeIf(equal, instr->environment());
2405
-
2406
- Operand double_load_operand = BuildFastArrayOperand(
2407
- instr->elements(), instr->key(), FAST_DOUBLE_ELEMENTS,
2408
- FixedDoubleArray::kHeaderSize - kHeapObjectTag);
2425
+ FixedDoubleArray::kHeaderSize - kHeapObjectTag,
2426
+ instr->additional_index());
2409
2427
  __ movsd(result, double_load_operand);
2410
2428
  }
2411
2429
 
@@ -2414,7 +2432,8 @@ Operand LCodeGen::BuildFastArrayOperand(
2414
2432
  LOperand* elements_pointer,
2415
2433
  LOperand* key,
2416
2434
  ElementsKind elements_kind,
2417
- uint32_t offset) {
2435
+ uint32_t offset,
2436
+ uint32_t additional_index) {
2418
2437
  Register elements_pointer_reg = ToRegister(elements_pointer);
2419
2438
  int shift_size = ElementsKindToShiftSize(elements_kind);
2420
2439
  if (key->IsConstantOperand()) {
@@ -2423,11 +2442,14 @@ Operand LCodeGen::BuildFastArrayOperand(
2423
2442
  Abort("array index constant value too big");
2424
2443
  }
2425
2444
  return Operand(elements_pointer_reg,
2426
- constant_value * (1 << shift_size) + offset);
2445
+ ((constant_value + additional_index) << shift_size)
2446
+ + offset);
2427
2447
  } else {
2428
2448
  ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size);
2429
- return Operand(elements_pointer_reg, ToRegister(key),
2430
- scale_factor, offset);
2449
+ return Operand(elements_pointer_reg,
2450
+ ToRegister(key),
2451
+ scale_factor,
2452
+ offset + (additional_index << shift_size));
2431
2453
  }
2432
2454
  }
2433
2455
 
@@ -2436,7 +2458,17 @@ void LCodeGen::DoLoadKeyedSpecializedArrayElement(
2436
2458
  LLoadKeyedSpecializedArrayElement* instr) {
2437
2459
  ElementsKind elements_kind = instr->elements_kind();
2438
2460
  Operand operand(BuildFastArrayOperand(instr->external_pointer(),
2439
- instr->key(), elements_kind, 0));
2461
+ instr->key(),
2462
+ elements_kind,
2463
+ 0,
2464
+ instr->additional_index()));
2465
+ if (instr->hydrogen()->IsDehoisted() && !instr->key()->IsConstantOperand()) {
2466
+ // Sign extend key because it could be a 32 bit negative value
2467
+ // and the dehoisted address computation happens in 64 bits
2468
+ Register key_reg = ToRegister(instr->key());
2469
+ __ movsxlq(key_reg, key_reg);
2470
+ }
2471
+
2440
2472
  if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
2441
2473
  XMMRegister result(ToDoubleRegister(instr->result()));
2442
2474
  __ movss(result, operand);
@@ -2473,8 +2505,11 @@ void LCodeGen::DoLoadKeyedSpecializedArrayElement(
2473
2505
  case EXTERNAL_FLOAT_ELEMENTS:
2474
2506
  case EXTERNAL_DOUBLE_ELEMENTS:
2475
2507
  case FAST_ELEMENTS:
2476
- case FAST_SMI_ONLY_ELEMENTS:
2508
+ case FAST_SMI_ELEMENTS:
2477
2509
  case FAST_DOUBLE_ELEMENTS:
2510
+ case FAST_HOLEY_ELEMENTS:
2511
+ case FAST_HOLEY_SMI_ELEMENTS:
2512
+ case FAST_HOLEY_DOUBLE_ELEMENTS:
2478
2513
  case DICTIONARY_ELEMENTS:
2479
2514
  case NON_STRICT_ARGUMENTS_ELEMENTS:
2480
2515
  UNREACHABLE();
@@ -3283,7 +3318,22 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
3283
3318
  int offset = instr->offset();
3284
3319
 
3285
3320
  if (!instr->transition().is_null()) {
3286
- __ Move(FieldOperand(object, HeapObject::kMapOffset), instr->transition());
3321
+ if (!instr->hydrogen()->NeedsWriteBarrierForMap()) {
3322
+ __ Move(FieldOperand(object, HeapObject::kMapOffset),
3323
+ instr->transition());
3324
+ } else {
3325
+ Register temp = ToRegister(instr->TempAt(0));
3326
+ __ Move(kScratchRegister, instr->transition());
3327
+ __ movq(FieldOperand(object, HeapObject::kMapOffset), kScratchRegister);
3328
+ // Update the write barrier for the map field.
3329
+ __ RecordWriteField(object,
3330
+ HeapObject::kMapOffset,
3331
+ kScratchRegister,
3332
+ temp,
3333
+ kSaveFPRegs,
3334
+ OMIT_REMEMBERED_SET,
3335
+ OMIT_SMI_CHECK);
3336
+ }
3287
3337
  }
3288
3338
 
3289
3339
  // Do the store.
@@ -3338,7 +3388,18 @@ void LCodeGen::DoStoreKeyedSpecializedArrayElement(
3338
3388
  LStoreKeyedSpecializedArrayElement* instr) {
3339
3389
  ElementsKind elements_kind = instr->elements_kind();
3340
3390
  Operand operand(BuildFastArrayOperand(instr->external_pointer(),
3341
- instr->key(), elements_kind, 0));
3391
+ instr->key(),
3392
+ elements_kind,
3393
+ 0,
3394
+ instr->additional_index()));
3395
+
3396
+ if (instr->hydrogen()->IsDehoisted() && !instr->key()->IsConstantOperand()) {
3397
+ // Sign extend key because it could be a 32 bit negative value
3398
+ // and the dehoisted address computation happens in 64 bits
3399
+ Register key_reg = ToRegister(instr->key());
3400
+ __ movsxlq(key_reg, key_reg);
3401
+ }
3402
+
3342
3403
  if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
3343
3404
  XMMRegister value(ToDoubleRegister(instr->value()));
3344
3405
  __ cvtsd2ss(value, value);
@@ -3364,8 +3425,11 @@ void LCodeGen::DoStoreKeyedSpecializedArrayElement(
3364
3425
  case EXTERNAL_FLOAT_ELEMENTS:
3365
3426
  case EXTERNAL_DOUBLE_ELEMENTS:
3366
3427
  case FAST_ELEMENTS:
3367
- case FAST_SMI_ONLY_ELEMENTS:
3428
+ case FAST_SMI_ELEMENTS:
3368
3429
  case FAST_DOUBLE_ELEMENTS:
3430
+ case FAST_HOLEY_ELEMENTS:
3431
+ case FAST_HOLEY_SMI_ELEMENTS:
3432
+ case FAST_HOLEY_DOUBLE_ELEMENTS:
3369
3433
  case DICTIONARY_ELEMENTS:
3370
3434
  case NON_STRICT_ARGUMENTS_ELEMENTS:
3371
3435
  UNREACHABLE();
@@ -3408,30 +3472,29 @@ void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) {
3408
3472
  Register elements = ToRegister(instr->object());
3409
3473
  Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg;
3410
3474
 
3411
- // Do the store.
3412
- if (instr->key()->IsConstantOperand()) {
3413
- ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
3414
- LConstantOperand* const_operand = LConstantOperand::cast(instr->key());
3415
- int offset =
3416
- ToInteger32(const_operand) * kPointerSize + FixedArray::kHeaderSize;
3417
- __ movq(FieldOperand(elements, offset), value);
3418
- } else {
3419
- __ movq(FieldOperand(elements,
3420
- key,
3421
- times_pointer_size,
3422
- FixedArray::kHeaderSize),
3423
- value);
3475
+ Operand operand =
3476
+ BuildFastArrayOperand(instr->object(),
3477
+ instr->key(),
3478
+ FAST_ELEMENTS,
3479
+ FixedArray::kHeaderSize - kHeapObjectTag,
3480
+ instr->additional_index());
3481
+
3482
+ if (instr->hydrogen()->IsDehoisted() && !instr->key()->IsConstantOperand()) {
3483
+ // Sign extend key because it could be a 32 bit negative value
3484
+ // and the dehoisted address computation happens in 64 bits
3485
+ Register key_reg = ToRegister(instr->key());
3486
+ __ movsxlq(key_reg, key_reg);
3424
3487
  }
3425
3488
 
3489
+ __ movq(operand, value);
3490
+
3426
3491
  if (instr->hydrogen()->NeedsWriteBarrier()) {
3492
+ ASSERT(!instr->key()->IsConstantOperand());
3427
3493
  HType type = instr->hydrogen()->value()->type();
3428
3494
  SmiCheck check_needed =
3429
3495
  type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
3430
3496
  // Compute address of modified element and store it into key register.
3431
- __ lea(key, FieldOperand(elements,
3432
- key,
3433
- times_pointer_size,
3434
- FixedArray::kHeaderSize));
3497
+ __ lea(key, operand);
3435
3498
  __ RecordWrite(elements,
3436
3499
  key,
3437
3500
  value,
@@ -3460,8 +3523,19 @@ void LCodeGen::DoStoreKeyedFastDoubleElement(
3460
3523
  }
3461
3524
 
3462
3525
  Operand double_store_operand = BuildFastArrayOperand(
3463
- instr->elements(), instr->key(), FAST_DOUBLE_ELEMENTS,
3464
- FixedDoubleArray::kHeaderSize - kHeapObjectTag);
3526
+ instr->elements(),
3527
+ instr->key(),
3528
+ FAST_DOUBLE_ELEMENTS,
3529
+ FixedDoubleArray::kHeaderSize - kHeapObjectTag,
3530
+ instr->additional_index());
3531
+
3532
+ if (instr->hydrogen()->IsDehoisted() && !instr->key()->IsConstantOperand()) {
3533
+ // Sign extend key because it could be a 32 bit negative value
3534
+ // and the dehoisted address computation happens in 64 bits
3535
+ Register key_reg = ToRegister(instr->key());
3536
+ __ movsxlq(key_reg, key_reg);
3537
+ }
3538
+
3465
3539
  __ movsd(double_store_operand, value);
3466
3540
  }
3467
3541
 
@@ -3490,21 +3564,22 @@ void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
3490
3564
  __ Cmp(FieldOperand(object_reg, HeapObject::kMapOffset), from_map);
3491
3565
  __ j(not_equal, &not_applicable);
3492
3566
  __ movq(new_map_reg, to_map, RelocInfo::EMBEDDED_OBJECT);
3493
- if (from_kind == FAST_SMI_ONLY_ELEMENTS && to_kind == FAST_ELEMENTS) {
3567
+ if (IsSimpleMapChangeTransition(from_kind, to_kind)) {
3494
3568
  __ movq(FieldOperand(object_reg, HeapObject::kMapOffset), new_map_reg);
3495
3569
  // Write barrier.
3496
3570
  ASSERT_NE(instr->temp_reg(), NULL);
3497
3571
  __ RecordWriteField(object_reg, HeapObject::kMapOffset, new_map_reg,
3498
3572
  ToRegister(instr->temp_reg()), kDontSaveFPRegs);
3499
- } else if (from_kind == FAST_SMI_ONLY_ELEMENTS &&
3500
- to_kind == FAST_DOUBLE_ELEMENTS) {
3573
+ } else if (IsFastSmiElementsKind(from_kind) &&
3574
+ IsFastDoubleElementsKind(to_kind)) {
3501
3575
  Register fixed_object_reg = ToRegister(instr->temp_reg());
3502
3576
  ASSERT(fixed_object_reg.is(rdx));
3503
3577
  ASSERT(new_map_reg.is(rbx));
3504
3578
  __ movq(fixed_object_reg, object_reg);
3505
3579
  CallCode(isolate()->builtins()->TransitionElementsSmiToDouble(),
3506
3580
  RelocInfo::CODE_TARGET, instr);
3507
- } else if (from_kind == FAST_DOUBLE_ELEMENTS && to_kind == FAST_ELEMENTS) {
3581
+ } else if (IsFastDoubleElementsKind(from_kind) &&
3582
+ IsFastObjectElementsKind(to_kind)) {
3508
3583
  Register fixed_object_reg = ToRegister(instr->temp_reg());
3509
3584
  ASSERT(fixed_object_reg.is(rdx));
3510
3585
  ASSERT(new_map_reg.is(rbx));
@@ -4178,8 +4253,9 @@ void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) {
4178
4253
 
4179
4254
  // Deopt if the array literal boilerplate ElementsKind is of a type different
4180
4255
  // than the expected one. The check isn't necessary if the boilerplate has
4181
- // already been converted to FAST_ELEMENTS.
4182
- if (boilerplate_elements_kind != FAST_ELEMENTS) {
4256
+ // already been converted to TERMINAL_FAST_ELEMENTS_KIND.
4257
+ if (CanTransitionToMoreGeneralFastElementsKind(
4258
+ boilerplate_elements_kind, true)) {
4183
4259
  __ LoadHeapObject(rax, instr->hydrogen()->boilerplate_object());
4184
4260
  __ movq(rbx, FieldOperand(rax, HeapObject::kMapOffset));
4185
4261
  // Load the map's "bit field 2".
@@ -4325,10 +4401,11 @@ void LCodeGen::DoFastLiteral(LFastLiteral* instr) {
4325
4401
  ElementsKind boilerplate_elements_kind =
4326
4402
  instr->hydrogen()->boilerplate()->GetElementsKind();
4327
4403
 
4328
- // Deopt if the literal boilerplate ElementsKind is of a type different than
4329
- // the expected one. The check isn't necessary if the boilerplate has already
4330
- // been converted to FAST_ELEMENTS.
4331
- if (boilerplate_elements_kind != FAST_ELEMENTS) {
4404
+ // Deopt if the array literal boilerplate ElementsKind is of a type different
4405
+ // than the expected one. The check isn't necessary if the boilerplate has
4406
+ // already been converted to TERMINAL_FAST_ELEMENTS_KIND.
4407
+ if (CanTransitionToMoreGeneralFastElementsKind(
4408
+ boilerplate_elements_kind, true)) {
4332
4409
  __ LoadHeapObject(rbx, instr->hydrogen()->boilerplate());
4333
4410
  __ movq(rcx, FieldOperand(rbx, HeapObject::kMapOffset));
4334
4411
  // Load the map's "bit field 2".