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
@@ -1868,10 +1868,12 @@ void MacroAssembler::CompareRoot(Register obj,
1868
1868
  void MacroAssembler::CheckFastElements(Register map,
1869
1869
  Register scratch,
1870
1870
  Label* fail) {
1871
- STATIC_ASSERT(FAST_SMI_ONLY_ELEMENTS == 0);
1872
- STATIC_ASSERT(FAST_ELEMENTS == 1);
1871
+ STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
1872
+ STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
1873
+ STATIC_ASSERT(FAST_ELEMENTS == 2);
1874
+ STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3);
1873
1875
  ldrb(scratch, FieldMemOperand(map, Map::kBitField2Offset));
1874
- cmp(scratch, Operand(Map::kMaximumBitField2FastElementValue));
1876
+ cmp(scratch, Operand(Map::kMaximumBitField2FastHoleyElementValue));
1875
1877
  b(hi, fail);
1876
1878
  }
1877
1879
 
@@ -1879,22 +1881,25 @@ void MacroAssembler::CheckFastElements(Register map,
1879
1881
  void MacroAssembler::CheckFastObjectElements(Register map,
1880
1882
  Register scratch,
1881
1883
  Label* fail) {
1882
- STATIC_ASSERT(FAST_SMI_ONLY_ELEMENTS == 0);
1883
- STATIC_ASSERT(FAST_ELEMENTS == 1);
1884
+ STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
1885
+ STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
1886
+ STATIC_ASSERT(FAST_ELEMENTS == 2);
1887
+ STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3);
1884
1888
  ldrb(scratch, FieldMemOperand(map, Map::kBitField2Offset));
1885
- cmp(scratch, Operand(Map::kMaximumBitField2FastSmiOnlyElementValue));
1889
+ cmp(scratch, Operand(Map::kMaximumBitField2FastHoleySmiElementValue));
1886
1890
  b(ls, fail);
1887
- cmp(scratch, Operand(Map::kMaximumBitField2FastElementValue));
1891
+ cmp(scratch, Operand(Map::kMaximumBitField2FastHoleyElementValue));
1888
1892
  b(hi, fail);
1889
1893
  }
1890
1894
 
1891
1895
 
1892
- void MacroAssembler::CheckFastSmiOnlyElements(Register map,
1893
- Register scratch,
1894
- Label* fail) {
1895
- STATIC_ASSERT(FAST_SMI_ONLY_ELEMENTS == 0);
1896
+ void MacroAssembler::CheckFastSmiElements(Register map,
1897
+ Register scratch,
1898
+ Label* fail) {
1899
+ STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
1900
+ STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
1896
1901
  ldrb(scratch, FieldMemOperand(map, Map::kBitField2Offset));
1897
- cmp(scratch, Operand(Map::kMaximumBitField2FastSmiOnlyElementValue));
1902
+ cmp(scratch, Operand(Map::kMaximumBitField2FastHoleySmiElementValue));
1898
1903
  b(hi, fail);
1899
1904
  }
1900
1905
 
@@ -1997,22 +2002,17 @@ void MacroAssembler::CompareMap(Register obj,
1997
2002
  ldr(scratch, FieldMemOperand(obj, HeapObject::kMapOffset));
1998
2003
  cmp(scratch, Operand(map));
1999
2004
  if (mode == ALLOW_ELEMENT_TRANSITION_MAPS) {
2000
- Map* transitioned_fast_element_map(
2001
- map->LookupElementsTransitionMap(FAST_ELEMENTS, NULL));
2002
- ASSERT(transitioned_fast_element_map == NULL ||
2003
- map->elements_kind() != FAST_ELEMENTS);
2004
- if (transitioned_fast_element_map != NULL) {
2005
- b(eq, early_success);
2006
- cmp(scratch, Operand(Handle<Map>(transitioned_fast_element_map)));
2007
- }
2008
-
2009
- Map* transitioned_double_map(
2010
- map->LookupElementsTransitionMap(FAST_DOUBLE_ELEMENTS, NULL));
2011
- ASSERT(transitioned_double_map == NULL ||
2012
- map->elements_kind() == FAST_SMI_ONLY_ELEMENTS);
2013
- if (transitioned_double_map != NULL) {
2014
- b(eq, early_success);
2015
- cmp(scratch, Operand(Handle<Map>(transitioned_double_map)));
2005
+ ElementsKind kind = map->elements_kind();
2006
+ if (IsFastElementsKind(kind)) {
2007
+ bool packed = IsFastPackedElementsKind(kind);
2008
+ Map* current_map = *map;
2009
+ while (CanTransitionToMoreGeneralFastElementsKind(kind, packed)) {
2010
+ kind = GetNextMoreGeneralFastElementsKind(kind, packed);
2011
+ current_map = current_map->LookupElementsTransitionMap(kind, NULL);
2012
+ if (!current_map) break;
2013
+ b(eq, early_success);
2014
+ cmp(scratch, Operand(Handle<Map>(current_map)));
2015
+ }
2016
2016
  }
2017
2017
  }
2018
2018
  }
@@ -2865,28 +2865,38 @@ void MacroAssembler::LoadTransitionedArrayMapConditional(
2865
2865
  ldr(scratch, FieldMemOperand(scratch, GlobalObject::kGlobalContextOffset));
2866
2866
 
2867
2867
  // Check that the function's map is the same as the expected cached map.
2868
- int expected_index =
2869
- Context::GetContextMapIndexFromElementsKind(expected_kind);
2870
- ldr(ip, MemOperand(scratch, Context::SlotOffset(expected_index)));
2871
- cmp(map_in_out, ip);
2868
+ ldr(scratch,
2869
+ MemOperand(scratch,
2870
+ Context::SlotOffset(Context::JS_ARRAY_MAPS_INDEX)));
2871
+ size_t offset = expected_kind * kPointerSize +
2872
+ FixedArrayBase::kHeaderSize;
2873
+ cmp(map_in_out, scratch);
2872
2874
  b(ne, no_map_match);
2873
2875
 
2874
2876
  // Use the transitioned cached map.
2875
- int trans_index =
2876
- Context::GetContextMapIndexFromElementsKind(transitioned_kind);
2877
- ldr(map_in_out, MemOperand(scratch, Context::SlotOffset(trans_index)));
2877
+ offset = transitioned_kind * kPointerSize +
2878
+ FixedArrayBase::kHeaderSize;
2879
+ ldr(map_in_out, FieldMemOperand(scratch, offset));
2878
2880
  }
2879
2881
 
2880
2882
 
2881
2883
  void MacroAssembler::LoadInitialArrayMap(
2882
- Register function_in, Register scratch, Register map_out) {
2884
+ Register function_in, Register scratch,
2885
+ Register map_out, bool can_have_holes) {
2883
2886
  ASSERT(!function_in.is(map_out));
2884
2887
  Label done;
2885
2888
  ldr(map_out, FieldMemOperand(function_in,
2886
2889
  JSFunction::kPrototypeOrInitialMapOffset));
2887
2890
  if (!FLAG_smi_only_arrays) {
2888
- LoadTransitionedArrayMapConditional(FAST_SMI_ONLY_ELEMENTS,
2889
- FAST_ELEMENTS,
2891
+ ElementsKind kind = can_have_holes ? FAST_HOLEY_ELEMENTS : FAST_ELEMENTS;
2892
+ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
2893
+ kind,
2894
+ map_out,
2895
+ scratch,
2896
+ &done);
2897
+ } else if (can_have_holes) {
2898
+ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
2899
+ FAST_HOLEY_SMI_ELEMENTS,
2890
2900
  map_out,
2891
2901
  scratch,
2892
2902
  &done);
@@ -3738,7 +3748,7 @@ CodePatcher::CodePatcher(byte* address, int instructions)
3738
3748
  : address_(address),
3739
3749
  instructions_(instructions),
3740
3750
  size_(instructions * Assembler::kInstrSize),
3741
- masm_(Isolate::Current(), address, size_ + Assembler::kGap) {
3751
+ masm_(NULL, address, size_ + Assembler::kGap) {
3742
3752
  // Create a new macro assembler pointing to the address of the code to patch.
3743
3753
  // The size is adjusted with kGap on order for the assembler to generate size
3744
3754
  // bytes of instructions without failing with buffer size constraints.
@@ -512,7 +512,8 @@ class MacroAssembler: public Assembler {
512
512
  // Load the initial map for new Arrays from a JSFunction.
513
513
  void LoadInitialArrayMap(Register function_in,
514
514
  Register scratch,
515
- Register map_out);
515
+ Register map_out,
516
+ bool can_have_holes);
516
517
 
517
518
  void LoadGlobalFunction(int index, Register function);
518
519
 
@@ -802,9 +803,9 @@ class MacroAssembler: public Assembler {
802
803
 
803
804
  // Check if a map for a JSObject indicates that the object has fast smi only
804
805
  // elements. Jump to the specified label if it does not.
805
- void CheckFastSmiOnlyElements(Register map,
806
- Register scratch,
807
- Label* fail);
806
+ void CheckFastSmiElements(Register map,
807
+ Register scratch,
808
+ Label* fail);
808
809
 
809
810
  // Check to see if maybe_number can be stored as a double in
810
811
  // FastDoubleElements. If it can, store it at the index specified by key in
@@ -1,4 +1,4 @@
1
- // Copyright 2009 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:
@@ -43,45 +43,49 @@ namespace internal {
43
43
  #ifndef V8_INTERPRETED_REGEXP
44
44
  /*
45
45
  * This assembler uses the following register assignment convention
46
+ * - r4 : Temporarily stores the index of capture start after a matching pass
47
+ * for a global regexp.
46
48
  * - r5 : Pointer to current code object (Code*) including heap object tag.
47
49
  * - r6 : 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
  * - r7 : Currently loaded character. Must be loaded using
50
52
  * LoadCurrentCharacter before using any of the dispatch methods.
51
- * - r8 : points to tip of backtrack stack
53
+ * - r8 : Points to tip of backtrack stack
52
54
  * - r9 : Unused, might be used by C code and expected unchanged.
53
55
  * - r10 : End of input (points to byte after last character in input).
54
56
  * - r11 : Frame pointer. Used to access arguments, local variables and
55
57
  * RegExp registers.
56
58
  * - r12 : IP register, used by assembler. Very volatile.
57
- * - r13/sp : points to tip of C stack.
59
+ * - r13/sp : Points to tip of C stack.
58
60
  *
59
61
  * The remaining registers are free for computations.
60
62
  * Each call to a public method should retain this convention.
61
63
  *
62
64
  * The stack will have the following structure:
63
- * - fp[52] Isolate* isolate (Address of the current isolate)
64
- * - fp[48] direct_call (if 1, direct call from JavaScript code,
65
- * if 0, call through the runtime system).
66
- * - fp[44] stack_area_base (High end of the memory area to use as
67
- * backtracking stack).
65
+ * - fp[56] Isolate* isolate (address of the current isolate)
66
+ * - fp[52] direct_call (if 1, direct call from JavaScript code,
67
+ * if 0, call through the runtime system).
68
+ * - fp[48] stack_area_base (high end of the memory area to use as
69
+ * backtracking stack).
70
+ * - fp[44] capture array size (may fit multiple sets of matches)
68
71
  * - fp[40] int* capture_array (int[num_saved_registers_], for output).
69
72
  * - fp[36] secondary link/return address used by native call.
70
73
  * --- sp when called ---
71
- * - fp[32] return address (lr).
72
- * - fp[28] old frame pointer (r11).
74
+ * - fp[32] return address (lr).
75
+ * - fp[28] old frame pointer (r11).
73
76
  * - fp[0..24] backup of registers r4..r10.
74
77
  * --- frame pointer ----
75
- * - fp[-4] end of input (Address of end of string).
76
- * - 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).
77
80
  * - fp[-12] start index (character index of start).
78
81
  * - fp[-16] void* input_string (location of a handle containing the string).
79
- * - 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
80
84
  * position -1). Used to initialize capture registers to a
81
85
  * non-position.
82
- * - 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
83
87
  * string, otherwise 0)
84
- * - 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
85
89
  * - register 1 num_saved_registers_ registers)
86
90
  * - ...
87
91
  * - register num_registers-1
@@ -197,9 +201,9 @@ void RegExpMacroAssemblerARM::CheckCharacterGT(uc16 limit, Label* on_greater) {
197
201
  void RegExpMacroAssemblerARM::CheckAtStart(Label* on_at_start) {
198
202
  Label not_at_start;
199
203
  // Did we start the match at the start of the string at all?
200
- __ ldr(r0, MemOperand(frame_pointer(), kAtStart));
204
+ __ ldr(r0, MemOperand(frame_pointer(), kStartIndex));
201
205
  __ cmp(r0, Operand(0, RelocInfo::NONE));
202
- BranchOrBacktrack(eq, &not_at_start);
206
+ BranchOrBacktrack(ne, &not_at_start);
203
207
 
204
208
  // If we did, are we still at the start of the input?
205
209
  __ ldr(r1, MemOperand(frame_pointer(), kInputStart));
@@ -212,9 +216,9 @@ void RegExpMacroAssemblerARM::CheckAtStart(Label* on_at_start) {
212
216
 
213
217
  void RegExpMacroAssemblerARM::CheckNotAtStart(Label* on_not_at_start) {
214
218
  // Did we start the match at the start of the string at all?
215
- __ ldr(r0, MemOperand(frame_pointer(), kAtStart));
219
+ __ ldr(r0, MemOperand(frame_pointer(), kStartIndex));
216
220
  __ cmp(r0, Operand(0, RelocInfo::NONE));
217
- BranchOrBacktrack(eq, on_not_at_start);
221
+ BranchOrBacktrack(ne, on_not_at_start);
218
222
  // If we did, are we still at the start of the input?
219
223
  __ ldr(r1, MemOperand(frame_pointer(), kInputStart));
220
224
  __ add(r0, end_of_input_address(), Operand(current_input_offset()));
@@ -655,6 +659,7 @@ void RegExpMacroAssemblerARM::Fail() {
655
659
 
656
660
 
657
661
  Handle<HeapObject> RegExpMacroAssemblerARM::GetCode(Handle<String> source) {
662
+ Label return_r0;
658
663
  // Finalize code - write the entry point code now we know how many
659
664
  // registers we need.
660
665
 
@@ -678,8 +683,9 @@ Handle<HeapObject> RegExpMacroAssemblerARM::GetCode(Handle<String> source) {
678
683
  // Set frame pointer in space for it if this is not a direct call
679
684
  // from generated code.
680
685
  __ add(frame_pointer(), sp, Operand(4 * kPointerSize));
686
+ __ mov(r0, Operand(0, RelocInfo::NONE));
687
+ __ push(r0); // Make room for success counter and initialize it to 0.
681
688
  __ push(r0); // Make room for "position - 1" constant (value is irrelevant).
682
- __ push(r0); // Make room for "at start" constant (value is irrelevant).
683
689
  // Check if we have space on the stack for registers.
684
690
  Label stack_limit_hit;
685
691
  Label stack_ok;
@@ -698,13 +704,13 @@ Handle<HeapObject> RegExpMacroAssemblerARM::GetCode(Handle<String> source) {
698
704
  // Exit with OutOfMemory exception. There is not enough space on the stack
699
705
  // for our working registers.
700
706
  __ mov(r0, Operand(EXCEPTION));
701
- __ jmp(&exit_label_);
707
+ __ jmp(&return_r0);
702
708
 
703
709
  __ bind(&stack_limit_hit);
704
710
  CallCheckStackGuardState(r0);
705
711
  __ cmp(r0, Operand(0, RelocInfo::NONE));
706
712
  // If returned value is non-zero, we exit with the returned value as result.
707
- __ b(ne, &exit_label_);
713
+ __ b(ne, &return_r0);
708
714
 
709
715
  __ bind(&stack_ok);
710
716
 
@@ -725,41 +731,45 @@ Handle<HeapObject> RegExpMacroAssemblerARM::GetCode(Handle<String> source) {
725
731
  // position registers.
726
732
  __ str(r0, MemOperand(frame_pointer(), kInputStartMinusOne));
727
733
 
728
- // Determine whether the start index is zero, that is at the start of the
729
- // string, and store that value in a local variable.
730
- __ cmp(r1, Operand(0));
731
- __ mov(r1, Operand(1), LeaveCC, eq);
732
- __ mov(r1, Operand(0, RelocInfo::NONE), LeaveCC, ne);
733
- __ str(r1, MemOperand(frame_pointer(), kAtStart));
734
+ // Initialize code pointer register
735
+ __ mov(code_pointer(), Operand(masm_->CodeObject()));
736
+
737
+ Label load_char_start_regexp, start_regexp;
738
+ // Load newline if index is at start, previous character otherwise.
739
+ __ cmp(r1, Operand(0, RelocInfo::NONE));
740
+ __ b(ne, &load_char_start_regexp);
741
+ __ mov(current_character(), Operand('\n'), LeaveCC, eq);
742
+ __ jmp(&start_regexp);
743
+
744
+ // Global regexp restarts matching here.
745
+ __ bind(&load_char_start_regexp);
746
+ // Load previous char as initial value of current character register.
747
+ LoadCurrentCharacterUnchecked(-1, 1);
748
+ __ bind(&start_regexp);
734
749
 
750
+ // Initialize on-stack registers.
735
751
  if (num_saved_registers_ > 0) { // Always is, if generated from a regexp.
736
752
  // Fill saved registers with initial value = start offset - 1
737
-
738
- // Address of register 0.
739
- __ add(r1, frame_pointer(), Operand(kRegisterZero));
740
- __ mov(r2, Operand(num_saved_registers_));
741
- Label init_loop;
742
- __ bind(&init_loop);
743
- __ str(r0, MemOperand(r1, kPointerSize, NegPostIndex));
744
- __ sub(r2, r2, Operand(1), SetCC);
745
- __ b(ne, &init_loop);
753
+ if (num_saved_registers_ > 8) {
754
+ // Address of register 0.
755
+ __ add(r1, frame_pointer(), Operand(kRegisterZero));
756
+ __ mov(r2, Operand(num_saved_registers_));
757
+ Label init_loop;
758
+ __ bind(&init_loop);
759
+ __ str(r0, MemOperand(r1, kPointerSize, NegPostIndex));
760
+ __ sub(r2, r2, Operand(1), SetCC);
761
+ __ b(ne, &init_loop);
762
+ } else {
763
+ for (int i = 0; i < num_saved_registers_; i++) {
764
+ __ str(r0, register_location(i));
765
+ }
766
+ }
746
767
  }
747
768
 
748
769
  // Initialize backtrack stack pointer.
749
770
  __ ldr(backtrack_stackpointer(), MemOperand(frame_pointer(), kStackHighEnd));
750
- // Initialize code pointer register
751
- __ mov(code_pointer(), Operand(masm_->CodeObject()));
752
- // Load previous char as initial value of current character register.
753
- Label at_start;
754
- __ ldr(r0, MemOperand(frame_pointer(), kAtStart));
755
- __ cmp(r0, Operand(0, RelocInfo::NONE));
756
- __ b(ne, &at_start);
757
- LoadCurrentCharacterUnchecked(-1, 1); // Load previous char.
758
- __ jmp(&start_label_);
759
- __ bind(&at_start);
760
- __ mov(current_character(), Operand('\n'));
761
- __ jmp(&start_label_);
762
771
 
772
+ __ jmp(&start_label_);
763
773
 
764
774
  // Exit code:
765
775
  if (success_label_.is_linked()) {
@@ -786,6 +796,10 @@ Handle<HeapObject> RegExpMacroAssemblerARM::GetCode(Handle<String> source) {
786
796
  for (int i = 0; i < num_saved_registers_; i += 2) {
787
797
  __ ldr(r2, register_location(i));
788
798
  __ ldr(r3, register_location(i + 1));
799
+ if (global()) {
800
+ // Keep capture start in r4 for the zero-length check later.
801
+ __ mov(r4, r2);
802
+ }
789
803
  if (mode_ == UC16) {
790
804
  __ add(r2, r1, Operand(r2, ASR, 1));
791
805
  __ add(r3, r1, Operand(r3, ASR, 1));
@@ -797,10 +811,54 @@ Handle<HeapObject> RegExpMacroAssemblerARM::GetCode(Handle<String> source) {
797
811
  __ str(r3, MemOperand(r0, kPointerSize, PostIndex));
798
812
  }
799
813
  }
800
- __ mov(r0, Operand(SUCCESS));
814
+
815
+ if (global()) {
816
+ // Restart matching if the regular expression is flagged as global.
817
+ __ ldr(r0, MemOperand(frame_pointer(), kSuccessfulCaptures));
818
+ __ ldr(r1, MemOperand(frame_pointer(), kNumOutputRegisters));
819
+ __ ldr(r2, MemOperand(frame_pointer(), kRegisterOutput));
820
+ // Increment success counter.
821
+ __ add(r0, r0, Operand(1));
822
+ __ str(r0, MemOperand(frame_pointer(), kSuccessfulCaptures));
823
+ // Capture results have been stored, so the number of remaining global
824
+ // output registers is reduced by the number of stored captures.
825
+ __ sub(r1, r1, Operand(num_saved_registers_));
826
+ // Check whether we have enough room for another set of capture results.
827
+ __ cmp(r1, Operand(num_saved_registers_));
828
+ __ b(lt, &return_r0);
829
+
830
+ __ str(r1, MemOperand(frame_pointer(), kNumOutputRegisters));
831
+ // Advance the location for output.
832
+ __ add(r2, r2, Operand(num_saved_registers_ * kPointerSize));
833
+ __ str(r2, MemOperand(frame_pointer(), kRegisterOutput));
834
+
835
+ // Prepare r0 to initialize registers with its value in the next run.
836
+ __ ldr(r0, MemOperand(frame_pointer(), kInputStartMinusOne));
837
+ // Special case for zero-length matches.
838
+ // r4: capture start index
839
+ __ cmp(current_input_offset(), r4);
840
+ // Not a zero-length match, restart.
841
+ __ b(ne, &load_char_start_regexp);
842
+ // Offset from the end is zero if we already reached the end.
843
+ __ cmp(current_input_offset(), Operand(0));
844
+ __ b(eq, &exit_label_);
845
+ // Advance current position after a zero-length match.
846
+ __ add(current_input_offset(),
847
+ current_input_offset(),
848
+ Operand((mode_ == UC16) ? 2 : 1));
849
+ __ b(&load_char_start_regexp);
850
+ } else {
851
+ __ mov(r0, Operand(SUCCESS));
852
+ }
801
853
  }
854
+
802
855
  // Exit and return r0
803
856
  __ bind(&exit_label_);
857
+ if (global()) {
858
+ __ ldr(r0, MemOperand(frame_pointer(), kSuccessfulCaptures));
859
+ }
860
+
861
+ __ bind(&return_r0);
804
862
  // Skip sp past regexp registers and local variables..
805
863
  __ mov(sp, frame_pointer());
806
864
  // Restore registers r4..r11 and return (restoring lr to pc).
@@ -822,7 +880,7 @@ Handle<HeapObject> RegExpMacroAssemblerARM::GetCode(Handle<String> source) {
822
880
  __ cmp(r0, Operand(0, RelocInfo::NONE));
823
881
  // If returning non-zero, we should end execution with the given
824
882
  // result as return value.
825
- __ b(ne, &exit_label_);
883
+ __ b(ne, &return_r0);
826
884
 
827
885
  // String might have moved: Reload end of string from frame.
828
886
  __ ldr(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd));
@@ -859,7 +917,7 @@ Handle<HeapObject> RegExpMacroAssemblerARM::GetCode(Handle<String> source) {
859
917
  __ bind(&exit_with_exception);
860
918
  // Exit with Result EXCEPTION(-1) to signal thrown exception.
861
919
  __ mov(r0, Operand(EXCEPTION));
862
- __ jmp(&exit_label_);
920
+ __ jmp(&return_r0);
863
921
  }
864
922
 
865
923
  CodeDesc code_desc;
@@ -1014,8 +1072,9 @@ void RegExpMacroAssemblerARM::SetRegister(int register_index, int to) {
1014
1072
  }
1015
1073
 
1016
1074
 
1017
- void RegExpMacroAssemblerARM::Succeed() {
1075
+ bool RegExpMacroAssemblerARM::Succeed() {
1018
1076
  __ jmp(&success_label_);
1077
+ return global();
1019
1078
  }
1020
1079
 
1021
1080
 
@@ -1307,8 +1366,9 @@ void RegExpMacroAssemblerARM::LoadCurrentCharacterUnchecked(int cp_offset,
1307
1366
  int characters) {
1308
1367
  Register offset = current_input_offset();
1309
1368
  if (cp_offset != 0) {
1310
- __ add(r0, current_input_offset(), Operand(cp_offset * char_size()));
1311
- offset = r0;
1369
+ // r4 is not being used to store the capture start index at this point.
1370
+ __ add(r4, current_input_offset(), Operand(cp_offset * char_size()));
1371
+ offset = r4;
1312
1372
  }
1313
1373
  // The ldr, str, ldrh, strh instructions can do unaligned accesses, if the CPU
1314
1374
  // and the operating system running on the target allow it.