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
@@ -231,7 +231,8 @@ class LCodeGen BASE_EMBEDDED {
231
231
  LOperand* elements_pointer,
232
232
  LOperand* key,
233
233
  ElementsKind elements_kind,
234
- uint32_t offset);
234
+ uint32_t offset,
235
+ uint32_t additional_index = 0);
235
236
 
236
237
  // Specific math operations - used from DoUnaryMathOperation.
237
238
  void EmitIntegerMathAbs(LUnaryMathOperation* instr);
@@ -2012,8 +2012,9 @@ LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) {
2012
2012
 
2013
2013
  LInstruction* LChunkBuilder::DoTransitionElementsKind(
2014
2014
  HTransitionElementsKind* instr) {
2015
- if (instr->original_map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS &&
2016
- instr->transitioned_map()->elements_kind() == FAST_ELEMENTS) {
2015
+ ElementsKind from_kind = instr->original_map()->elements_kind();
2016
+ ElementsKind to_kind = instr->transitioned_map()->elements_kind();
2017
+ if (IsSimpleMapChangeTransition(from_kind, to_kind)) {
2017
2018
  LOperand* object = UseRegister(instr->object());
2018
2019
  LOperand* new_map_reg = TempRegister();
2019
2020
  LOperand* temp_reg = TempRegister();
@@ -2035,10 +2036,19 @@ LInstruction* LChunkBuilder::DoTransitionElementsKind(
2035
2036
 
2036
2037
  LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
2037
2038
  bool needs_write_barrier = instr->NeedsWriteBarrier();
2038
-
2039
- LOperand* obj = needs_write_barrier
2040
- ? UseTempRegister(instr->object())
2041
- : UseRegisterAtStart(instr->object());
2039
+ bool needs_write_barrier_for_map = !instr->transition().is_null() &&
2040
+ instr->NeedsWriteBarrierForMap();
2041
+
2042
+ LOperand* obj;
2043
+ if (needs_write_barrier) {
2044
+ obj = instr->is_in_object()
2045
+ ? UseRegister(instr->object())
2046
+ : UseTempRegister(instr->object());
2047
+ } else {
2048
+ obj = needs_write_barrier_for_map
2049
+ ? UseRegister(instr->object())
2050
+ : UseRegisterAtStart(instr->object());
2051
+ }
2042
2052
 
2043
2053
  LOperand* val = needs_write_barrier
2044
2054
  ? UseTempRegister(instr->value())
@@ -2046,8 +2056,8 @@ LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
2046
2056
 
2047
2057
  // We only need a scratch register if we have a write barrier or we
2048
2058
  // have a store into the properties array (not in-object-property).
2049
- LOperand* temp = (!instr->is_in_object() || needs_write_barrier)
2050
- ? TempRegister() : NULL;
2059
+ LOperand* temp = (!instr->is_in_object() || needs_write_barrier ||
2060
+ needs_write_barrier_for_map) ? TempRegister() : NULL;
2051
2061
 
2052
2062
  return new(zone()) LStoreNamedField(obj, val, temp);
2053
2063
  }
@@ -1199,6 +1199,7 @@ class LLoadKeyedFastElement: public LTemplateInstruction<1, 2, 0> {
1199
1199
 
1200
1200
  LOperand* elements() { return inputs_[0]; }
1201
1201
  LOperand* key() { return inputs_[1]; }
1202
+ uint32_t additional_index() const { return hydrogen()->index_offset(); }
1202
1203
  };
1203
1204
 
1204
1205
 
@@ -1215,13 +1216,13 @@ class LLoadKeyedFastDoubleElement: public LTemplateInstruction<1, 2, 0> {
1215
1216
 
1216
1217
  LOperand* elements() { return inputs_[0]; }
1217
1218
  LOperand* key() { return inputs_[1]; }
1219
+ uint32_t additional_index() const { return hydrogen()->index_offset(); }
1218
1220
  };
1219
1221
 
1220
1222
 
1221
1223
  class LLoadKeyedSpecializedArrayElement: public LTemplateInstruction<1, 2, 0> {
1222
1224
  public:
1223
- LLoadKeyedSpecializedArrayElement(LOperand* external_pointer,
1224
- LOperand* key) {
1225
+ LLoadKeyedSpecializedArrayElement(LOperand* external_pointer, LOperand* key) {
1225
1226
  inputs_[0] = external_pointer;
1226
1227
  inputs_[1] = key;
1227
1228
  }
@@ -1235,6 +1236,7 @@ class LLoadKeyedSpecializedArrayElement: public LTemplateInstruction<1, 2, 0> {
1235
1236
  ElementsKind elements_kind() const {
1236
1237
  return hydrogen()->elements_kind();
1237
1238
  }
1239
+ uint32_t additional_index() const { return hydrogen()->index_offset(); }
1238
1240
  };
1239
1241
 
1240
1242
 
@@ -1692,6 +1694,7 @@ class LStoreKeyedFastElement: public LTemplateInstruction<0, 3, 0> {
1692
1694
  LOperand* object() { return inputs_[0]; }
1693
1695
  LOperand* key() { return inputs_[1]; }
1694
1696
  LOperand* value() { return inputs_[2]; }
1697
+ uint32_t additional_index() const { return hydrogen()->index_offset(); }
1695
1698
  };
1696
1699
 
1697
1700
 
@@ -1716,6 +1719,7 @@ class LStoreKeyedFastDoubleElement: public LTemplateInstruction<0, 3, 0> {
1716
1719
  LOperand* value() { return inputs_[2]; }
1717
1720
 
1718
1721
  bool NeedsCanonicalization() { return hydrogen()->NeedsCanonicalization(); }
1722
+ uint32_t additional_index() const { return hydrogen()->index_offset(); }
1719
1723
  };
1720
1724
 
1721
1725
 
@@ -1739,6 +1743,7 @@ class LStoreKeyedSpecializedArrayElement: public LTemplateInstruction<0, 3, 0> {
1739
1743
  ElementsKind elements_kind() const {
1740
1744
  return hydrogen()->elements_kind();
1741
1745
  }
1746
+ uint32_t additional_index() const { return hydrogen()->index_offset(); }
1742
1747
  };
1743
1748
 
1744
1749
 
@@ -2658,10 +2658,12 @@ void MacroAssembler::CmpInstanceType(Register map, InstanceType type) {
2658
2658
  void MacroAssembler::CheckFastElements(Register map,
2659
2659
  Label* fail,
2660
2660
  Label::Distance distance) {
2661
- STATIC_ASSERT(FAST_SMI_ONLY_ELEMENTS == 0);
2662
- STATIC_ASSERT(FAST_ELEMENTS == 1);
2661
+ STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
2662
+ STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
2663
+ STATIC_ASSERT(FAST_ELEMENTS == 2);
2664
+ STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3);
2663
2665
  cmpb(FieldOperand(map, Map::kBitField2Offset),
2664
- Immediate(Map::kMaximumBitField2FastElementValue));
2666
+ Immediate(Map::kMaximumBitField2FastHoleyElementValue));
2665
2667
  j(above, fail, distance);
2666
2668
  }
2667
2669
 
@@ -2669,23 +2671,26 @@ void MacroAssembler::CheckFastElements(Register map,
2669
2671
  void MacroAssembler::CheckFastObjectElements(Register map,
2670
2672
  Label* fail,
2671
2673
  Label::Distance distance) {
2672
- STATIC_ASSERT(FAST_SMI_ONLY_ELEMENTS == 0);
2673
- STATIC_ASSERT(FAST_ELEMENTS == 1);
2674
+ STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
2675
+ STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
2676
+ STATIC_ASSERT(FAST_ELEMENTS == 2);
2677
+ STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3);
2674
2678
  cmpb(FieldOperand(map, Map::kBitField2Offset),
2675
- Immediate(Map::kMaximumBitField2FastSmiOnlyElementValue));
2679
+ Immediate(Map::kMaximumBitField2FastHoleySmiElementValue));
2676
2680
  j(below_equal, fail, distance);
2677
2681
  cmpb(FieldOperand(map, Map::kBitField2Offset),
2678
- Immediate(Map::kMaximumBitField2FastElementValue));
2682
+ Immediate(Map::kMaximumBitField2FastHoleyElementValue));
2679
2683
  j(above, fail, distance);
2680
2684
  }
2681
2685
 
2682
2686
 
2683
- void MacroAssembler::CheckFastSmiOnlyElements(Register map,
2684
- Label* fail,
2685
- Label::Distance distance) {
2686
- STATIC_ASSERT(FAST_SMI_ONLY_ELEMENTS == 0);
2687
+ void MacroAssembler::CheckFastSmiElements(Register map,
2688
+ Label* fail,
2689
+ Label::Distance distance) {
2690
+ STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
2691
+ STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
2687
2692
  cmpb(FieldOperand(map, Map::kBitField2Offset),
2688
- Immediate(Map::kMaximumBitField2FastSmiOnlyElementValue));
2693
+ Immediate(Map::kMaximumBitField2FastHoleySmiElementValue));
2689
2694
  j(above, fail, distance);
2690
2695
  }
2691
2696
 
@@ -2749,24 +2754,18 @@ void MacroAssembler::CompareMap(Register obj,
2749
2754
  CompareMapMode mode) {
2750
2755
  Cmp(FieldOperand(obj, HeapObject::kMapOffset), map);
2751
2756
  if (mode == ALLOW_ELEMENT_TRANSITION_MAPS) {
2752
- Map* transitioned_fast_element_map(
2753
- map->LookupElementsTransitionMap(FAST_ELEMENTS, NULL));
2754
- ASSERT(transitioned_fast_element_map == NULL ||
2755
- map->elements_kind() != FAST_ELEMENTS);
2756
- if (transitioned_fast_element_map != NULL) {
2757
- j(equal, early_success, Label::kNear);
2758
- Cmp(FieldOperand(obj, HeapObject::kMapOffset),
2759
- Handle<Map>(transitioned_fast_element_map));
2760
- }
2761
-
2762
- Map* transitioned_double_map(
2763
- map->LookupElementsTransitionMap(FAST_DOUBLE_ELEMENTS, NULL));
2764
- ASSERT(transitioned_double_map == NULL ||
2765
- map->elements_kind() == FAST_SMI_ONLY_ELEMENTS);
2766
- if (transitioned_double_map != NULL) {
2767
- j(equal, early_success, Label::kNear);
2768
- Cmp(FieldOperand(obj, HeapObject::kMapOffset),
2769
- Handle<Map>(transitioned_double_map));
2757
+ ElementsKind kind = map->elements_kind();
2758
+ if (IsFastElementsKind(kind)) {
2759
+ bool packed = IsFastPackedElementsKind(kind);
2760
+ Map* current_map = *map;
2761
+ while (CanTransitionToMoreGeneralFastElementsKind(kind, packed)) {
2762
+ kind = GetNextMoreGeneralFastElementsKind(kind, packed);
2763
+ current_map = current_map->LookupElementsTransitionMap(kind, NULL);
2764
+ if (!current_map) break;
2765
+ j(equal, early_success, Label::kNear);
2766
+ Cmp(FieldOperand(obj, HeapObject::kMapOffset),
2767
+ Handle<Map>(current_map));
2768
+ }
2770
2769
  }
2771
2770
  }
2772
2771
  }
@@ -4057,27 +4056,38 @@ void MacroAssembler::LoadTransitionedArrayMapConditional(
4057
4056
  movq(scratch, FieldOperand(scratch, GlobalObject::kGlobalContextOffset));
4058
4057
 
4059
4058
  // Check that the function's map is the same as the expected cached map.
4060
- int expected_index =
4061
- Context::GetContextMapIndexFromElementsKind(expected_kind);
4062
- cmpq(map_in_out, Operand(scratch, Context::SlotOffset(expected_index)));
4059
+ movq(scratch, Operand(scratch,
4060
+ Context::SlotOffset(Context::JS_ARRAY_MAPS_INDEX)));
4061
+
4062
+ int offset = expected_kind * kPointerSize +
4063
+ FixedArrayBase::kHeaderSize;
4064
+ cmpq(map_in_out, FieldOperand(scratch, offset));
4063
4065
  j(not_equal, no_map_match);
4064
4066
 
4065
4067
  // Use the transitioned cached map.
4066
- int trans_index =
4067
- Context::GetContextMapIndexFromElementsKind(transitioned_kind);
4068
- movq(map_in_out, Operand(scratch, Context::SlotOffset(trans_index)));
4068
+ offset = transitioned_kind * kPointerSize +
4069
+ FixedArrayBase::kHeaderSize;
4070
+ movq(map_in_out, FieldOperand(scratch, offset));
4069
4071
  }
4070
4072
 
4071
4073
 
4072
4074
  void MacroAssembler::LoadInitialArrayMap(
4073
- Register function_in, Register scratch, Register map_out) {
4075
+ Register function_in, Register scratch,
4076
+ Register map_out, bool can_have_holes) {
4074
4077
  ASSERT(!function_in.is(map_out));
4075
4078
  Label done;
4076
4079
  movq(map_out, FieldOperand(function_in,
4077
4080
  JSFunction::kPrototypeOrInitialMapOffset));
4078
4081
  if (!FLAG_smi_only_arrays) {
4079
- LoadTransitionedArrayMapConditional(FAST_SMI_ONLY_ELEMENTS,
4080
- FAST_ELEMENTS,
4082
+ ElementsKind kind = can_have_holes ? FAST_HOLEY_ELEMENTS : FAST_ELEMENTS;
4083
+ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
4084
+ kind,
4085
+ map_out,
4086
+ scratch,
4087
+ &done);
4088
+ } else if (can_have_holes) {
4089
+ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
4090
+ FAST_HOLEY_SMI_ELEMENTS,
4081
4091
  map_out,
4082
4092
  scratch,
4083
4093
  &done);
@@ -4188,7 +4198,7 @@ bool AreAliased(Register r1, Register r2, Register r3, Register r4) {
4188
4198
  CodePatcher::CodePatcher(byte* address, int size)
4189
4199
  : address_(address),
4190
4200
  size_(size),
4191
- masm_(Isolate::Current(), address, size + Assembler::kGap) {
4201
+ masm_(NULL, address, size + Assembler::kGap) {
4192
4202
  // Create a new macro assembler pointing to the address of the code to patch.
4193
4203
  // The size is adjusted with kGap on order for the assembler to generate size
4194
4204
  // bytes of instructions without failing with buffer size constraints.
@@ -877,9 +877,9 @@ class MacroAssembler: public Assembler {
877
877
 
878
878
  // Check if a map for a JSObject indicates that the object has fast smi only
879
879
  // elements. Jump to the specified label if it does not.
880
- void CheckFastSmiOnlyElements(Register map,
881
- Label* fail,
882
- Label::Distance distance = Label::kFar);
880
+ void CheckFastSmiElements(Register map,
881
+ Label* fail,
882
+ Label::Distance distance = Label::kFar);
883
883
 
884
884
  // Check to see if maybe_number can be stored as a double in
885
885
  // FastDoubleElements. If it can, store it at the index specified by index in
@@ -1141,7 +1141,8 @@ class MacroAssembler: public Assembler {
1141
1141
  // Load the initial map for new Arrays from a JSFunction.
1142
1142
  void LoadInitialArrayMap(Register function_in,
1143
1143
  Register scratch,
1144
- Register map_out);
1144
+ Register map_out,
1145
+ bool can_have_holes);
1145
1146
 
1146
1147
  // Load the global function with the given index.
1147
1148
  void LoadGlobalFunction(int index, Register function);
@@ -1,4 +1,4 @@
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:
@@ -44,21 +44,23 @@ namespace internal {
44
44
 
45
45
  /*
46
46
  * This assembler uses the following register assignment convention
47
- * - rdx : currently loaded character(s) as ASCII or UC16. Must be loaded using
48
- * LoadCurrentCharacter before using any of the dispatch methods.
49
- * - rdi : current position in input, as negative offset from end of string.
47
+ * - rdx : Currently loaded character(s) as ASCII or UC16. Must be loaded
48
+ * using LoadCurrentCharacter before using any of the dispatch methods.
49
+ * Temporarily stores the index of capture start after a matching pass
50
+ * for a global regexp.
51
+ * - rdi : Current position in input, as negative offset from end of string.
50
52
  * Please notice that this is the byte offset, not the character
51
- * offset! Is always a 32-bit signed (negative) offset, but must be
53
+ * offset! Is always a 32-bit signed (negative) offset, but must be
52
54
  * maintained sign-extended to 64 bits, since it is used as index.
53
- * - rsi : end of input (points to byte after last character in input),
55
+ * - rsi : End of input (points to byte after last character in input),
54
56
  * so that rsi+rdi points to the current character.
55
- * - rbp : frame pointer. Used to access arguments, local variables and
57
+ * - rbp : Frame pointer. Used to access arguments, local variables and
56
58
  * RegExp registers.
57
- * - rsp : points to tip of C stack.
58
- * - rcx : points to tip of backtrack stack. The backtrack stack contains
59
- * only 32-bit values. Most are offsets from some base (e.g., character
59
+ * - rsp : Points to tip of C stack.
60
+ * - rcx : Points to tip of backtrack stack. The backtrack stack contains
61
+ * only 32-bit values. Most are offsets from some base (e.g., character
60
62
  * positions from end of string or code location from Code* pointer).
61
- * - r8 : code object pointer. Used to convert between absolute and
63
+ * - r8 : Code object pointer. Used to convert between absolute and
62
64
  * code-object-relative addresses.
63
65
  *
64
66
  * The registers rax, rbx, r9 and r11 are free to use for computations.
@@ -72,20 +74,22 @@ namespace internal {
72
74
  *
73
75
  * The stack will have the following content, in some order, indexable from the
74
76
  * frame pointer (see, e.g., kStackHighEnd):
75
- * - Isolate* isolate (Address of the current isolate)
77
+ * - Isolate* isolate (address of the current isolate)
76
78
  * - direct_call (if 1, direct call from JavaScript code, if 0 call
77
79
  * through the runtime system)
78
- * - stack_area_base (High end of the memory area to use as
80
+ * - stack_area_base (high end of the memory area to use as
79
81
  * backtracking stack)
82
+ * - capture array size (may fit multiple sets of matches)
80
83
  * - int* capture_array (int[num_saved_registers_], for output).
81
- * - end of input (Address of end of string)
82
- * - start of input (Address of first character in string)
84
+ * - end of input (address of end of string)
85
+ * - start of input (address of first character in string)
83
86
  * - start index (character index of start)
84
87
  * - String* input_string (input string)
85
88
  * - return address
86
89
  * - backup of callee save registers (rbx, possibly rsi and rdi).
90
+ * - success counter (only useful for global regexp to count matches)
87
91
  * - Offset of location before start of input (effectively character
88
- * position -1). Used to initialize capture registers to a non-position.
92
+ * position -1). Used to initialize capture registers to a non-position.
89
93
  * - At start of string (if 1, we are starting at the start of the
90
94
  * string, otherwise 0)
91
95
  * - register 0 rbp[-n] (Only positions must be stored in the first
@@ -94,7 +98,7 @@ namespace internal {
94
98
  *
95
99
  * The first num_saved_registers_ registers are initialized to point to
96
100
  * "character -1" in the string (i.e., char_size() bytes before the first
97
- * character of the string). The remaining registers starts out uninitialized.
101
+ * character of the string). The remaining registers starts out uninitialized.
98
102
  *
99
103
  * The first seven values must be provided by the calling code by
100
104
  * calling the code's entry address cast to a function pointer with the
@@ -744,13 +748,16 @@ bool RegExpMacroAssemblerX64::CheckSpecialCharacterClass(uc16 type,
744
748
 
745
749
 
746
750
  void RegExpMacroAssemblerX64::Fail() {
747
- ASSERT(FAILURE == 0); // Return value for failure is zero.
748
- __ Set(rax, 0);
751
+ STATIC_ASSERT(FAILURE == 0); // Return value for failure is zero.
752
+ if (!global()) {
753
+ __ Set(rax, FAILURE);
754
+ }
749
755
  __ jmp(&exit_label_);
750
756
  }
751
757
 
752
758
 
753
759
  Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
760
+ Label return_rax;
754
761
  // Finalize code - write the entry point code now we know how many
755
762
  // registers we need.
756
763
  // Entry code:
@@ -784,7 +791,7 @@ Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
784
791
  ASSERT_EQ(kInputStart, -3 * kPointerSize);
785
792
  ASSERT_EQ(kInputEnd, -4 * kPointerSize);
786
793
  ASSERT_EQ(kRegisterOutput, -5 * kPointerSize);
787
- ASSERT_EQ(kStackHighEnd, -6 * kPointerSize);
794
+ ASSERT_EQ(kNumOutputRegisters, -6 * kPointerSize);
788
795
  __ push(rdi);
789
796
  __ push(rsi);
790
797
  __ push(rdx);
@@ -795,7 +802,8 @@ Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
795
802
  __ push(rbx); // Callee-save
796
803
  #endif
797
804
 
798
- __ push(Immediate(0)); // Make room for "at start" constant.
805
+ __ push(Immediate(0)); // Number of successful matches in a global regexp.
806
+ __ push(Immediate(0)); // Make room for "input start - 1" constant.
799
807
 
800
808
  // Check if we have space on the stack for registers.
801
809
  Label stack_limit_hit;
@@ -815,14 +823,14 @@ Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
815
823
  // Exit with OutOfMemory exception. There is not enough space on the stack
816
824
  // for our working registers.
817
825
  __ Set(rax, EXCEPTION);
818
- __ jmp(&exit_label_);
826
+ __ jmp(&return_rax);
819
827
 
820
828
  __ bind(&stack_limit_hit);
821
829
  __ Move(code_object_pointer(), masm_.CodeObject());
822
830
  CallCheckStackGuardState(); // Preserves no registers beside rbp and rsp.
823
831
  __ testq(rax, rax);
824
832
  // If returned value is non-zero, we exit with the returned value as result.
825
- __ j(not_zero, &exit_label_);
833
+ __ j(not_zero, &return_rax);
826
834
 
827
835
  __ bind(&stack_ok);
828
836
 
@@ -847,19 +855,7 @@ Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
847
855
  // position registers.
848
856
  __ movq(Operand(rbp, kInputStartMinusOne), rax);
849
857
 
850
- if (num_saved_registers_ > 0) {
851
- // Fill saved registers with initial value = start offset - 1
852
- // Fill in stack push order, to avoid accessing across an unwritten
853
- // page (a problem on Windows).
854
- __ Set(rcx, kRegisterZero);
855
- Label init_loop;
856
- __ bind(&init_loop);
857
- __ movq(Operand(rbp, rcx, times_1, 0), rax);
858
- __ subq(rcx, Immediate(kPointerSize));
859
- __ cmpq(rcx,
860
- Immediate(kRegisterZero - num_saved_registers_ * kPointerSize));
861
- __ j(greater, &init_loop);
862
- }
858
+ #ifdef WIN32
863
859
  // Ensure that we have written to each stack page, in order. Skipping a page
864
860
  // on Windows can cause segmentation faults. Assuming page size is 4k.
865
861
  const int kPageSize = 4096;
@@ -869,21 +865,49 @@ Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
869
865
  i += kRegistersPerPage) {
870
866
  __ movq(register_location(i), rax); // One write every page.
871
867
  }
868
+ #endif // WIN32
872
869
 
873
- // Initialize backtrack stack pointer.
874
- __ movq(backtrack_stackpointer(), Operand(rbp, kStackHighEnd));
875
870
  // Initialize code object pointer.
876
871
  __ Move(code_object_pointer(), masm_.CodeObject());
877
- // Load previous char as initial value of current-character.
878
- Label at_start;
879
- __ cmpb(Operand(rbp, kStartIndex), Immediate(0));
880
- __ j(equal, &at_start);
881
- LoadCurrentCharacterUnchecked(-1, 1); // Load previous char.
882
- __ jmp(&start_label_);
883
- __ bind(&at_start);
872
+
873
+ Label load_char_start_regexp, start_regexp;
874
+ // Load newline if index is at start, previous character otherwise.
875
+ __ cmpl(Operand(rbp, kStartIndex), Immediate(0));
876
+ __ j(not_equal, &load_char_start_regexp, Label::kNear);
884
877
  __ Set(current_character(), '\n');
885
- __ jmp(&start_label_);
878
+ __ jmp(&start_regexp, Label::kNear);
879
+
880
+ // Global regexp restarts matching here.
881
+ __ bind(&load_char_start_regexp);
882
+ // Load previous char as initial value of current character register.
883
+ LoadCurrentCharacterUnchecked(-1, 1);
884
+ __ bind(&start_regexp);
885
+
886
+ // Initialize on-stack registers.
887
+ if (num_saved_registers_ > 0) {
888
+ // Fill saved registers with initial value = start offset - 1
889
+ // Fill in stack push order, to avoid accessing across an unwritten
890
+ // page (a problem on Windows).
891
+ if (num_saved_registers_ > 8) {
892
+ __ Set(rcx, kRegisterZero);
893
+ Label init_loop;
894
+ __ bind(&init_loop);
895
+ __ movq(Operand(rbp, rcx, times_1, 0), rax);
896
+ __ subq(rcx, Immediate(kPointerSize));
897
+ __ cmpq(rcx,
898
+ Immediate(kRegisterZero - num_saved_registers_ * kPointerSize));
899
+ __ j(greater, &init_loop);
900
+ } else { // Unroll the loop.
901
+ for (int i = 0; i < num_saved_registers_; i++) {
902
+ __ movq(register_location(i), rax);
903
+ }
904
+ }
905
+ }
906
+
907
+ // Initialize backtrack stack pointer.
908
+ __ movq(backtrack_stackpointer(), Operand(rbp, kStackHighEnd));
886
909
 
910
+ __ jmp(&start_label_);
887
911
 
888
912
  // Exit code:
889
913
  if (success_label_.is_linked()) {
@@ -902,6 +926,10 @@ Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
902
926
  }
903
927
  for (int i = 0; i < num_saved_registers_; i++) {
904
928
  __ movq(rax, register_location(i));
929
+ if (i == 0 && global()) {
930
+ // Keep capture start in rdx for the zero-length check later.
931
+ __ movq(rdx, rax);
932
+ }
905
933
  __ addq(rax, rcx); // Convert to index from start, not end.
906
934
  if (mode_ == UC16) {
907
935
  __ sar(rax, Immediate(1)); // Convert byte index to character index.
@@ -909,12 +937,54 @@ Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
909
937
  __ movl(Operand(rbx, i * kIntSize), rax);
910
938
  }
911
939
  }
912
- __ Set(rax, SUCCESS);
940
+
941
+ if (global()) {
942
+ // Restart matching if the regular expression is flagged as global.
943
+ // Increment success counter.
944
+ __ incq(Operand(rbp, kSuccessfulCaptures));
945
+ // Capture results have been stored, so the number of remaining global
946
+ // output registers is reduced by the number of stored captures.
947
+ __ movsxlq(rcx, Operand(rbp, kNumOutputRegisters));
948
+ __ subq(rcx, Immediate(num_saved_registers_));
949
+ // Check whether we have enough room for another set of capture results.
950
+ __ cmpq(rcx, Immediate(num_saved_registers_));
951
+ __ j(less, &exit_label_);
952
+
953
+ __ movq(Operand(rbp, kNumOutputRegisters), rcx);
954
+ // Advance the location for output.
955
+ __ addq(Operand(rbp, kRegisterOutput),
956
+ Immediate(num_saved_registers_ * kIntSize));
957
+
958
+ // Prepare rax to initialize registers with its value in the next run.
959
+ __ movq(rax, Operand(rbp, kInputStartMinusOne));
960
+
961
+ // Special case for zero-length matches.
962
+ // rdx: capture start index
963
+ __ cmpq(rdi, rdx);
964
+ // Not a zero-length match, restart.
965
+ __ j(not_equal, &load_char_start_regexp);
966
+ // rdi (offset from the end) is zero if we already reached the end.
967
+ __ testq(rdi, rdi);
968
+ __ j(zero, &exit_label_, Label::kNear);
969
+ // Advance current position after a zero-length match.
970
+ if (mode_ == UC16) {
971
+ __ addq(rdi, Immediate(2));
972
+ } else {
973
+ __ incq(rdi);
974
+ }
975
+ __ jmp(&load_char_start_regexp);
976
+ } else {
977
+ __ movq(rax, Immediate(SUCCESS));
978
+ }
913
979
  }
914
980
 
915
- // Exit and return rax
916
981
  __ bind(&exit_label_);
982
+ if (global()) {
983
+ // Return the number of successful captures.
984
+ __ movq(rax, Operand(rbp, kSuccessfulCaptures));
985
+ }
917
986
 
987
+ __ bind(&return_rax);
918
988
  #ifdef _WIN64
919
989
  // Restore callee save registers.
920
990
  __ lea(rsp, Operand(rbp, kLastCalleeSaveRegister));
@@ -951,7 +1021,7 @@ Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
951
1021
  __ testq(rax, rax);
952
1022
  // If returning non-zero, we should end execution with the given
953
1023
  // result as return value.
954
- __ j(not_zero, &exit_label_);
1024
+ __ j(not_zero, &return_rax);
955
1025
 
956
1026
  // Restore registers.
957
1027
  __ Move(code_object_pointer(), masm_.CodeObject());
@@ -1012,7 +1082,7 @@ Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
1012
1082
  __ bind(&exit_with_exception);
1013
1083
  // Exit with Result EXCEPTION(-1) to signal thrown exception.
1014
1084
  __ Set(rax, EXCEPTION);
1015
- __ jmp(&exit_label_);
1085
+ __ jmp(&return_rax);
1016
1086
  }
1017
1087
 
1018
1088
  FixupCodeRelativePositions();
@@ -1135,8 +1205,9 @@ void RegExpMacroAssemblerX64::SetRegister(int register_index, int to) {
1135
1205
  }
1136
1206
 
1137
1207
 
1138
- void RegExpMacroAssemblerX64::Succeed() {
1208
+ bool RegExpMacroAssemblerX64::Succeed() {
1139
1209
  __ jmp(&success_label_);
1210
+ return global();
1140
1211
  }
1141
1212
 
1142
1213