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
@@ -242,7 +242,8 @@ class LCodeGen BASE_EMBEDDED {
242
242
  Operand BuildFastArrayOperand(LOperand* elements_pointer,
243
243
  LOperand* key,
244
244
  ElementsKind elements_kind,
245
- uint32_t offset);
245
+ uint32_t offset,
246
+ uint32_t additional_index = 0);
246
247
 
247
248
  // Specific math operations - used from DoUnaryMathOperation.
248
249
  void EmitIntegerMathAbs(LUnaryMathOperation* instr);
@@ -1990,8 +1990,7 @@ LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement(
1990
1990
  LOperand* external_pointer = UseRegister(instr->external_pointer());
1991
1991
  LOperand* key = UseRegisterOrConstant(instr->key());
1992
1992
  LLoadKeyedSpecializedArrayElement* result =
1993
- new(zone()) LLoadKeyedSpecializedArrayElement(external_pointer,
1994
- key);
1993
+ new(zone()) LLoadKeyedSpecializedArrayElement(external_pointer, key);
1995
1994
  LInstruction* load_instr = DefineAsRegister(result);
1996
1995
  // An unsigned int array load might overflow and cause a deopt, make sure it
1997
1996
  // has an environment.
@@ -2093,8 +2092,9 @@ LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) {
2093
2092
 
2094
2093
  LInstruction* LChunkBuilder::DoTransitionElementsKind(
2095
2094
  HTransitionElementsKind* instr) {
2096
- if (instr->original_map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS &&
2097
- instr->transitioned_map()->elements_kind() == FAST_ELEMENTS) {
2095
+ ElementsKind from_kind = instr->original_map()->elements_kind();
2096
+ ElementsKind to_kind = instr->transitioned_map()->elements_kind();
2097
+ if (IsSimpleMapChangeTransition(from_kind, to_kind)) {
2098
2098
  LOperand* object = UseRegister(instr->object());
2099
2099
  LOperand* new_map_reg = TempRegister();
2100
2100
  LOperand* temp_reg = TempRegister();
@@ -2116,6 +2116,8 @@ LInstruction* LChunkBuilder::DoTransitionElementsKind(
2116
2116
 
2117
2117
  LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
2118
2118
  bool needs_write_barrier = instr->NeedsWriteBarrier();
2119
+ bool needs_write_barrier_for_map = !instr->transition().is_null() &&
2120
+ instr->NeedsWriteBarrierForMap();
2119
2121
 
2120
2122
  LOperand* obj;
2121
2123
  if (needs_write_barrier) {
@@ -2123,7 +2125,9 @@ LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
2123
2125
  ? UseRegister(instr->object())
2124
2126
  : UseTempRegister(instr->object());
2125
2127
  } else {
2126
- obj = UseRegisterAtStart(instr->object());
2128
+ obj = needs_write_barrier_for_map
2129
+ ? UseRegister(instr->object())
2130
+ : UseRegisterAtStart(instr->object());
2127
2131
  }
2128
2132
 
2129
2133
  LOperand* val = needs_write_barrier
@@ -2132,11 +2136,13 @@ LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
2132
2136
 
2133
2137
  // We only need a scratch register if we have a write barrier or we
2134
2138
  // have a store into the properties array (not in-object-property).
2135
- LOperand* temp = (!instr->is_in_object() || needs_write_barrier)
2136
- ? TempRegister()
2137
- : NULL;
2139
+ LOperand* temp = (!instr->is_in_object() || needs_write_barrier ||
2140
+ needs_write_barrier_for_map) ? TempRegister() : NULL;
2141
+
2142
+ // We need a temporary register for write barrier of the map field.
2143
+ LOperand* temp_map = needs_write_barrier_for_map ? TempRegister() : NULL;
2138
2144
 
2139
- return new(zone()) LStoreNamedField(obj, val, temp);
2145
+ return new(zone()) LStoreNamedField(obj, val, temp, temp_map);
2140
2146
  }
2141
2147
 
2142
2148
 
@@ -1238,13 +1238,13 @@ class LLoadKeyedFastElement: public LTemplateInstruction<1, 2, 0> {
1238
1238
 
1239
1239
  LOperand* elements() { return inputs_[0]; }
1240
1240
  LOperand* key() { return inputs_[1]; }
1241
+ uint32_t additional_index() const { return hydrogen()->index_offset(); }
1241
1242
  };
1242
1243
 
1243
1244
 
1244
1245
  class LLoadKeyedFastDoubleElement: public LTemplateInstruction<1, 2, 0> {
1245
1246
  public:
1246
- LLoadKeyedFastDoubleElement(LOperand* elements,
1247
- LOperand* key) {
1247
+ LLoadKeyedFastDoubleElement(LOperand* elements, LOperand* key) {
1248
1248
  inputs_[0] = elements;
1249
1249
  inputs_[1] = key;
1250
1250
  }
@@ -1255,13 +1255,13 @@ class LLoadKeyedFastDoubleElement: public LTemplateInstruction<1, 2, 0> {
1255
1255
 
1256
1256
  LOperand* elements() { return inputs_[0]; }
1257
1257
  LOperand* key() { return inputs_[1]; }
1258
+ uint32_t additional_index() const { return hydrogen()->index_offset(); }
1258
1259
  };
1259
1260
 
1260
1261
 
1261
1262
  class LLoadKeyedSpecializedArrayElement: public LTemplateInstruction<1, 2, 0> {
1262
1263
  public:
1263
- LLoadKeyedSpecializedArrayElement(LOperand* external_pointer,
1264
- LOperand* key) {
1264
+ LLoadKeyedSpecializedArrayElement(LOperand* external_pointer, LOperand* key) {
1265
1265
  inputs_[0] = external_pointer;
1266
1266
  inputs_[1] = key;
1267
1267
  }
@@ -1275,6 +1275,7 @@ class LLoadKeyedSpecializedArrayElement: public LTemplateInstruction<1, 2, 0> {
1275
1275
  ElementsKind elements_kind() const {
1276
1276
  return hydrogen()->elements_kind();
1277
1277
  }
1278
+ uint32_t additional_index() const { return hydrogen()->index_offset(); }
1278
1279
  };
1279
1280
 
1280
1281
 
@@ -1714,12 +1715,16 @@ class LSmiUntag: public LTemplateInstruction<1, 1, 0> {
1714
1715
  };
1715
1716
 
1716
1717
 
1717
- class LStoreNamedField: public LTemplateInstruction<0, 2, 1> {
1718
+ class LStoreNamedField: public LTemplateInstruction<0, 2, 2> {
1718
1719
  public:
1719
- LStoreNamedField(LOperand* obj, LOperand* val, LOperand* temp) {
1720
+ LStoreNamedField(LOperand* obj,
1721
+ LOperand* val,
1722
+ LOperand* temp,
1723
+ LOperand* temp_map) {
1720
1724
  inputs_[0] = obj;
1721
1725
  inputs_[1] = val;
1722
1726
  temps_[0] = temp;
1727
+ temps_[1] = temp_map;
1723
1728
  }
1724
1729
 
1725
1730
  DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store-named-field")
@@ -1775,6 +1780,7 @@ class LStoreKeyedFastElement: public LTemplateInstruction<0, 3, 0> {
1775
1780
  LOperand* object() { return inputs_[0]; }
1776
1781
  LOperand* key() { return inputs_[1]; }
1777
1782
  LOperand* value() { return inputs_[2]; }
1783
+ uint32_t additional_index() const { return hydrogen()->index_offset(); }
1778
1784
  };
1779
1785
 
1780
1786
 
@@ -1797,6 +1803,7 @@ class LStoreKeyedFastDoubleElement: public LTemplateInstruction<0, 3, 0> {
1797
1803
  LOperand* elements() { return inputs_[0]; }
1798
1804
  LOperand* key() { return inputs_[1]; }
1799
1805
  LOperand* value() { return inputs_[2]; }
1806
+ uint32_t additional_index() const { return hydrogen()->index_offset(); }
1800
1807
 
1801
1808
  bool NeedsCanonicalization() { return hydrogen()->NeedsCanonicalization(); }
1802
1809
  };
@@ -1822,6 +1829,7 @@ class LStoreKeyedSpecializedArrayElement: public LTemplateInstruction<0, 3, 0> {
1822
1829
  ElementsKind elements_kind() const {
1823
1830
  return hydrogen()->elements_kind();
1824
1831
  }
1832
+ uint32_t additional_index() const { return hydrogen()->index_offset(); }
1825
1833
  };
1826
1834
 
1827
1835
 
@@ -382,10 +382,12 @@ void MacroAssembler::CmpInstanceType(Register map, InstanceType type) {
382
382
  void MacroAssembler::CheckFastElements(Register map,
383
383
  Label* fail,
384
384
  Label::Distance distance) {
385
- STATIC_ASSERT(FAST_SMI_ONLY_ELEMENTS == 0);
386
- STATIC_ASSERT(FAST_ELEMENTS == 1);
385
+ STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
386
+ STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
387
+ STATIC_ASSERT(FAST_ELEMENTS == 2);
388
+ STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3);
387
389
  cmpb(FieldOperand(map, Map::kBitField2Offset),
388
- Map::kMaximumBitField2FastElementValue);
390
+ Map::kMaximumBitField2FastHoleyElementValue);
389
391
  j(above, fail, distance);
390
392
  }
391
393
 
@@ -393,23 +395,26 @@ void MacroAssembler::CheckFastElements(Register map,
393
395
  void MacroAssembler::CheckFastObjectElements(Register map,
394
396
  Label* fail,
395
397
  Label::Distance distance) {
396
- STATIC_ASSERT(FAST_SMI_ONLY_ELEMENTS == 0);
397
- STATIC_ASSERT(FAST_ELEMENTS == 1);
398
+ STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
399
+ STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
400
+ STATIC_ASSERT(FAST_ELEMENTS == 2);
401
+ STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3);
398
402
  cmpb(FieldOperand(map, Map::kBitField2Offset),
399
- Map::kMaximumBitField2FastSmiOnlyElementValue);
403
+ Map::kMaximumBitField2FastHoleySmiElementValue);
400
404
  j(below_equal, fail, distance);
401
405
  cmpb(FieldOperand(map, Map::kBitField2Offset),
402
- Map::kMaximumBitField2FastElementValue);
406
+ Map::kMaximumBitField2FastHoleyElementValue);
403
407
  j(above, fail, distance);
404
408
  }
405
409
 
406
410
 
407
- void MacroAssembler::CheckFastSmiOnlyElements(Register map,
408
- Label* fail,
409
- Label::Distance distance) {
410
- STATIC_ASSERT(FAST_SMI_ONLY_ELEMENTS == 0);
411
+ void MacroAssembler::CheckFastSmiElements(Register map,
412
+ Label* fail,
413
+ Label::Distance distance) {
414
+ STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
415
+ STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
411
416
  cmpb(FieldOperand(map, Map::kBitField2Offset),
412
- Map::kMaximumBitField2FastSmiOnlyElementValue);
417
+ Map::kMaximumBitField2FastHoleySmiElementValue);
413
418
  j(above, fail, distance);
414
419
  }
415
420
 
@@ -493,24 +498,18 @@ void MacroAssembler::CompareMap(Register obj,
493
498
  CompareMapMode mode) {
494
499
  cmp(FieldOperand(obj, HeapObject::kMapOffset), map);
495
500
  if (mode == ALLOW_ELEMENT_TRANSITION_MAPS) {
496
- Map* transitioned_fast_element_map(
497
- map->LookupElementsTransitionMap(FAST_ELEMENTS, NULL));
498
- ASSERT(transitioned_fast_element_map == NULL ||
499
- map->elements_kind() != FAST_ELEMENTS);
500
- if (transitioned_fast_element_map != NULL) {
501
- j(equal, early_success, Label::kNear);
502
- cmp(FieldOperand(obj, HeapObject::kMapOffset),
503
- Handle<Map>(transitioned_fast_element_map));
504
- }
505
-
506
- Map* transitioned_double_map(
507
- map->LookupElementsTransitionMap(FAST_DOUBLE_ELEMENTS, NULL));
508
- ASSERT(transitioned_double_map == NULL ||
509
- map->elements_kind() == FAST_SMI_ONLY_ELEMENTS);
510
- if (transitioned_double_map != NULL) {
511
- j(equal, early_success, Label::kNear);
512
- cmp(FieldOperand(obj, HeapObject::kMapOffset),
513
- Handle<Map>(transitioned_double_map));
501
+ ElementsKind kind = map->elements_kind();
502
+ if (IsFastElementsKind(kind)) {
503
+ bool packed = IsFastPackedElementsKind(kind);
504
+ Map* current_map = *map;
505
+ while (CanTransitionToMoreGeneralFastElementsKind(kind, packed)) {
506
+ kind = GetNextMoreGeneralFastElementsKind(kind, packed);
507
+ current_map = current_map->LookupElementsTransitionMap(kind, NULL);
508
+ if (!current_map) break;
509
+ j(equal, early_success, Label::kNear);
510
+ cmp(FieldOperand(obj, HeapObject::kMapOffset),
511
+ Handle<Map>(current_map));
512
+ }
514
513
  }
515
514
  }
516
515
  }
@@ -2161,27 +2160,38 @@ void MacroAssembler::LoadTransitionedArrayMapConditional(
2161
2160
  mov(scratch, FieldOperand(scratch, GlobalObject::kGlobalContextOffset));
2162
2161
 
2163
2162
  // Check that the function's map is the same as the expected cached map.
2164
- int expected_index =
2165
- Context::GetContextMapIndexFromElementsKind(expected_kind);
2166
- cmp(map_in_out, Operand(scratch, Context::SlotOffset(expected_index)));
2163
+ mov(scratch, Operand(scratch,
2164
+ Context::SlotOffset(Context::JS_ARRAY_MAPS_INDEX)));
2165
+
2166
+ size_t offset = expected_kind * kPointerSize +
2167
+ FixedArrayBase::kHeaderSize;
2168
+ cmp(map_in_out, FieldOperand(scratch, offset));
2167
2169
  j(not_equal, no_map_match);
2168
2170
 
2169
2171
  // Use the transitioned cached map.
2170
- int trans_index =
2171
- Context::GetContextMapIndexFromElementsKind(transitioned_kind);
2172
- mov(map_in_out, Operand(scratch, Context::SlotOffset(trans_index)));
2172
+ offset = transitioned_kind * kPointerSize +
2173
+ FixedArrayBase::kHeaderSize;
2174
+ mov(map_in_out, FieldOperand(scratch, offset));
2173
2175
  }
2174
2176
 
2175
2177
 
2176
2178
  void MacroAssembler::LoadInitialArrayMap(
2177
- Register function_in, Register scratch, Register map_out) {
2179
+ Register function_in, Register scratch,
2180
+ Register map_out, bool can_have_holes) {
2178
2181
  ASSERT(!function_in.is(map_out));
2179
2182
  Label done;
2180
2183
  mov(map_out, FieldOperand(function_in,
2181
2184
  JSFunction::kPrototypeOrInitialMapOffset));
2182
2185
  if (!FLAG_smi_only_arrays) {
2183
- LoadTransitionedArrayMapConditional(FAST_SMI_ONLY_ELEMENTS,
2184
- FAST_ELEMENTS,
2186
+ ElementsKind kind = can_have_holes ? FAST_HOLEY_ELEMENTS : FAST_ELEMENTS;
2187
+ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
2188
+ kind,
2189
+ map_out,
2190
+ scratch,
2191
+ &done);
2192
+ } else if (can_have_holes) {
2193
+ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
2194
+ FAST_HOLEY_SMI_ELEMENTS,
2185
2195
  map_out,
2186
2196
  scratch,
2187
2197
  &done);
@@ -2566,7 +2576,7 @@ bool AreAliased(Register r1, Register r2, Register r3, Register r4) {
2566
2576
  CodePatcher::CodePatcher(byte* address, int size)
2567
2577
  : address_(address),
2568
2578
  size_(size),
2569
- masm_(Isolate::Current(), address, size + Assembler::kGap) {
2579
+ masm_(NULL, address, size + Assembler::kGap) {
2570
2580
  // Create a new macro assembler pointing to the address of the code to patch.
2571
2581
  // The size is adjusted with kGap on order for the assembler to generate size
2572
2582
  // bytes of instructions without failing with buffer size constraints.
@@ -235,7 +235,8 @@ class MacroAssembler: public Assembler {
235
235
  // Load the initial map for new Arrays from a JSFunction.
236
236
  void LoadInitialArrayMap(Register function_in,
237
237
  Register scratch,
238
- Register map_out);
238
+ Register map_out,
239
+ bool can_have_holes);
239
240
 
240
241
  // Load the global function with the given index.
241
242
  void LoadGlobalFunction(int index, Register function);
@@ -357,9 +358,9 @@ class MacroAssembler: public Assembler {
357
358
 
358
359
  // Check if a map for a JSObject indicates that the object has fast smi only
359
360
  // elements. Jump to the specified label if it does not.
360
- void CheckFastSmiOnlyElements(Register map,
361
- Label* fail,
362
- Label::Distance distance = Label::kFar);
361
+ void CheckFastSmiElements(Register map,
362
+ Label* fail,
363
+ Label::Distance distance = Label::kFar);
363
364
 
364
365
  // Check to see if maybe_number can be stored as a double in
365
366
  // FastDoubleElements. If it can, store it at the index specified by key in
@@ -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:
@@ -42,28 +42,30 @@ namespace internal {
42
42
  #ifndef V8_INTERPRETED_REGEXP
43
43
  /*
44
44
  * This assembler uses the following register assignment convention
45
- * - edx : current character. Must be loaded using LoadCurrentCharacter
46
- * before using any of the dispatch methods.
47
- * - edi : current position in input, as negative offset from end of string.
45
+ * - edx : Current character. Must be loaded using LoadCurrentCharacter
46
+ * before using any of the dispatch methods. Temporarily stores the
47
+ * index of capture start after a matching pass for a global regexp.
48
+ * - edi : Current position in input, as negative offset from end of string.
48
49
  * Please notice that this is the byte offset, not the character offset!
49
50
  * - esi : end of input (points to byte after last character in input).
50
- * - ebp : frame pointer. Used to access arguments, local variables and
51
+ * - ebp : Frame pointer. Used to access arguments, local variables and
51
52
  * RegExp registers.
52
- * - esp : points to tip of C stack.
53
- * - ecx : points to tip of backtrack stack
53
+ * - esp : Points to tip of C stack.
54
+ * - ecx : Points to tip of backtrack stack
54
55
  *
55
56
  * The registers eax and ebx are free to use for computations.
56
57
  *
57
58
  * Each call to a public method should retain this convention.
58
59
  * The stack will have the following structure:
59
- * - Isolate* isolate (Address of the current isolate)
60
+ * - Isolate* isolate (address of the current isolate)
60
61
  * - direct_call (if 1, direct call from JavaScript code, if 0
61
62
  * call through the runtime system)
62
- * - stack_area_base (High end of the memory area to use as
63
+ * - stack_area_base (high end of the memory area to use as
63
64
  * backtracking stack)
65
+ * - capture array size (may fit multiple sets of matches)
64
66
  * - int* capture_array (int[num_saved_registers_], for output).
65
- * - end of input (Address of end of string)
66
- * - start of input (Address of first character in string)
67
+ * - end of input (address of end of string)
68
+ * - start of input (address of first character in string)
67
69
  * - start index (character index of start)
68
70
  * - String* input_string (location of a handle containing the string)
69
71
  * --- frame alignment (if applicable) ---
@@ -72,9 +74,10 @@ namespace internal {
72
74
  * - backup of caller esi
73
75
  * - backup of caller edi
74
76
  * - backup of caller ebx
77
+ * - success counter (only for global regexps to count matches).
75
78
  * - Offset of location before start of input (effectively character
76
79
  * position -1). Used to initialize capture registers to a non-position.
77
- * - register 0 ebp[-4] (Only positions must be stored in the first
80
+ * - register 0 ebp[-4] (only positions must be stored in the first
78
81
  * - register 1 ebp[-8] num_saved_registers_ registers)
79
82
  * - ...
80
83
  *
@@ -706,13 +709,16 @@ bool RegExpMacroAssemblerIA32::CheckSpecialCharacterClass(uc16 type,
706
709
 
707
710
 
708
711
  void RegExpMacroAssemblerIA32::Fail() {
709
- ASSERT(FAILURE == 0); // Return value for failure is zero.
710
- __ Set(eax, Immediate(0));
712
+ STATIC_ASSERT(FAILURE == 0); // Return value for failure is zero.
713
+ if (!global()) {
714
+ __ Set(eax, Immediate(FAILURE));
715
+ }
711
716
  __ jmp(&exit_label_);
712
717
  }
713
718
 
714
719
 
715
720
  Handle<HeapObject> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
721
+ Label return_eax;
716
722
  // Finalize code - write the entry point code now we know how many
717
723
  // registers we need.
718
724
 
@@ -731,6 +737,7 @@ Handle<HeapObject> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
731
737
  __ push(esi);
732
738
  __ push(edi);
733
739
  __ push(ebx); // Callee-save on MacOS.
740
+ __ push(Immediate(0)); // Number of successful matches in a global regexp.
734
741
  __ push(Immediate(0)); // Make room for "input start - 1" constant.
735
742
 
736
743
  // Check if we have space on the stack for registers.
@@ -750,13 +757,13 @@ Handle<HeapObject> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
750
757
  // Exit with OutOfMemory exception. There is not enough space on the stack
751
758
  // for our working registers.
752
759
  __ mov(eax, EXCEPTION);
753
- __ jmp(&exit_label_);
760
+ __ jmp(&return_eax);
754
761
 
755
762
  __ bind(&stack_limit_hit);
756
763
  CallCheckStackGuardState(ebx);
757
764
  __ or_(eax, eax);
758
765
  // If returned value is non-zero, we exit with the returned value as result.
759
- __ j(not_zero, &exit_label_);
766
+ __ j(not_zero, &return_eax);
760
767
 
761
768
  __ bind(&stack_ok);
762
769
  // Load start index for later use.
@@ -783,19 +790,8 @@ Handle<HeapObject> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
783
790
  // position registers.
784
791
  __ mov(Operand(ebp, kInputStartMinusOne), eax);
785
792
 
786
- if (num_saved_registers_ > 0) { // Always is, if generated from a regexp.
787
- // Fill saved registers with initial value = start offset - 1
788
- // Fill in stack push order, to avoid accessing across an unwritten
789
- // page (a problem on Windows).
790
- __ mov(ecx, kRegisterZero);
791
- Label init_loop;
792
- __ bind(&init_loop);
793
- __ mov(Operand(ebp, ecx, times_1, +0), eax);
794
- __ sub(ecx, Immediate(kPointerSize));
795
- __ cmp(ecx, kRegisterZero - num_saved_registers_ * kPointerSize);
796
- __ j(greater, &init_loop);
797
- }
798
- // Ensure that we have written to each stack page, in order. Skipping a page
793
+ #ifdef WIN32
794
+ // Ensure that we write to each stack page, in order. Skipping a page
799
795
  // on Windows can cause segmentation faults. Assuming page size is 4k.
800
796
  const int kPageSize = 4096;
801
797
  const int kRegistersPerPage = kPageSize / kPointerSize;
@@ -804,20 +800,45 @@ Handle<HeapObject> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
804
800
  i += kRegistersPerPage) {
805
801
  __ mov(register_location(i), eax); // One write every page.
806
802
  }
803
+ #endif // WIN32
804
+
805
+ Label load_char_start_regexp, start_regexp;
806
+ // Load newline if index is at start, previous character otherwise.
807
+ __ cmp(Operand(ebp, kStartIndex), Immediate(0));
808
+ __ j(not_equal, &load_char_start_regexp, Label::kNear);
809
+ __ mov(current_character(), '\n');
810
+ __ jmp(&start_regexp, Label::kNear);
807
811
 
812
+ // Global regexp restarts matching here.
813
+ __ bind(&load_char_start_regexp);
814
+ // Load previous char as initial value of current character register.
815
+ LoadCurrentCharacterUnchecked(-1, 1);
816
+ __ bind(&start_regexp);
817
+
818
+ // Initialize on-stack registers.
819
+ if (num_saved_registers_ > 0) { // Always is, if generated from a regexp.
820
+ // Fill saved registers with initial value = start offset - 1
821
+ // Fill in stack push order, to avoid accessing across an unwritten
822
+ // page (a problem on Windows).
823
+ if (num_saved_registers_ > 8) {
824
+ __ mov(ecx, kRegisterZero);
825
+ Label init_loop;
826
+ __ bind(&init_loop);
827
+ __ mov(Operand(ebp, ecx, times_1, 0), eax);
828
+ __ sub(ecx, Immediate(kPointerSize));
829
+ __ cmp(ecx, kRegisterZero - num_saved_registers_ * kPointerSize);
830
+ __ j(greater, &init_loop);
831
+ } else { // Unroll the loop.
832
+ for (int i = 0; i < num_saved_registers_; i++) {
833
+ __ mov(register_location(i), eax);
834
+ }
835
+ }
836
+ }
808
837
 
809
838
  // Initialize backtrack stack pointer.
810
839
  __ mov(backtrack_stackpointer(), Operand(ebp, kStackHighEnd));
811
- // Load previous char as initial value of current-character.
812
- Label at_start;
813
- __ cmp(Operand(ebp, kStartIndex), Immediate(0));
814
- __ j(equal, &at_start);
815
- LoadCurrentCharacterUnchecked(-1, 1); // Load previous char.
816
- __ jmp(&start_label_);
817
- __ bind(&at_start);
818
- __ mov(current_character(), '\n');
819
- __ jmp(&start_label_);
820
840
 
841
+ __ jmp(&start_label_);
821
842
 
822
843
  // Exit code:
823
844
  if (success_label_.is_linked()) {
@@ -836,6 +857,10 @@ Handle<HeapObject> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
836
857
  }
837
858
  for (int i = 0; i < num_saved_registers_; i++) {
838
859
  __ mov(eax, register_location(i));
860
+ if (i == 0 && global()) {
861
+ // Keep capture start in edx for the zero-length check later.
862
+ __ mov(edx, eax);
863
+ }
839
864
  // Convert to index from start of string, not end.
840
865
  __ add(eax, ecx);
841
866
  if (mode_ == UC16) {
@@ -844,10 +869,54 @@ Handle<HeapObject> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
844
869
  __ mov(Operand(ebx, i * kPointerSize), eax);
845
870
  }
846
871
  }
847
- __ mov(eax, Immediate(SUCCESS));
872
+
873
+ if (global()) {
874
+ // Restart matching if the regular expression is flagged as global.
875
+ // Increment success counter.
876
+ __ inc(Operand(ebp, kSuccessfulCaptures));
877
+ // Capture results have been stored, so the number of remaining global
878
+ // output registers is reduced by the number of stored captures.
879
+ __ mov(ecx, Operand(ebp, kNumOutputRegisters));
880
+ __ sub(ecx, Immediate(num_saved_registers_));
881
+ // Check whether we have enough room for another set of capture results.
882
+ __ cmp(ecx, Immediate(num_saved_registers_));
883
+ __ j(less, &exit_label_);
884
+
885
+ __ mov(Operand(ebp, kNumOutputRegisters), ecx);
886
+ // Advance the location for output.
887
+ __ add(Operand(ebp, kRegisterOutput),
888
+ Immediate(num_saved_registers_ * kPointerSize));
889
+
890
+ // Prepare eax to initialize registers with its value in the next run.
891
+ __ mov(eax, Operand(ebp, kInputStartMinusOne));
892
+
893
+ // Special case for zero-length matches.
894
+ // edx: capture start index
895
+ __ cmp(edi, edx);
896
+ // Not a zero-length match, restart.
897
+ __ j(not_equal, &load_char_start_regexp);
898
+ // edi (offset from the end) is zero if we already reached the end.
899
+ __ test(edi, edi);
900
+ __ j(zero, &exit_label_, Label::kNear);
901
+ // Advance current position after a zero-length match.
902
+ if (mode_ == UC16) {
903
+ __ add(edi, Immediate(2));
904
+ } else {
905
+ __ inc(edi);
906
+ }
907
+ __ jmp(&load_char_start_regexp);
908
+ } else {
909
+ __ mov(eax, Immediate(SUCCESS));
910
+ }
848
911
  }
849
- // Exit and return eax
912
+
850
913
  __ bind(&exit_label_);
914
+ if (global()) {
915
+ // Return the number of successful captures.
916
+ __ mov(eax, Operand(ebp, kSuccessfulCaptures));
917
+ }
918
+
919
+ __ bind(&return_eax);
851
920
  // Skip esp past regexp registers.
852
921
  __ lea(esp, Operand(ebp, kBackup_ebx));
853
922
  // Restore callee-save registers.
@@ -877,7 +946,7 @@ Handle<HeapObject> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
877
946
  __ or_(eax, eax);
878
947
  // If returning non-zero, we should end execution with the given
879
948
  // result as return value.
880
- __ j(not_zero, &exit_label_);
949
+ __ j(not_zero, &return_eax);
881
950
 
882
951
  __ pop(edi);
883
952
  __ pop(backtrack_stackpointer());
@@ -924,7 +993,7 @@ Handle<HeapObject> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
924
993
  __ bind(&exit_with_exception);
925
994
  // Exit with Result EXCEPTION(-1) to signal thrown exception.
926
995
  __ mov(eax, EXCEPTION);
927
- __ jmp(&exit_label_);
996
+ __ jmp(&return_eax);
928
997
  }
929
998
 
930
999
  CodeDesc code_desc;
@@ -1043,8 +1112,9 @@ void RegExpMacroAssemblerIA32::SetRegister(int register_index, int to) {
1043
1112
  }
1044
1113
 
1045
1114
 
1046
- void RegExpMacroAssemblerIA32::Succeed() {
1115
+ bool RegExpMacroAssemblerIA32::Succeed() {
1047
1116
  __ jmp(&success_label_);
1117
+ return global();
1048
1118
  }
1049
1119
 
1050
1120