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
@@ -2023,8 +2023,9 @@ LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) {
2023
2023
 
2024
2024
  LInstruction* LChunkBuilder::DoTransitionElementsKind(
2025
2025
  HTransitionElementsKind* instr) {
2026
- if (instr->original_map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS &&
2027
- instr->transitioned_map()->elements_kind() == FAST_ELEMENTS) {
2026
+ ElementsKind from_kind = instr->original_map()->elements_kind();
2027
+ ElementsKind to_kind = instr->transitioned_map()->elements_kind();
2028
+ if (IsSimpleMapChangeTransition(from_kind, to_kind)) {
2028
2029
  LOperand* object = UseRegister(instr->object());
2029
2030
  LOperand* new_map_reg = TempRegister();
2030
2031
  LTransitionElementsKind* result =
@@ -2045,16 +2046,28 @@ LInstruction* LChunkBuilder::DoTransitionElementsKind(
2045
2046
 
2046
2047
  LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
2047
2048
  bool needs_write_barrier = instr->NeedsWriteBarrier();
2048
-
2049
- LOperand* obj = needs_write_barrier
2050
- ? UseTempRegister(instr->object())
2051
- : UseRegisterAtStart(instr->object());
2049
+ bool needs_write_barrier_for_map = !instr->transition().is_null() &&
2050
+ instr->NeedsWriteBarrierForMap();
2051
+
2052
+ LOperand* obj;
2053
+ if (needs_write_barrier) {
2054
+ obj = instr->is_in_object()
2055
+ ? UseRegister(instr->object())
2056
+ : UseTempRegister(instr->object());
2057
+ } else {
2058
+ obj = needs_write_barrier_for_map
2059
+ ? UseRegister(instr->object())
2060
+ : UseRegisterAtStart(instr->object());
2061
+ }
2052
2062
 
2053
2063
  LOperand* val = needs_write_barrier
2054
2064
  ? UseTempRegister(instr->value())
2055
2065
  : UseRegister(instr->value());
2056
2066
 
2057
- return new(zone()) LStoreNamedField(obj, val);
2067
+ // We need a temporary register for write barrier of the map field.
2068
+ LOperand* temp = needs_write_barrier_for_map ? TempRegister() : NULL;
2069
+
2070
+ return new(zone()) LStoreNamedField(obj, val, temp);
2058
2071
  }
2059
2072
 
2060
2073
 
@@ -1201,6 +1201,7 @@ class LLoadKeyedFastElement: public LTemplateInstruction<1, 2, 0> {
1201
1201
 
1202
1202
  LOperand* elements() { return inputs_[0]; }
1203
1203
  LOperand* key() { return inputs_[1]; }
1204
+ uint32_t additional_index() const { return hydrogen()->index_offset(); }
1204
1205
  };
1205
1206
 
1206
1207
 
@@ -1217,13 +1218,14 @@ class LLoadKeyedFastDoubleElement: public LTemplateInstruction<1, 2, 0> {
1217
1218
 
1218
1219
  LOperand* elements() { return inputs_[0]; }
1219
1220
  LOperand* key() { return inputs_[1]; }
1221
+ uint32_t additional_index() const { return hydrogen()->index_offset(); }
1220
1222
  };
1221
1223
 
1222
1224
 
1223
1225
  class LLoadKeyedSpecializedArrayElement: public LTemplateInstruction<1, 2, 0> {
1224
1226
  public:
1225
- LLoadKeyedSpecializedArrayElement(LOperand* external_pointer,
1226
- LOperand* key) {
1227
+ LLoadKeyedSpecializedArrayElement(LOperand* external_pointer,
1228
+ LOperand* key) {
1227
1229
  inputs_[0] = external_pointer;
1228
1230
  inputs_[1] = key;
1229
1231
  }
@@ -1237,6 +1239,7 @@ class LLoadKeyedSpecializedArrayElement: public LTemplateInstruction<1, 2, 0> {
1237
1239
  ElementsKind elements_kind() const {
1238
1240
  return hydrogen()->elements_kind();
1239
1241
  }
1242
+ uint32_t additional_index() const { return hydrogen()->index_offset(); }
1240
1243
  };
1241
1244
 
1242
1245
 
@@ -1647,11 +1650,12 @@ class LSmiUntag: public LTemplateInstruction<1, 1, 0> {
1647
1650
  };
1648
1651
 
1649
1652
 
1650
- class LStoreNamedField: public LTemplateInstruction<0, 2, 0> {
1653
+ class LStoreNamedField: public LTemplateInstruction<0, 2, 1> {
1651
1654
  public:
1652
- LStoreNamedField(LOperand* obj, LOperand* val) {
1655
+ LStoreNamedField(LOperand* obj, LOperand* val, LOperand* temp) {
1653
1656
  inputs_[0] = obj;
1654
1657
  inputs_[1] = val;
1658
+ temps_[0] = temp;
1655
1659
  }
1656
1660
 
1657
1661
  DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store-named-field")
@@ -1705,6 +1709,7 @@ class LStoreKeyedFastElement: public LTemplateInstruction<0, 3, 0> {
1705
1709
  LOperand* object() { return inputs_[0]; }
1706
1710
  LOperand* key() { return inputs_[1]; }
1707
1711
  LOperand* value() { return inputs_[2]; }
1712
+ uint32_t additional_index() const { return hydrogen()->index_offset(); }
1708
1713
  };
1709
1714
 
1710
1715
 
@@ -1727,6 +1732,7 @@ class LStoreKeyedFastDoubleElement: public LTemplateInstruction<0, 3, 0> {
1727
1732
  LOperand* elements() { return inputs_[0]; }
1728
1733
  LOperand* key() { return inputs_[1]; }
1729
1734
  LOperand* value() { return inputs_[2]; }
1735
+ uint32_t additional_index() const { return hydrogen()->index_offset(); }
1730
1736
 
1731
1737
  bool NeedsCanonicalization() { return hydrogen()->NeedsCanonicalization(); }
1732
1738
  };
@@ -1771,6 +1777,7 @@ class LStoreKeyedSpecializedArrayElement: public LTemplateInstruction<0, 3, 0> {
1771
1777
  ElementsKind elements_kind() const {
1772
1778
  return hydrogen()->elements_kind();
1773
1779
  }
1780
+ uint32_t additional_index() const { return hydrogen()->index_offset(); }
1774
1781
  };
1775
1782
 
1776
1783
 
@@ -3341,33 +3341,39 @@ void MacroAssembler::InitializeFieldsWithFiller(Register start_offset,
3341
3341
  void MacroAssembler::CheckFastElements(Register map,
3342
3342
  Register scratch,
3343
3343
  Label* fail) {
3344
- STATIC_ASSERT(FAST_SMI_ONLY_ELEMENTS == 0);
3345
- STATIC_ASSERT(FAST_ELEMENTS == 1);
3344
+ STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
3345
+ STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
3346
+ STATIC_ASSERT(FAST_ELEMENTS == 2);
3347
+ STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3);
3346
3348
  lbu(scratch, FieldMemOperand(map, Map::kBitField2Offset));
3347
- Branch(fail, hi, scratch, Operand(Map::kMaximumBitField2FastElementValue));
3349
+ Branch(fail, hi, scratch,
3350
+ Operand(Map::kMaximumBitField2FastHoleyElementValue));
3348
3351
  }
3349
3352
 
3350
3353
 
3351
3354
  void MacroAssembler::CheckFastObjectElements(Register map,
3352
3355
  Register scratch,
3353
3356
  Label* fail) {
3354
- STATIC_ASSERT(FAST_SMI_ONLY_ELEMENTS == 0);
3355
- STATIC_ASSERT(FAST_ELEMENTS == 1);
3357
+ STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
3358
+ STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
3359
+ STATIC_ASSERT(FAST_ELEMENTS == 2);
3360
+ STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3);
3356
3361
  lbu(scratch, FieldMemOperand(map, Map::kBitField2Offset));
3357
3362
  Branch(fail, ls, scratch,
3358
- Operand(Map::kMaximumBitField2FastSmiOnlyElementValue));
3363
+ Operand(Map::kMaximumBitField2FastHoleySmiElementValue));
3359
3364
  Branch(fail, hi, scratch,
3360
- Operand(Map::kMaximumBitField2FastElementValue));
3365
+ Operand(Map::kMaximumBitField2FastHoleyElementValue));
3361
3366
  }
3362
3367
 
3363
3368
 
3364
- void MacroAssembler::CheckFastSmiOnlyElements(Register map,
3365
- Register scratch,
3366
- Label* fail) {
3367
- STATIC_ASSERT(FAST_SMI_ONLY_ELEMENTS == 0);
3369
+ void MacroAssembler::CheckFastSmiElements(Register map,
3370
+ Register scratch,
3371
+ Label* fail) {
3372
+ STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
3373
+ STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
3368
3374
  lbu(scratch, FieldMemOperand(map, Map::kBitField2Offset));
3369
3375
  Branch(fail, hi, scratch,
3370
- Operand(Map::kMaximumBitField2FastSmiOnlyElementValue));
3376
+ Operand(Map::kMaximumBitField2FastHoleySmiElementValue));
3371
3377
  }
3372
3378
 
3373
3379
 
@@ -3469,22 +3475,17 @@ void MacroAssembler::CompareMapAndBranch(Register obj,
3469
3475
  lw(scratch, FieldMemOperand(obj, HeapObject::kMapOffset));
3470
3476
  Operand right = Operand(map);
3471
3477
  if (mode == ALLOW_ELEMENT_TRANSITION_MAPS) {
3472
- Map* transitioned_fast_element_map(
3473
- map->LookupElementsTransitionMap(FAST_ELEMENTS, NULL));
3474
- ASSERT(transitioned_fast_element_map == NULL ||
3475
- map->elements_kind() != FAST_ELEMENTS);
3476
- if (transitioned_fast_element_map != NULL) {
3477
- Branch(early_success, eq, scratch, right);
3478
- right = Operand(Handle<Map>(transitioned_fast_element_map));
3479
- }
3480
-
3481
- Map* transitioned_double_map(
3482
- map->LookupElementsTransitionMap(FAST_DOUBLE_ELEMENTS, NULL));
3483
- ASSERT(transitioned_double_map == NULL ||
3484
- map->elements_kind() == FAST_SMI_ONLY_ELEMENTS);
3485
- if (transitioned_double_map != NULL) {
3486
- Branch(early_success, eq, scratch, right);
3487
- right = Operand(Handle<Map>(transitioned_double_map));
3478
+ ElementsKind kind = map->elements_kind();
3479
+ if (IsFastElementsKind(kind)) {
3480
+ bool packed = IsFastPackedElementsKind(kind);
3481
+ Map* current_map = *map;
3482
+ while (CanTransitionToMoreGeneralFastElementsKind(kind, packed)) {
3483
+ kind = GetNextMoreGeneralFastElementsKind(kind, packed);
3484
+ current_map = current_map->LookupElementsTransitionMap(kind, NULL);
3485
+ if (!current_map) break;
3486
+ Branch(early_success, eq, scratch, right);
3487
+ right = Operand(Handle<Map>(current_map));
3488
+ }
3488
3489
  }
3489
3490
  }
3490
3491
 
@@ -4443,27 +4444,37 @@ void MacroAssembler::LoadTransitionedArrayMapConditional(
4443
4444
  lw(scratch, FieldMemOperand(scratch, GlobalObject::kGlobalContextOffset));
4444
4445
 
4445
4446
  // Check that the function's map is the same as the expected cached map.
4446
- int expected_index =
4447
- Context::GetContextMapIndexFromElementsKind(expected_kind);
4448
- lw(at, MemOperand(scratch, Context::SlotOffset(expected_index)));
4449
- Branch(no_map_match, ne, map_in_out, Operand(at));
4447
+ lw(scratch,
4448
+ MemOperand(scratch,
4449
+ Context::SlotOffset(Context::JS_ARRAY_MAPS_INDEX)));
4450
+ size_t offset = expected_kind * kPointerSize +
4451
+ FixedArrayBase::kHeaderSize;
4452
+ Branch(no_map_match, ne, map_in_out, Operand(scratch));
4450
4453
 
4451
4454
  // Use the transitioned cached map.
4452
- int trans_index =
4453
- Context::GetContextMapIndexFromElementsKind(transitioned_kind);
4454
- lw(map_in_out, MemOperand(scratch, Context::SlotOffset(trans_index)));
4455
+ offset = transitioned_kind * kPointerSize +
4456
+ FixedArrayBase::kHeaderSize;
4457
+ lw(map_in_out, FieldMemOperand(scratch, offset));
4455
4458
  }
4456
4459
 
4457
4460
 
4458
4461
  void MacroAssembler::LoadInitialArrayMap(
4459
- Register function_in, Register scratch, Register map_out) {
4462
+ Register function_in, Register scratch,
4463
+ Register map_out, bool can_have_holes) {
4460
4464
  ASSERT(!function_in.is(map_out));
4461
4465
  Label done;
4462
4466
  lw(map_out, FieldMemOperand(function_in,
4463
4467
  JSFunction::kPrototypeOrInitialMapOffset));
4464
4468
  if (!FLAG_smi_only_arrays) {
4465
- LoadTransitionedArrayMapConditional(FAST_SMI_ONLY_ELEMENTS,
4466
- FAST_ELEMENTS,
4469
+ ElementsKind kind = can_have_holes ? FAST_HOLEY_ELEMENTS : FAST_ELEMENTS;
4470
+ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
4471
+ kind,
4472
+ map_out,
4473
+ scratch,
4474
+ &done);
4475
+ } else if (can_have_holes) {
4476
+ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
4477
+ FAST_HOLEY_SMI_ELEMENTS,
4467
4478
  map_out,
4468
4479
  scratch,
4469
4480
  &done);
@@ -5378,7 +5389,7 @@ CodePatcher::CodePatcher(byte* address, int instructions)
5378
5389
  : address_(address),
5379
5390
  instructions_(instructions),
5380
5391
  size_(instructions * Assembler::kInstrSize),
5381
- masm_(Isolate::Current(), address, size_ + Assembler::kGap) {
5392
+ masm_(NULL, address, size_ + Assembler::kGap) {
5382
5393
  // Create a new macro assembler pointing to the address of the code to patch.
5383
5394
  // The size is adjusted with kGap on order for the assembler to generate size
5384
5395
  // bytes of instructions without failing with buffer size constraints.
@@ -819,7 +819,8 @@ class MacroAssembler: public Assembler {
819
819
  // Load the initial map for new Arrays from a JSFunction.
820
820
  void LoadInitialArrayMap(Register function_in,
821
821
  Register scratch,
822
- Register map_out);
822
+ Register map_out,
823
+ bool can_have_holes);
823
824
 
824
825
  void LoadGlobalFunction(int index, Register function);
825
826
 
@@ -961,9 +962,9 @@ class MacroAssembler: public Assembler {
961
962
 
962
963
  // Check if a map for a JSObject indicates that the object has fast smi only
963
964
  // elements. Jump to the specified label if it does not.
964
- void CheckFastSmiOnlyElements(Register map,
965
- Register scratch,
966
- Label* fail);
965
+ void CheckFastSmiElements(Register map,
966
+ Register scratch,
967
+ Label* fail);
967
968
 
968
969
  // Check to see if maybe_number can be stored as a double in
969
970
  // FastDoubleElements. If it can, store it at the index specified by key in
@@ -43,44 +43,49 @@ namespace internal {
43
43
  #ifndef V8_INTERPRETED_REGEXP
44
44
  /*
45
45
  * This assembler uses the following register assignment convention
46
+ * - t7 : Temporarily stores the index of capture start after a matching pass
47
+ * for a global regexp.
46
48
  * - t1 : Pointer to current code object (Code*) including heap object tag.
47
49
  * - t2 : Current position in input, as negative offset from end of string.
48
50
  * Please notice that this is the byte offset, not the character offset!
49
51
  * - t3 : Currently loaded character. Must be loaded using
50
52
  * LoadCurrentCharacter before using any of the dispatch methods.
51
- * - t4 : points to tip of backtrack stack
53
+ * - t4 : Points to tip of backtrack stack
52
54
  * - t5 : Unused.
53
55
  * - t6 : End of input (points to byte after last character in input).
54
56
  * - fp : Frame pointer. Used to access arguments, local variables and
55
57
  * RegExp registers.
56
- * - sp : points to tip of C stack.
58
+ * - sp : Points to tip of C stack.
57
59
  *
58
60
  * The remaining registers are free for computations.
59
61
  * Each call to a public method should retain this convention.
60
62
  *
61
63
  * The stack will have the following structure:
62
64
  *
63
- * - fp[56] direct_call (if 1, direct call from JavaScript code,
65
+ * - fp[64] Isolate* isolate (address of the current isolate)
66
+ * - fp[60] direct_call (if 1, direct call from JavaScript code,
64
67
  * if 0, call through the runtime system).
65
- * - fp[52] stack_area_base (High end of the memory area to use as
68
+ * - fp[56] stack_area_base (High end of the memory area to use as
66
69
  * backtracking stack).
70
+ * - fp[52] capture array size (may fit multiple sets of matches)
67
71
  * - fp[48] int* capture_array (int[num_saved_registers_], for output).
68
72
  * - fp[44] secondary link/return address used by native call.
69
73
  * --- sp when called ---
70
- * - fp[40] return address (lr).
71
- * - fp[36] old frame pointer (r11).
74
+ * - fp[40] return address (lr).
75
+ * - fp[36] old frame pointer (r11).
72
76
  * - fp[0..32] backup of registers s0..s7.
73
77
  * --- frame pointer ----
74
- * - fp[-4] end of input (Address of end of string).
75
- * - fp[-8] start of input (Address of first character in string).
78
+ * - fp[-4] end of input (address of end of string).
79
+ * - fp[-8] start of input (address of first character in string).
76
80
  * - fp[-12] start index (character index of start).
77
81
  * - fp[-16] void* input_string (location of a handle containing the string).
78
- * - fp[-20] Offset of location before start of input (effectively character
82
+ * - fp[-20] success counter (only for global regexps to count matches).
83
+ * - fp[-24] Offset of location before start of input (effectively character
79
84
  * position -1). Used to initialize capture registers to a
80
85
  * non-position.
81
- * - fp[-24] At start (if 1, we are starting at the start of the
86
+ * - fp[-28] At start (if 1, we are starting at the start of the
82
87
  * string, otherwise 0)
83
- * - fp[-28] register 0 (Only positions must be stored in the first
88
+ * - fp[-32] register 0 (Only positions must be stored in the first
84
89
  * - register 1 num_saved_registers_ registers)
85
90
  * - ...
86
91
  * - register num_registers-1
@@ -201,8 +206,8 @@ void RegExpMacroAssemblerMIPS::CheckCharacterGT(uc16 limit, Label* on_greater) {
201
206
  void RegExpMacroAssemblerMIPS::CheckAtStart(Label* on_at_start) {
202
207
  Label not_at_start;
203
208
  // Did we start the match at the start of the string at all?
204
- __ lw(a0, MemOperand(frame_pointer(), kAtStart));
205
- BranchOrBacktrack(&not_at_start, eq, a0, Operand(zero_reg));
209
+ __ lw(a0, MemOperand(frame_pointer(), kStartIndex));
210
+ BranchOrBacktrack(&not_at_start, ne, a0, Operand(zero_reg));
206
211
 
207
212
  // If we did, are we still at the start of the input?
208
213
  __ lw(a1, MemOperand(frame_pointer(), kInputStart));
@@ -214,8 +219,8 @@ void RegExpMacroAssemblerMIPS::CheckAtStart(Label* on_at_start) {
214
219
 
215
220
  void RegExpMacroAssemblerMIPS::CheckNotAtStart(Label* on_not_at_start) {
216
221
  // Did we start the match at the start of the string at all?
217
- __ lw(a0, MemOperand(frame_pointer(), kAtStart));
218
- BranchOrBacktrack(on_not_at_start, eq, a0, Operand(zero_reg));
222
+ __ lw(a0, MemOperand(frame_pointer(), kStartIndex));
223
+ BranchOrBacktrack(on_not_at_start, ne, a0, Operand(zero_reg));
219
224
  // If we did, are we still at the start of the input?
220
225
  __ lw(a1, MemOperand(frame_pointer(), kInputStart));
221
226
  __ Addu(a0, end_of_input_address(), Operand(current_input_offset()));
@@ -640,6 +645,7 @@ void RegExpMacroAssemblerMIPS::Fail() {
640
645
 
641
646
 
642
647
  Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
648
+ Label return_v0;
643
649
  if (masm_->has_exception()) {
644
650
  // If the code gets corrupted due to long regular expressions and lack of
645
651
  // space on trampolines, an internal exception flag is set. If this case
@@ -669,8 +675,9 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
669
675
  // Set frame pointer in space for it if this is not a direct call
670
676
  // from generated code.
671
677
  __ Addu(frame_pointer(), sp, Operand(4 * kPointerSize));
678
+ __ mov(a0, zero_reg);
679
+ __ push(a0); // Make room for success counter and initialize it to 0.
672
680
  __ push(a0); // Make room for "position - 1" constant (value irrelevant).
673
- __ push(a0); // Make room for "at start" constant (value irrelevant).
674
681
 
675
682
  // Check if we have space on the stack for registers.
676
683
  Label stack_limit_hit;
@@ -689,12 +696,12 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
689
696
  // Exit with OutOfMemory exception. There is not enough space on the stack
690
697
  // for our working registers.
691
698
  __ li(v0, Operand(EXCEPTION));
692
- __ jmp(&exit_label_);
699
+ __ jmp(&return_v0);
693
700
 
694
701
  __ bind(&stack_limit_hit);
695
702
  CallCheckStackGuardState(a0);
696
703
  // If returned value is non-zero, we exit with the returned value as result.
697
- __ Branch(&exit_label_, ne, v0, Operand(zero_reg));
704
+ __ Branch(&return_v0, ne, v0, Operand(zero_reg));
698
705
 
699
706
  __ bind(&stack_ok);
700
707
  // Allocate space on stack for registers.
@@ -715,39 +722,44 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
715
722
  // position registers.
716
723
  __ sw(a0, MemOperand(frame_pointer(), kInputStartMinusOne));
717
724
 
718
- // Determine whether the start index is zero, that is at the start of the
719
- // string, and store that value in a local variable.
720
- __ mov(t5, a1);
721
- __ li(a1, Operand(1));
722
- __ Movn(a1, zero_reg, t5);
723
- __ sw(a1, MemOperand(frame_pointer(), kAtStart));
725
+ // Initialize code pointer register
726
+ __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE);
727
+
728
+ Label load_char_start_regexp, start_regexp;
729
+ // Load newline if index is at start, previous character otherwise.
730
+ __ Branch(&load_char_start_regexp, ne, a1, Operand(zero_reg));
731
+ __ li(current_character(), Operand('\n'));
732
+ __ jmp(&start_regexp);
733
+
734
+ // Global regexp restarts matching here.
735
+ __ bind(&load_char_start_regexp);
736
+ // Load previous char as initial value of current character register.
737
+ LoadCurrentCharacterUnchecked(-1, 1);
738
+ __ bind(&start_regexp);
724
739
 
740
+ // Initialize on-stack registers.
725
741
  if (num_saved_registers_ > 0) { // Always is, if generated from a regexp.
726
742
  // Fill saved registers with initial value = start offset - 1.
727
-
728
- // Address of register 0.
729
- __ Addu(a1, frame_pointer(), Operand(kRegisterZero));
730
- __ li(a2, Operand(num_saved_registers_));
731
- Label init_loop;
732
- __ bind(&init_loop);
733
- __ sw(a0, MemOperand(a1));
734
- __ Addu(a1, a1, Operand(-kPointerSize));
735
- __ Subu(a2, a2, Operand(1));
736
- __ Branch(&init_loop, ne, a2, Operand(zero_reg));
743
+ if (num_saved_registers_ > 8) {
744
+ // Address of register 0.
745
+ __ Addu(a1, frame_pointer(), Operand(kRegisterZero));
746
+ __ li(a2, Operand(num_saved_registers_));
747
+ Label init_loop;
748
+ __ bind(&init_loop);
749
+ __ sw(a0, MemOperand(a1));
750
+ __ Addu(a1, a1, Operand(-kPointerSize));
751
+ __ Subu(a2, a2, Operand(1));
752
+ __ Branch(&init_loop, ne, a2, Operand(zero_reg));
753
+ } else {
754
+ for (int i = 0; i < num_saved_registers_; i++) {
755
+ __ sw(a0, register_location(i));
756
+ }
757
+ }
737
758
  }
738
759
 
739
760
  // Initialize backtrack stack pointer.
740
761
  __ lw(backtrack_stackpointer(), MemOperand(frame_pointer(), kStackHighEnd));
741
- // Initialize code pointer register
742
- __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE);
743
- // Load previous char as initial value of current character register.
744
- Label at_start;
745
- __ lw(a0, MemOperand(frame_pointer(), kAtStart));
746
- __ Branch(&at_start, ne, a0, Operand(zero_reg));
747
- LoadCurrentCharacterUnchecked(-1, 1); // Load previous char.
748
- __ jmp(&start_label_);
749
- __ bind(&at_start);
750
- __ li(current_character(), Operand('\n'));
762
+
751
763
  __ jmp(&start_label_);
752
764
 
753
765
 
@@ -776,6 +788,10 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
776
788
  for (int i = 0; i < num_saved_registers_; i += 2) {
777
789
  __ lw(a2, register_location(i));
778
790
  __ lw(a3, register_location(i + 1));
791
+ if (global()) {
792
+ // Keep capture start in a4 for the zero-length check later.
793
+ __ mov(t7, a2);
794
+ }
779
795
  if (mode_ == UC16) {
780
796
  __ sra(a2, a2, 1);
781
797
  __ Addu(a2, a2, a1);
@@ -791,10 +807,52 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
791
807
  __ Addu(a0, a0, kPointerSize);
792
808
  }
793
809
  }
794
- __ li(v0, Operand(SUCCESS));
810
+
811
+ if (global()) {
812
+ // Restart matching if the regular expression is flagged as global.
813
+ __ lw(a0, MemOperand(frame_pointer(), kSuccessfulCaptures));
814
+ __ lw(a1, MemOperand(frame_pointer(), kNumOutputRegisters));
815
+ __ lw(a2, MemOperand(frame_pointer(), kRegisterOutput));
816
+ // Increment success counter.
817
+ __ Addu(a0, a0, 1);
818
+ __ sw(a0, MemOperand(frame_pointer(), kSuccessfulCaptures));
819
+ // Capture results have been stored, so the number of remaining global
820
+ // output registers is reduced by the number of stored captures.
821
+ __ Subu(a1, a1, num_saved_registers_);
822
+ // Check whether we have enough room for another set of capture results.
823
+ __ mov(v0, a0);
824
+ __ Branch(&return_v0, lt, a1, Operand(num_saved_registers_));
825
+
826
+ __ sw(a1, MemOperand(frame_pointer(), kNumOutputRegisters));
827
+ // Advance the location for output.
828
+ __ Addu(a2, a2, num_saved_registers_ * kPointerSize);
829
+ __ sw(a2, MemOperand(frame_pointer(), kRegisterOutput));
830
+
831
+ // Prepare a0 to initialize registers with its value in the next run.
832
+ __ lw(a0, MemOperand(frame_pointer(), kInputStartMinusOne));
833
+ // Special case for zero-length matches.
834
+ // t7: capture start index
835
+ // Not a zero-length match, restart.
836
+ __ Branch(
837
+ &load_char_start_regexp, ne, current_input_offset(), Operand(t7));
838
+ // Offset from the end is zero if we already reached the end.
839
+ __ Branch(&exit_label_, eq, current_input_offset(), Operand(zero_reg));
840
+ // Advance current position after a zero-length match.
841
+ __ Addu(current_input_offset(),
842
+ current_input_offset(),
843
+ Operand((mode_ == UC16) ? 2 : 1));
844
+ __ Branch(&load_char_start_regexp);
845
+ } else {
846
+ __ li(v0, Operand(SUCCESS));
847
+ }
795
848
  }
796
849
  // Exit and return v0.
797
850
  __ bind(&exit_label_);
851
+ if (global()) {
852
+ __ lw(v0, MemOperand(frame_pointer(), kSuccessfulCaptures));
853
+ }
854
+
855
+ __ bind(&return_v0);
798
856
  // Skip sp past regexp registers and local variables..
799
857
  __ mov(sp, frame_pointer());
800
858
  // Restore registers s0..s7 and return (restoring ra to pc).
@@ -820,7 +878,7 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
820
878
  __ MultiPop(regexp_registers_to_retain);
821
879
  // If returning non-zero, we should end execution with the given
822
880
  // result as return value.
823
- __ Branch(&exit_label_, ne, v0, Operand(zero_reg));
881
+ __ Branch(&return_v0, ne, v0, Operand(zero_reg));
824
882
 
825
883
  // String might have moved: Reload end of string from frame.
826
884
  __ lw(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd));
@@ -864,7 +922,7 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
864
922
  __ bind(&exit_with_exception);
865
923
  // Exit with Result EXCEPTION(-1) to signal thrown exception.
866
924
  __ li(v0, Operand(EXCEPTION));
867
- __ jmp(&exit_label_);
925
+ __ jmp(&return_v0);
868
926
  }
869
927
  }
870
928
 
@@ -1012,8 +1070,9 @@ void RegExpMacroAssemblerMIPS::SetRegister(int register_index, int to) {
1012
1070
  }
1013
1071
 
1014
1072
 
1015
- void RegExpMacroAssemblerMIPS::Succeed() {
1073
+ bool RegExpMacroAssemblerMIPS::Succeed() {
1016
1074
  __ jmp(&success_label_);
1075
+ return global();
1017
1076
  }
1018
1077
 
1019
1078
 
@@ -1280,8 +1339,9 @@ void RegExpMacroAssemblerMIPS::LoadCurrentCharacterUnchecked(int cp_offset,
1280
1339
  int characters) {
1281
1340
  Register offset = current_input_offset();
1282
1341
  if (cp_offset != 0) {
1283
- __ Addu(a0, current_input_offset(), Operand(cp_offset * char_size()));
1284
- offset = a0;
1342
+ // t7 is not being used to store the capture start index at this point.
1343
+ __ Addu(t7, current_input_offset(), Operand(cp_offset * char_size()));
1344
+ offset = t7;
1285
1345
  }
1286
1346
  // We assume that we cannot do unaligned loads on MIPS, so this function
1287
1347
  // must only be used to load a single character at a time.