libv8 3.11.8.17 → 3.16.14.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (754) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -2
  3. data/Gemfile +1 -1
  4. data/Rakefile +6 -7
  5. data/lib/libv8/version.rb +1 -1
  6. data/vendor/v8/.gitignore +24 -3
  7. data/vendor/v8/AUTHORS +7 -0
  8. data/vendor/v8/ChangeLog +839 -0
  9. data/vendor/v8/DEPS +1 -1
  10. data/vendor/v8/Makefile.android +92 -0
  11. data/vendor/v8/OWNERS +11 -0
  12. data/vendor/v8/PRESUBMIT.py +71 -0
  13. data/vendor/v8/SConstruct +34 -39
  14. data/vendor/v8/build/android.gypi +56 -37
  15. data/vendor/v8/build/common.gypi +112 -30
  16. data/vendor/v8/build/gyp_v8 +1 -1
  17. data/vendor/v8/build/standalone.gypi +15 -11
  18. data/vendor/v8/include/v8-debug.h +9 -1
  19. data/vendor/v8/include/v8-preparser.h +4 -3
  20. data/vendor/v8/include/v8-profiler.h +25 -25
  21. data/vendor/v8/include/v8-testing.h +4 -3
  22. data/vendor/v8/include/v8.h +994 -540
  23. data/vendor/v8/preparser/preparser-process.cc +3 -3
  24. data/vendor/v8/samples/lineprocessor.cc +20 -27
  25. data/vendor/v8/samples/process.cc +18 -14
  26. data/vendor/v8/samples/shell.cc +16 -15
  27. data/vendor/v8/src/SConscript +15 -14
  28. data/vendor/v8/src/accessors.cc +169 -77
  29. data/vendor/v8/src/accessors.h +4 -0
  30. data/vendor/v8/src/allocation-inl.h +2 -2
  31. data/vendor/v8/src/allocation.h +7 -7
  32. data/vendor/v8/src/api.cc +810 -497
  33. data/vendor/v8/src/api.h +85 -60
  34. data/vendor/v8/src/arm/assembler-arm-inl.h +179 -22
  35. data/vendor/v8/src/arm/assembler-arm.cc +633 -264
  36. data/vendor/v8/src/arm/assembler-arm.h +264 -197
  37. data/vendor/v8/src/arm/builtins-arm.cc +117 -27
  38. data/vendor/v8/src/arm/code-stubs-arm.cc +1241 -700
  39. data/vendor/v8/src/arm/code-stubs-arm.h +35 -138
  40. data/vendor/v8/src/arm/codegen-arm.cc +285 -16
  41. data/vendor/v8/src/arm/codegen-arm.h +22 -0
  42. data/vendor/v8/src/arm/constants-arm.cc +5 -3
  43. data/vendor/v8/src/arm/constants-arm.h +24 -11
  44. data/vendor/v8/src/arm/debug-arm.cc +3 -3
  45. data/vendor/v8/src/arm/deoptimizer-arm.cc +382 -92
  46. data/vendor/v8/src/arm/disasm-arm.cc +61 -12
  47. data/vendor/v8/src/arm/frames-arm.h +0 -14
  48. data/vendor/v8/src/arm/full-codegen-arm.cc +332 -304
  49. data/vendor/v8/src/arm/ic-arm.cc +180 -259
  50. data/vendor/v8/src/arm/lithium-arm.cc +364 -316
  51. data/vendor/v8/src/arm/lithium-arm.h +512 -275
  52. data/vendor/v8/src/arm/lithium-codegen-arm.cc +1768 -809
  53. data/vendor/v8/src/arm/lithium-codegen-arm.h +97 -35
  54. data/vendor/v8/src/arm/lithium-gap-resolver-arm.cc +12 -5
  55. data/vendor/v8/src/arm/macro-assembler-arm.cc +439 -228
  56. data/vendor/v8/src/arm/macro-assembler-arm.h +116 -70
  57. data/vendor/v8/src/arm/regexp-macro-assembler-arm.cc +54 -44
  58. data/vendor/v8/src/arm/regexp-macro-assembler-arm.h +3 -10
  59. data/vendor/v8/src/arm/simulator-arm.cc +272 -238
  60. data/vendor/v8/src/arm/simulator-arm.h +38 -8
  61. data/vendor/v8/src/arm/stub-cache-arm.cc +522 -895
  62. data/vendor/v8/src/array.js +101 -70
  63. data/vendor/v8/src/assembler.cc +270 -19
  64. data/vendor/v8/src/assembler.h +110 -15
  65. data/vendor/v8/src/ast.cc +79 -69
  66. data/vendor/v8/src/ast.h +255 -301
  67. data/vendor/v8/src/atomicops.h +7 -1
  68. data/vendor/v8/src/atomicops_internals_tsan.h +335 -0
  69. data/vendor/v8/src/bootstrapper.cc +481 -418
  70. data/vendor/v8/src/bootstrapper.h +4 -4
  71. data/vendor/v8/src/builtins.cc +498 -311
  72. data/vendor/v8/src/builtins.h +75 -47
  73. data/vendor/v8/src/checks.cc +2 -1
  74. data/vendor/v8/src/checks.h +8 -0
  75. data/vendor/v8/src/code-stubs-hydrogen.cc +253 -0
  76. data/vendor/v8/src/code-stubs.cc +249 -84
  77. data/vendor/v8/src/code-stubs.h +501 -169
  78. data/vendor/v8/src/codegen.cc +36 -18
  79. data/vendor/v8/src/codegen.h +25 -3
  80. data/vendor/v8/src/collection.js +54 -17
  81. data/vendor/v8/src/compilation-cache.cc +24 -16
  82. data/vendor/v8/src/compilation-cache.h +15 -6
  83. data/vendor/v8/src/compiler.cc +497 -195
  84. data/vendor/v8/src/compiler.h +246 -38
  85. data/vendor/v8/src/contexts.cc +64 -24
  86. data/vendor/v8/src/contexts.h +60 -29
  87. data/vendor/v8/src/conversions-inl.h +24 -14
  88. data/vendor/v8/src/conversions.h +7 -4
  89. data/vendor/v8/src/counters.cc +21 -12
  90. data/vendor/v8/src/counters.h +44 -16
  91. data/vendor/v8/src/cpu-profiler.h +1 -1
  92. data/vendor/v8/src/d8-debug.cc +2 -2
  93. data/vendor/v8/src/d8-readline.cc +13 -2
  94. data/vendor/v8/src/d8.cc +681 -273
  95. data/vendor/v8/src/d8.gyp +4 -4
  96. data/vendor/v8/src/d8.h +38 -18
  97. data/vendor/v8/src/d8.js +0 -617
  98. data/vendor/v8/src/data-flow.h +55 -0
  99. data/vendor/v8/src/date.js +1 -42
  100. data/vendor/v8/src/dateparser-inl.h +5 -1
  101. data/vendor/v8/src/debug-agent.cc +10 -15
  102. data/vendor/v8/src/debug-debugger.js +147 -149
  103. data/vendor/v8/src/debug.cc +323 -164
  104. data/vendor/v8/src/debug.h +26 -14
  105. data/vendor/v8/src/deoptimizer.cc +765 -290
  106. data/vendor/v8/src/deoptimizer.h +130 -28
  107. data/vendor/v8/src/disassembler.cc +10 -4
  108. data/vendor/v8/src/elements-kind.cc +7 -2
  109. data/vendor/v8/src/elements-kind.h +19 -0
  110. data/vendor/v8/src/elements.cc +607 -285
  111. data/vendor/v8/src/elements.h +36 -13
  112. data/vendor/v8/src/execution.cc +52 -31
  113. data/vendor/v8/src/execution.h +4 -4
  114. data/vendor/v8/src/extensions/externalize-string-extension.cc +5 -4
  115. data/vendor/v8/src/extensions/gc-extension.cc +5 -1
  116. data/vendor/v8/src/extensions/statistics-extension.cc +153 -0
  117. data/vendor/v8/src/{inspector.h → extensions/statistics-extension.h} +12 -23
  118. data/vendor/v8/src/factory.cc +101 -134
  119. data/vendor/v8/src/factory.h +36 -31
  120. data/vendor/v8/src/flag-definitions.h +102 -25
  121. data/vendor/v8/src/flags.cc +9 -5
  122. data/vendor/v8/src/frames-inl.h +10 -0
  123. data/vendor/v8/src/frames.cc +116 -26
  124. data/vendor/v8/src/frames.h +96 -12
  125. data/vendor/v8/src/full-codegen.cc +219 -74
  126. data/vendor/v8/src/full-codegen.h +63 -21
  127. data/vendor/v8/src/func-name-inferrer.cc +8 -7
  128. data/vendor/v8/src/func-name-inferrer.h +5 -3
  129. data/vendor/v8/src/gdb-jit.cc +71 -57
  130. data/vendor/v8/src/global-handles.cc +230 -101
  131. data/vendor/v8/src/global-handles.h +26 -27
  132. data/vendor/v8/src/globals.h +17 -19
  133. data/vendor/v8/src/handles-inl.h +59 -12
  134. data/vendor/v8/src/handles.cc +180 -200
  135. data/vendor/v8/src/handles.h +80 -11
  136. data/vendor/v8/src/hashmap.h +60 -40
  137. data/vendor/v8/src/heap-inl.h +107 -45
  138. data/vendor/v8/src/heap-profiler.cc +38 -19
  139. data/vendor/v8/src/heap-profiler.h +24 -14
  140. data/vendor/v8/src/heap.cc +1123 -738
  141. data/vendor/v8/src/heap.h +385 -146
  142. data/vendor/v8/src/hydrogen-instructions.cc +700 -217
  143. data/vendor/v8/src/hydrogen-instructions.h +1158 -472
  144. data/vendor/v8/src/hydrogen.cc +3319 -1662
  145. data/vendor/v8/src/hydrogen.h +411 -170
  146. data/vendor/v8/src/ia32/assembler-ia32-inl.h +46 -16
  147. data/vendor/v8/src/ia32/assembler-ia32.cc +131 -61
  148. data/vendor/v8/src/ia32/assembler-ia32.h +115 -57
  149. data/vendor/v8/src/ia32/builtins-ia32.cc +99 -5
  150. data/vendor/v8/src/ia32/code-stubs-ia32.cc +787 -495
  151. data/vendor/v8/src/ia32/code-stubs-ia32.h +10 -100
  152. data/vendor/v8/src/ia32/codegen-ia32.cc +227 -23
  153. data/vendor/v8/src/ia32/codegen-ia32.h +14 -0
  154. data/vendor/v8/src/ia32/deoptimizer-ia32.cc +428 -87
  155. data/vendor/v8/src/ia32/disasm-ia32.cc +28 -1
  156. data/vendor/v8/src/ia32/frames-ia32.h +6 -16
  157. data/vendor/v8/src/ia32/full-codegen-ia32.cc +280 -272
  158. data/vendor/v8/src/ia32/ic-ia32.cc +150 -250
  159. data/vendor/v8/src/ia32/lithium-codegen-ia32.cc +1600 -517
  160. data/vendor/v8/src/ia32/lithium-codegen-ia32.h +90 -24
  161. data/vendor/v8/src/ia32/lithium-gap-resolver-ia32.cc +10 -6
  162. data/vendor/v8/src/ia32/lithium-gap-resolver-ia32.h +2 -2
  163. data/vendor/v8/src/ia32/lithium-ia32.cc +405 -302
  164. data/vendor/v8/src/ia32/lithium-ia32.h +526 -271
  165. data/vendor/v8/src/ia32/macro-assembler-ia32.cc +378 -119
  166. data/vendor/v8/src/ia32/macro-assembler-ia32.h +62 -28
  167. data/vendor/v8/src/ia32/regexp-macro-assembler-ia32.cc +43 -30
  168. data/vendor/v8/src/ia32/regexp-macro-assembler-ia32.h +2 -10
  169. data/vendor/v8/src/ia32/stub-cache-ia32.cc +492 -678
  170. data/vendor/v8/src/ic-inl.h +9 -4
  171. data/vendor/v8/src/ic.cc +836 -923
  172. data/vendor/v8/src/ic.h +228 -247
  173. data/vendor/v8/src/incremental-marking-inl.h +26 -30
  174. data/vendor/v8/src/incremental-marking.cc +276 -248
  175. data/vendor/v8/src/incremental-marking.h +29 -37
  176. data/vendor/v8/src/interface.cc +34 -25
  177. data/vendor/v8/src/interface.h +69 -25
  178. data/vendor/v8/src/interpreter-irregexp.cc +2 -2
  179. data/vendor/v8/src/isolate.cc +382 -76
  180. data/vendor/v8/src/isolate.h +109 -56
  181. data/vendor/v8/src/json-parser.h +217 -104
  182. data/vendor/v8/src/json-stringifier.h +745 -0
  183. data/vendor/v8/src/json.js +10 -132
  184. data/vendor/v8/src/jsregexp-inl.h +106 -0
  185. data/vendor/v8/src/jsregexp.cc +517 -285
  186. data/vendor/v8/src/jsregexp.h +145 -117
  187. data/vendor/v8/src/list-inl.h +35 -22
  188. data/vendor/v8/src/list.h +46 -19
  189. data/vendor/v8/src/lithium-allocator-inl.h +22 -2
  190. data/vendor/v8/src/lithium-allocator.cc +85 -70
  191. data/vendor/v8/src/lithium-allocator.h +21 -39
  192. data/vendor/v8/src/lithium.cc +259 -5
  193. data/vendor/v8/src/lithium.h +131 -32
  194. data/vendor/v8/src/liveedit-debugger.js +52 -3
  195. data/vendor/v8/src/liveedit.cc +393 -113
  196. data/vendor/v8/src/liveedit.h +7 -3
  197. data/vendor/v8/src/log-utils.cc +4 -2
  198. data/vendor/v8/src/log.cc +170 -140
  199. data/vendor/v8/src/log.h +62 -11
  200. data/vendor/v8/src/macro-assembler.h +17 -0
  201. data/vendor/v8/src/macros.py +2 -0
  202. data/vendor/v8/src/mark-compact-inl.h +3 -23
  203. data/vendor/v8/src/mark-compact.cc +801 -830
  204. data/vendor/v8/src/mark-compact.h +154 -47
  205. data/vendor/v8/src/marking-thread.cc +85 -0
  206. data/vendor/v8/src/{inspector.cc → marking-thread.h} +32 -24
  207. data/vendor/v8/src/math.js +12 -18
  208. data/vendor/v8/src/messages.cc +18 -8
  209. data/vendor/v8/src/messages.js +314 -261
  210. data/vendor/v8/src/mips/assembler-mips-inl.h +58 -6
  211. data/vendor/v8/src/mips/assembler-mips.cc +92 -75
  212. data/vendor/v8/src/mips/assembler-mips.h +54 -60
  213. data/vendor/v8/src/mips/builtins-mips.cc +116 -17
  214. data/vendor/v8/src/mips/code-stubs-mips.cc +919 -556
  215. data/vendor/v8/src/mips/code-stubs-mips.h +22 -131
  216. data/vendor/v8/src/mips/codegen-mips.cc +281 -6
  217. data/vendor/v8/src/mips/codegen-mips.h +22 -0
  218. data/vendor/v8/src/mips/constants-mips.cc +2 -0
  219. data/vendor/v8/src/mips/constants-mips.h +12 -2
  220. data/vendor/v8/src/mips/deoptimizer-mips.cc +286 -50
  221. data/vendor/v8/src/mips/disasm-mips.cc +13 -0
  222. data/vendor/v8/src/mips/full-codegen-mips.cc +297 -284
  223. data/vendor/v8/src/mips/ic-mips.cc +182 -263
  224. data/vendor/v8/src/mips/lithium-codegen-mips.cc +1208 -556
  225. data/vendor/v8/src/mips/lithium-codegen-mips.h +72 -19
  226. data/vendor/v8/src/mips/lithium-gap-resolver-mips.cc +9 -2
  227. data/vendor/v8/src/mips/lithium-mips.cc +290 -302
  228. data/vendor/v8/src/mips/lithium-mips.h +463 -266
  229. data/vendor/v8/src/mips/macro-assembler-mips.cc +208 -115
  230. data/vendor/v8/src/mips/macro-assembler-mips.h +67 -24
  231. data/vendor/v8/src/mips/regexp-macro-assembler-mips.cc +40 -25
  232. data/vendor/v8/src/mips/regexp-macro-assembler-mips.h +3 -9
  233. data/vendor/v8/src/mips/simulator-mips.cc +112 -40
  234. data/vendor/v8/src/mips/simulator-mips.h +5 -0
  235. data/vendor/v8/src/mips/stub-cache-mips.cc +502 -884
  236. data/vendor/v8/src/mirror-debugger.js +157 -30
  237. data/vendor/v8/src/mksnapshot.cc +88 -14
  238. data/vendor/v8/src/object-observe.js +235 -0
  239. data/vendor/v8/src/objects-debug.cc +178 -176
  240. data/vendor/v8/src/objects-inl.h +1333 -486
  241. data/vendor/v8/src/objects-printer.cc +125 -43
  242. data/vendor/v8/src/objects-visiting-inl.h +578 -6
  243. data/vendor/v8/src/objects-visiting.cc +2 -2
  244. data/vendor/v8/src/objects-visiting.h +172 -79
  245. data/vendor/v8/src/objects.cc +3533 -2885
  246. data/vendor/v8/src/objects.h +1352 -1131
  247. data/vendor/v8/src/optimizing-compiler-thread.cc +152 -0
  248. data/vendor/v8/src/optimizing-compiler-thread.h +111 -0
  249. data/vendor/v8/src/parser.cc +390 -500
  250. data/vendor/v8/src/parser.h +45 -33
  251. data/vendor/v8/src/platform-cygwin.cc +10 -21
  252. data/vendor/v8/src/platform-freebsd.cc +36 -41
  253. data/vendor/v8/src/platform-linux.cc +160 -124
  254. data/vendor/v8/src/platform-macos.cc +30 -27
  255. data/vendor/v8/src/platform-nullos.cc +17 -1
  256. data/vendor/v8/src/platform-openbsd.cc +19 -50
  257. data/vendor/v8/src/platform-posix.cc +14 -0
  258. data/vendor/v8/src/platform-solaris.cc +20 -53
  259. data/vendor/v8/src/platform-win32.cc +49 -26
  260. data/vendor/v8/src/platform.h +40 -1
  261. data/vendor/v8/src/preparser.cc +8 -5
  262. data/vendor/v8/src/preparser.h +2 -2
  263. data/vendor/v8/src/prettyprinter.cc +16 -0
  264. data/vendor/v8/src/prettyprinter.h +2 -0
  265. data/vendor/v8/src/profile-generator-inl.h +1 -0
  266. data/vendor/v8/src/profile-generator.cc +209 -147
  267. data/vendor/v8/src/profile-generator.h +15 -12
  268. data/vendor/v8/src/property-details.h +46 -31
  269. data/vendor/v8/src/property.cc +27 -46
  270. data/vendor/v8/src/property.h +163 -83
  271. data/vendor/v8/src/proxy.js +7 -2
  272. data/vendor/v8/src/regexp-macro-assembler-irregexp.cc +4 -13
  273. data/vendor/v8/src/regexp-macro-assembler-irregexp.h +1 -2
  274. data/vendor/v8/src/regexp-macro-assembler-tracer.cc +1 -11
  275. data/vendor/v8/src/regexp-macro-assembler-tracer.h +0 -1
  276. data/vendor/v8/src/regexp-macro-assembler.cc +31 -14
  277. data/vendor/v8/src/regexp-macro-assembler.h +14 -11
  278. data/vendor/v8/src/regexp-stack.cc +1 -0
  279. data/vendor/v8/src/regexp.js +9 -8
  280. data/vendor/v8/src/rewriter.cc +18 -7
  281. data/vendor/v8/src/runtime-profiler.cc +52 -43
  282. data/vendor/v8/src/runtime-profiler.h +0 -25
  283. data/vendor/v8/src/runtime.cc +2006 -2023
  284. data/vendor/v8/src/runtime.h +56 -49
  285. data/vendor/v8/src/safepoint-table.cc +12 -18
  286. data/vendor/v8/src/safepoint-table.h +11 -8
  287. data/vendor/v8/src/scanner.cc +1 -0
  288. data/vendor/v8/src/scanner.h +4 -10
  289. data/vendor/v8/src/scopeinfo.cc +35 -9
  290. data/vendor/v8/src/scopeinfo.h +64 -3
  291. data/vendor/v8/src/scopes.cc +251 -156
  292. data/vendor/v8/src/scopes.h +61 -27
  293. data/vendor/v8/src/serialize.cc +348 -396
  294. data/vendor/v8/src/serialize.h +125 -114
  295. data/vendor/v8/src/small-pointer-list.h +11 -11
  296. data/vendor/v8/src/{smart-array-pointer.h → smart-pointers.h} +64 -15
  297. data/vendor/v8/src/snapshot-common.cc +64 -15
  298. data/vendor/v8/src/snapshot-empty.cc +7 -1
  299. data/vendor/v8/src/snapshot.h +9 -2
  300. data/vendor/v8/src/spaces-inl.h +17 -0
  301. data/vendor/v8/src/spaces.cc +477 -183
  302. data/vendor/v8/src/spaces.h +238 -58
  303. data/vendor/v8/src/splay-tree-inl.h +8 -7
  304. data/vendor/v8/src/splay-tree.h +24 -10
  305. data/vendor/v8/src/store-buffer.cc +12 -5
  306. data/vendor/v8/src/store-buffer.h +2 -4
  307. data/vendor/v8/src/string-search.h +22 -6
  308. data/vendor/v8/src/string-stream.cc +11 -8
  309. data/vendor/v8/src/string.js +47 -15
  310. data/vendor/v8/src/stub-cache.cc +461 -224
  311. data/vendor/v8/src/stub-cache.h +164 -102
  312. data/vendor/v8/src/sweeper-thread.cc +105 -0
  313. data/vendor/v8/src/sweeper-thread.h +81 -0
  314. data/vendor/v8/src/token.h +1 -0
  315. data/vendor/v8/src/transitions-inl.h +220 -0
  316. data/vendor/v8/src/transitions.cc +160 -0
  317. data/vendor/v8/src/transitions.h +207 -0
  318. data/vendor/v8/src/type-info.cc +182 -181
  319. data/vendor/v8/src/type-info.h +31 -19
  320. data/vendor/v8/src/unicode-inl.h +62 -106
  321. data/vendor/v8/src/unicode.cc +57 -67
  322. data/vendor/v8/src/unicode.h +45 -91
  323. data/vendor/v8/src/uri.js +57 -29
  324. data/vendor/v8/src/utils.h +105 -5
  325. data/vendor/v8/src/v8-counters.cc +54 -11
  326. data/vendor/v8/src/v8-counters.h +134 -19
  327. data/vendor/v8/src/v8.cc +29 -29
  328. data/vendor/v8/src/v8.h +1 -0
  329. data/vendor/v8/src/v8conversions.cc +26 -22
  330. data/vendor/v8/src/v8globals.h +56 -43
  331. data/vendor/v8/src/v8natives.js +83 -30
  332. data/vendor/v8/src/v8threads.cc +42 -21
  333. data/vendor/v8/src/v8threads.h +4 -1
  334. data/vendor/v8/src/v8utils.cc +9 -93
  335. data/vendor/v8/src/v8utils.h +37 -33
  336. data/vendor/v8/src/variables.cc +6 -3
  337. data/vendor/v8/src/variables.h +6 -13
  338. data/vendor/v8/src/version.cc +2 -2
  339. data/vendor/v8/src/vm-state-inl.h +11 -0
  340. data/vendor/v8/src/x64/assembler-x64-inl.h +39 -8
  341. data/vendor/v8/src/x64/assembler-x64.cc +78 -64
  342. data/vendor/v8/src/x64/assembler-x64.h +38 -33
  343. data/vendor/v8/src/x64/builtins-x64.cc +105 -7
  344. data/vendor/v8/src/x64/code-stubs-x64.cc +790 -413
  345. data/vendor/v8/src/x64/code-stubs-x64.h +10 -106
  346. data/vendor/v8/src/x64/codegen-x64.cc +210 -8
  347. data/vendor/v8/src/x64/codegen-x64.h +20 -1
  348. data/vendor/v8/src/x64/deoptimizer-x64.cc +336 -75
  349. data/vendor/v8/src/x64/disasm-x64.cc +15 -0
  350. data/vendor/v8/src/x64/frames-x64.h +0 -14
  351. data/vendor/v8/src/x64/full-codegen-x64.cc +293 -270
  352. data/vendor/v8/src/x64/ic-x64.cc +153 -251
  353. data/vendor/v8/src/x64/lithium-codegen-x64.cc +1379 -531
  354. data/vendor/v8/src/x64/lithium-codegen-x64.h +67 -23
  355. data/vendor/v8/src/x64/lithium-gap-resolver-x64.cc +2 -2
  356. data/vendor/v8/src/x64/lithium-x64.cc +349 -289
  357. data/vendor/v8/src/x64/lithium-x64.h +460 -250
  358. data/vendor/v8/src/x64/macro-assembler-x64.cc +350 -177
  359. data/vendor/v8/src/x64/macro-assembler-x64.h +67 -49
  360. data/vendor/v8/src/x64/regexp-macro-assembler-x64.cc +46 -33
  361. data/vendor/v8/src/x64/regexp-macro-assembler-x64.h +2 -3
  362. data/vendor/v8/src/x64/stub-cache-x64.cc +484 -653
  363. data/vendor/v8/src/zone-inl.h +9 -27
  364. data/vendor/v8/src/zone.cc +5 -5
  365. data/vendor/v8/src/zone.h +53 -27
  366. data/vendor/v8/test/benchmarks/testcfg.py +5 -0
  367. data/vendor/v8/test/cctest/cctest.cc +4 -0
  368. data/vendor/v8/test/cctest/cctest.gyp +3 -1
  369. data/vendor/v8/test/cctest/cctest.h +57 -9
  370. data/vendor/v8/test/cctest/cctest.status +15 -15
  371. data/vendor/v8/test/cctest/test-accessors.cc +26 -0
  372. data/vendor/v8/test/cctest/test-alloc.cc +22 -30
  373. data/vendor/v8/test/cctest/test-api.cc +1943 -314
  374. data/vendor/v8/test/cctest/test-assembler-arm.cc +133 -13
  375. data/vendor/v8/test/cctest/test-assembler-ia32.cc +1 -1
  376. data/vendor/v8/test/cctest/test-assembler-mips.cc +12 -0
  377. data/vendor/v8/test/cctest/test-ast.cc +4 -2
  378. data/vendor/v8/test/cctest/test-compiler.cc +61 -29
  379. data/vendor/v8/test/cctest/test-dataflow.cc +2 -2
  380. data/vendor/v8/test/cctest/test-debug.cc +212 -33
  381. data/vendor/v8/test/cctest/test-decls.cc +257 -11
  382. data/vendor/v8/test/cctest/test-dictionary.cc +24 -10
  383. data/vendor/v8/test/cctest/test-disasm-arm.cc +118 -1
  384. data/vendor/v8/test/cctest/test-disasm-ia32.cc +3 -2
  385. data/vendor/v8/test/cctest/test-flags.cc +14 -1
  386. data/vendor/v8/test/cctest/test-func-name-inference.cc +7 -4
  387. data/vendor/v8/test/cctest/test-global-object.cc +51 -0
  388. data/vendor/v8/test/cctest/test-hashing.cc +32 -23
  389. data/vendor/v8/test/cctest/test-heap-profiler.cc +131 -77
  390. data/vendor/v8/test/cctest/test-heap.cc +1084 -143
  391. data/vendor/v8/test/cctest/test-list.cc +1 -1
  392. data/vendor/v8/test/cctest/test-liveedit.cc +3 -2
  393. data/vendor/v8/test/cctest/test-lockers.cc +12 -13
  394. data/vendor/v8/test/cctest/test-log.cc +10 -8
  395. data/vendor/v8/test/cctest/test-macro-assembler-x64.cc +2 -2
  396. data/vendor/v8/test/cctest/test-mark-compact.cc +44 -22
  397. data/vendor/v8/test/cctest/test-object-observe.cc +434 -0
  398. data/vendor/v8/test/cctest/test-parsing.cc +86 -39
  399. data/vendor/v8/test/cctest/test-platform-linux.cc +6 -0
  400. data/vendor/v8/test/cctest/test-platform-win32.cc +7 -0
  401. data/vendor/v8/test/cctest/test-random.cc +5 -4
  402. data/vendor/v8/test/cctest/test-regexp.cc +137 -101
  403. data/vendor/v8/test/cctest/test-serialize.cc +150 -230
  404. data/vendor/v8/test/cctest/test-sockets.cc +1 -1
  405. data/vendor/v8/test/cctest/test-spaces.cc +139 -0
  406. data/vendor/v8/test/cctest/test-strings.cc +736 -74
  407. data/vendor/v8/test/cctest/test-thread-termination.cc +10 -11
  408. data/vendor/v8/test/cctest/test-threads.cc +4 -4
  409. data/vendor/v8/test/cctest/test-utils.cc +16 -0
  410. data/vendor/v8/test/cctest/test-weakmaps.cc +7 -3
  411. data/vendor/v8/test/cctest/testcfg.py +64 -5
  412. data/vendor/v8/test/es5conform/testcfg.py +5 -0
  413. data/vendor/v8/test/message/message.status +1 -1
  414. data/vendor/v8/test/message/overwritten-builtins.out +3 -0
  415. data/vendor/v8/test/message/testcfg.py +89 -8
  416. data/vendor/v8/test/message/try-catch-finally-no-message.out +26 -26
  417. data/vendor/v8/test/mjsunit/accessor-map-sharing.js +18 -2
  418. data/vendor/v8/test/mjsunit/allocation-site-info.js +126 -0
  419. data/vendor/v8/test/mjsunit/array-bounds-check-removal.js +62 -1
  420. data/vendor/v8/test/mjsunit/array-iteration.js +1 -1
  421. data/vendor/v8/test/mjsunit/array-literal-transitions.js +2 -0
  422. data/vendor/v8/test/mjsunit/array-natives-elements.js +317 -0
  423. data/vendor/v8/test/mjsunit/array-reduce.js +8 -8
  424. data/vendor/v8/test/mjsunit/array-slice.js +12 -0
  425. data/vendor/v8/test/mjsunit/array-store-and-grow.js +4 -1
  426. data/vendor/v8/test/mjsunit/assert-opt-and-deopt.js +1 -1
  427. data/vendor/v8/test/mjsunit/bugs/bug-2337.js +53 -0
  428. data/vendor/v8/test/mjsunit/compare-known-objects-slow.js +69 -0
  429. data/vendor/v8/test/mjsunit/compiler/alloc-object-huge.js +3 -1
  430. data/vendor/v8/test/mjsunit/compiler/inline-accessors.js +368 -0
  431. data/vendor/v8/test/mjsunit/compiler/inline-arguments.js +87 -1
  432. data/vendor/v8/test/mjsunit/compiler/inline-closures.js +49 -0
  433. data/vendor/v8/test/mjsunit/compiler/inline-construct.js +55 -43
  434. data/vendor/v8/test/mjsunit/compiler/inline-literals.js +39 -0
  435. data/vendor/v8/test/mjsunit/compiler/multiply-add.js +69 -0
  436. data/vendor/v8/test/mjsunit/compiler/optimized-closures.js +57 -0
  437. data/vendor/v8/test/mjsunit/compiler/parallel-proto-change.js +44 -0
  438. data/vendor/v8/test/mjsunit/compiler/property-static.js +69 -0
  439. data/vendor/v8/test/mjsunit/compiler/proto-chain-constant.js +55 -0
  440. data/vendor/v8/test/mjsunit/compiler/proto-chain-load.js +44 -0
  441. data/vendor/v8/test/mjsunit/compiler/regress-gvn.js +3 -2
  442. data/vendor/v8/test/mjsunit/compiler/regress-or.js +6 -2
  443. data/vendor/v8/test/mjsunit/compiler/rotate.js +224 -0
  444. data/vendor/v8/test/mjsunit/compiler/uint32.js +173 -0
  445. data/vendor/v8/test/mjsunit/count-based-osr.js +2 -1
  446. data/vendor/v8/test/mjsunit/d8-os.js +3 -3
  447. data/vendor/v8/test/mjsunit/date-parse.js +3 -0
  448. data/vendor/v8/test/mjsunit/date.js +22 -0
  449. data/vendor/v8/test/mjsunit/debug-break-inline.js +1 -0
  450. data/vendor/v8/test/mjsunit/debug-evaluate-locals-optimized-double.js +22 -12
  451. data/vendor/v8/test/mjsunit/debug-evaluate-locals-optimized.js +21 -10
  452. data/vendor/v8/test/mjsunit/debug-liveedit-compile-error.js +60 -0
  453. data/vendor/v8/test/mjsunit/debug-liveedit-double-call.js +142 -0
  454. data/vendor/v8/test/mjsunit/debug-liveedit-literals.js +94 -0
  455. data/vendor/v8/test/mjsunit/debug-liveedit-restart-frame.js +153 -0
  456. data/vendor/v8/test/mjsunit/debug-multiple-breakpoints.js +1 -1
  457. data/vendor/v8/test/mjsunit/debug-script-breakpoints-closure.js +67 -0
  458. data/vendor/v8/test/mjsunit/debug-script-breakpoints-nested.js +82 -0
  459. data/vendor/v8/test/mjsunit/debug-script.js +4 -2
  460. data/vendor/v8/test/mjsunit/debug-set-variable-value.js +308 -0
  461. data/vendor/v8/test/mjsunit/debug-stepout-scope-part1.js +190 -0
  462. data/vendor/v8/test/mjsunit/debug-stepout-scope-part2.js +83 -0
  463. data/vendor/v8/test/mjsunit/debug-stepout-scope-part3.js +80 -0
  464. data/vendor/v8/test/mjsunit/debug-stepout-scope-part4.js +80 -0
  465. data/vendor/v8/test/mjsunit/debug-stepout-scope-part5.js +77 -0
  466. data/vendor/v8/test/mjsunit/debug-stepout-scope-part6.js +79 -0
  467. data/vendor/v8/test/mjsunit/debug-stepout-scope-part7.js +79 -0
  468. data/vendor/v8/test/mjsunit/{debug-stepout-scope.js → debug-stepout-scope-part8.js} +0 -189
  469. data/vendor/v8/test/mjsunit/delete-non-configurable.js +74 -0
  470. data/vendor/v8/test/mjsunit/deopt-minus-zero.js +56 -0
  471. data/vendor/v8/test/mjsunit/elements-kind.js +6 -4
  472. data/vendor/v8/test/mjsunit/elements-length-no-holey.js +33 -0
  473. data/vendor/v8/test/mjsunit/elements-transition-hoisting.js +46 -19
  474. data/vendor/v8/test/mjsunit/error-accessors.js +54 -0
  475. data/vendor/v8/test/mjsunit/error-constructors.js +1 -14
  476. data/vendor/v8/test/mjsunit/error-tostring.js +8 -0
  477. data/vendor/v8/test/mjsunit/eval-stack-trace.js +204 -0
  478. data/vendor/v8/test/mjsunit/external-array.js +364 -1
  479. data/vendor/v8/test/mjsunit/fast-array-length.js +37 -0
  480. data/vendor/v8/test/mjsunit/fast-non-keyed.js +113 -0
  481. data/vendor/v8/test/mjsunit/fast-prototype.js +117 -0
  482. data/vendor/v8/test/mjsunit/function-call.js +14 -18
  483. data/vendor/v8/test/mjsunit/fuzz-natives-part1.js +230 -0
  484. data/vendor/v8/test/mjsunit/fuzz-natives-part2.js +229 -0
  485. data/vendor/v8/test/mjsunit/fuzz-natives-part3.js +229 -0
  486. data/vendor/v8/test/mjsunit/{fuzz-natives.js → fuzz-natives-part4.js} +12 -2
  487. data/vendor/v8/test/mjsunit/generated-transition-stub.js +218 -0
  488. data/vendor/v8/test/mjsunit/greedy.js +1 -1
  489. data/vendor/v8/test/mjsunit/harmony/block-conflicts.js +2 -1
  490. data/vendor/v8/test/mjsunit/harmony/block-let-crankshaft.js +1 -1
  491. data/vendor/v8/test/mjsunit/harmony/collections.js +69 -11
  492. data/vendor/v8/test/mjsunit/harmony/debug-blockscopes.js +2 -2
  493. data/vendor/v8/test/mjsunit/harmony/module-linking.js +180 -3
  494. data/vendor/v8/test/mjsunit/harmony/module-parsing.js +31 -0
  495. data/vendor/v8/test/mjsunit/harmony/module-recompile.js +87 -0
  496. data/vendor/v8/test/mjsunit/harmony/module-resolution.js +15 -2
  497. data/vendor/v8/test/mjsunit/harmony/object-observe.js +1056 -0
  498. data/vendor/v8/test/mjsunit/harmony/proxies-json.js +178 -0
  499. data/vendor/v8/test/mjsunit/harmony/proxies.js +25 -10
  500. data/vendor/v8/test/mjsunit/json-parser-recursive.js +33 -0
  501. data/vendor/v8/test/mjsunit/json-stringify-recursive.js +52 -0
  502. data/vendor/v8/test/mjsunit/json.js +38 -2
  503. data/vendor/v8/test/mjsunit/json2.js +153 -0
  504. data/vendor/v8/test/mjsunit/limit-locals.js +5 -4
  505. data/vendor/v8/test/mjsunit/manual-parallel-recompile.js +79 -0
  506. data/vendor/v8/test/mjsunit/math-exp-precision.js +64 -0
  507. data/vendor/v8/test/mjsunit/math-floor-negative.js +59 -0
  508. data/vendor/v8/test/mjsunit/math-floor-of-div-minus-zero.js +41 -0
  509. data/vendor/v8/test/mjsunit/math-floor-of-div-nosudiv.js +288 -0
  510. data/vendor/v8/test/mjsunit/math-floor-of-div.js +81 -9
  511. data/vendor/v8/test/mjsunit/{math-floor.js → math-floor-part1.js} +1 -72
  512. data/vendor/v8/test/mjsunit/math-floor-part2.js +76 -0
  513. data/vendor/v8/test/mjsunit/math-floor-part3.js +78 -0
  514. data/vendor/v8/test/mjsunit/math-floor-part4.js +76 -0
  515. data/vendor/v8/test/mjsunit/mirror-object.js +43 -9
  516. data/vendor/v8/test/mjsunit/mjsunit.js +1 -1
  517. data/vendor/v8/test/mjsunit/mjsunit.status +52 -27
  518. data/vendor/v8/test/mjsunit/mul-exhaustive-part1.js +491 -0
  519. data/vendor/v8/test/mjsunit/mul-exhaustive-part10.js +470 -0
  520. data/vendor/v8/test/mjsunit/mul-exhaustive-part2.js +525 -0
  521. data/vendor/v8/test/mjsunit/mul-exhaustive-part3.js +532 -0
  522. data/vendor/v8/test/mjsunit/mul-exhaustive-part4.js +509 -0
  523. data/vendor/v8/test/mjsunit/mul-exhaustive-part5.js +505 -0
  524. data/vendor/v8/test/mjsunit/mul-exhaustive-part6.js +554 -0
  525. data/vendor/v8/test/mjsunit/mul-exhaustive-part7.js +497 -0
  526. data/vendor/v8/test/mjsunit/mul-exhaustive-part8.js +526 -0
  527. data/vendor/v8/test/mjsunit/mul-exhaustive-part9.js +533 -0
  528. data/vendor/v8/test/mjsunit/new-function.js +34 -0
  529. data/vendor/v8/test/mjsunit/numops-fuzz-part1.js +1172 -0
  530. data/vendor/v8/test/mjsunit/numops-fuzz-part2.js +1178 -0
  531. data/vendor/v8/test/mjsunit/numops-fuzz-part3.js +1178 -0
  532. data/vendor/v8/test/mjsunit/numops-fuzz-part4.js +1177 -0
  533. data/vendor/v8/test/mjsunit/object-define-property.js +107 -2
  534. data/vendor/v8/test/mjsunit/override-read-only-property.js +6 -4
  535. data/vendor/v8/test/mjsunit/packed-elements.js +2 -2
  536. data/vendor/v8/test/mjsunit/parse-int-float.js +4 -4
  537. data/vendor/v8/test/mjsunit/pixel-array-rounding.js +1 -1
  538. data/vendor/v8/test/mjsunit/readonly.js +228 -0
  539. data/vendor/v8/test/mjsunit/regexp-capture-3.js +16 -18
  540. data/vendor/v8/test/mjsunit/regexp-capture.js +2 -0
  541. data/vendor/v8/test/mjsunit/regexp-global.js +122 -0
  542. data/vendor/v8/test/mjsunit/regexp-results-cache.js +78 -0
  543. data/vendor/v8/test/mjsunit/regress/regress-1117.js +12 -3
  544. data/vendor/v8/test/mjsunit/regress/regress-1118.js +1 -1
  545. data/vendor/v8/test/mjsunit/regress/regress-115100.js +36 -0
  546. data/vendor/v8/test/mjsunit/regress/regress-1199637.js +1 -3
  547. data/vendor/v8/test/mjsunit/regress/regress-121407.js +1 -1
  548. data/vendor/v8/test/mjsunit/regress/regress-131923.js +30 -0
  549. data/vendor/v8/test/mjsunit/regress/regress-131994.js +70 -0
  550. data/vendor/v8/test/mjsunit/regress/regress-133211.js +35 -0
  551. data/vendor/v8/test/mjsunit/regress/regress-133211b.js +39 -0
  552. data/vendor/v8/test/mjsunit/regress/regress-136048.js +34 -0
  553. data/vendor/v8/test/mjsunit/regress/regress-137768.js +73 -0
  554. data/vendor/v8/test/mjsunit/regress/regress-143967.js +34 -0
  555. data/vendor/v8/test/mjsunit/regress/regress-145201.js +107 -0
  556. data/vendor/v8/test/mjsunit/regress/regress-147497.js +45 -0
  557. data/vendor/v8/test/mjsunit/regress/regress-148378.js +38 -0
  558. data/vendor/v8/test/mjsunit/regress/regress-1563.js +1 -1
  559. data/vendor/v8/test/mjsunit/regress/regress-1591.js +48 -0
  560. data/vendor/v8/test/mjsunit/regress/regress-164442.js +45 -0
  561. data/vendor/v8/test/mjsunit/regress/regress-165637.js +61 -0
  562. data/vendor/v8/test/mjsunit/regress/regress-166379.js +39 -0
  563. data/vendor/v8/test/mjsunit/regress/regress-166553.js +33 -0
  564. data/vendor/v8/test/mjsunit/regress/regress-1692.js +1 -1
  565. data/vendor/v8/test/mjsunit/regress/regress-171641.js +40 -0
  566. data/vendor/v8/test/mjsunit/regress/regress-1980.js +1 -1
  567. data/vendor/v8/test/mjsunit/regress/regress-2073.js +99 -0
  568. data/vendor/v8/test/mjsunit/regress/regress-2119.js +36 -0
  569. data/vendor/v8/test/mjsunit/regress/regress-2156.js +39 -0
  570. data/vendor/v8/test/mjsunit/regress/regress-2163.js +70 -0
  571. data/vendor/v8/test/mjsunit/regress/regress-2170.js +58 -0
  572. data/vendor/v8/test/mjsunit/regress/regress-2172.js +35 -0
  573. data/vendor/v8/test/mjsunit/regress/regress-2185-2.js +145 -0
  574. data/vendor/v8/test/mjsunit/regress/regress-2185.js +38 -0
  575. data/vendor/v8/test/mjsunit/regress/regress-2186.js +49 -0
  576. data/vendor/v8/test/mjsunit/regress/regress-2193.js +58 -0
  577. data/vendor/v8/test/mjsunit/regress/regress-2219.js +32 -0
  578. data/vendor/v8/test/mjsunit/regress/regress-2225.js +65 -0
  579. data/vendor/v8/test/mjsunit/regress/regress-2226.js +36 -0
  580. data/vendor/v8/test/mjsunit/regress/regress-2234.js +41 -0
  581. data/vendor/v8/test/mjsunit/regress/regress-2243.js +31 -0
  582. data/vendor/v8/test/mjsunit/regress/regress-2249.js +33 -0
  583. data/vendor/v8/test/mjsunit/regress/regress-2250.js +68 -0
  584. data/vendor/v8/test/mjsunit/regress/regress-2261.js +113 -0
  585. data/vendor/v8/test/mjsunit/regress/regress-2263.js +30 -0
  586. data/vendor/v8/test/mjsunit/regress/regress-2284.js +32 -0
  587. data/vendor/v8/test/mjsunit/regress/regress-2285.js +32 -0
  588. data/vendor/v8/test/mjsunit/regress/regress-2286.js +32 -0
  589. data/vendor/v8/test/mjsunit/regress/regress-2289.js +34 -0
  590. data/vendor/v8/test/mjsunit/regress/regress-2291.js +36 -0
  591. data/vendor/v8/test/mjsunit/regress/regress-2294.js +70 -0
  592. data/vendor/v8/test/mjsunit/regress/regress-2296.js +40 -0
  593. data/vendor/v8/test/mjsunit/regress/regress-2315.js +40 -0
  594. data/vendor/v8/test/mjsunit/regress/regress-2318.js +66 -0
  595. data/vendor/v8/test/mjsunit/regress/regress-2322.js +36 -0
  596. data/vendor/v8/test/mjsunit/regress/regress-2326.js +54 -0
  597. data/vendor/v8/test/mjsunit/regress/regress-2336.js +53 -0
  598. data/vendor/v8/test/mjsunit/regress/regress-2339.js +59 -0
  599. data/vendor/v8/test/mjsunit/regress/regress-2346.js +123 -0
  600. data/vendor/v8/test/mjsunit/regress/regress-2373.js +29 -0
  601. data/vendor/v8/test/mjsunit/regress/regress-2374.js +33 -0
  602. data/vendor/v8/test/mjsunit/regress/regress-2398.js +41 -0
  603. data/vendor/v8/test/mjsunit/regress/regress-2410.js +36 -0
  604. data/vendor/v8/test/mjsunit/regress/regress-2416.js +75 -0
  605. data/vendor/v8/test/mjsunit/regress/regress-2419.js +37 -0
  606. data/vendor/v8/test/mjsunit/regress/regress-2433.js +36 -0
  607. data/vendor/v8/test/mjsunit/regress/regress-2437.js +156 -0
  608. data/vendor/v8/test/mjsunit/regress/regress-2438.js +52 -0
  609. data/vendor/v8/test/mjsunit/regress/regress-2443.js +129 -0
  610. data/vendor/v8/test/mjsunit/regress/regress-2444.js +120 -0
  611. data/vendor/v8/test/mjsunit/regress/regress-2489.js +50 -0
  612. data/vendor/v8/test/mjsunit/regress/regress-2499.js +40 -0
  613. data/vendor/v8/test/mjsunit/regress/regress-334.js +1 -1
  614. data/vendor/v8/test/mjsunit/regress/regress-492.js +39 -1
  615. data/vendor/v8/test/mjsunit/regress/regress-builtin-array-op.js +38 -0
  616. data/vendor/v8/test/mjsunit/regress/regress-cnlt-elements.js +43 -0
  617. data/vendor/v8/test/mjsunit/regress/regress-cnlt-enum-indices.js +45 -0
  618. data/vendor/v8/test/mjsunit/regress/regress-cntl-descriptors-enum.js +46 -0
  619. data/vendor/v8/test/mjsunit/regress/regress-convert-enum.js +60 -0
  620. data/vendor/v8/test/mjsunit/regress/regress-convert-enum2.js +46 -0
  621. data/vendor/v8/test/mjsunit/regress/regress-convert-transition.js +40 -0
  622. data/vendor/v8/test/mjsunit/regress/regress-crbug-119926.js +3 -1
  623. data/vendor/v8/test/mjsunit/regress/regress-crbug-125148.js +90 -0
  624. data/vendor/v8/test/mjsunit/regress/regress-crbug-134055.js +63 -0
  625. data/vendor/v8/test/mjsunit/regress/regress-crbug-134609.js +59 -0
  626. data/vendor/v8/test/mjsunit/regress/regress-crbug-135008.js +45 -0
  627. data/vendor/v8/test/mjsunit/regress/regress-crbug-135066.js +55 -0
  628. data/vendor/v8/test/mjsunit/regress/regress-crbug-137689.js +47 -0
  629. data/vendor/v8/test/mjsunit/regress/regress-crbug-138887.js +48 -0
  630. data/vendor/v8/test/mjsunit/regress/regress-crbug-140083.js +44 -0
  631. data/vendor/v8/test/mjsunit/regress/regress-crbug-142087.js +38 -0
  632. data/vendor/v8/test/mjsunit/regress/regress-crbug-142218.js +44 -0
  633. data/vendor/v8/test/mjsunit/regress/regress-crbug-145961.js +39 -0
  634. data/vendor/v8/test/mjsunit/regress/regress-crbug-146910.js +33 -0
  635. data/vendor/v8/test/mjsunit/regress/regress-crbug-147475.js +48 -0
  636. data/vendor/v8/test/mjsunit/regress/regress-crbug-148376.js +35 -0
  637. data/vendor/v8/test/mjsunit/regress/regress-crbug-150545.js +53 -0
  638. data/vendor/v8/test/mjsunit/regress/regress-crbug-150729.js +39 -0
  639. data/vendor/v8/test/mjsunit/regress/regress-crbug-157019.js +54 -0
  640. data/vendor/v8/test/mjsunit/regress/regress-crbug-157520.js +38 -0
  641. data/vendor/v8/test/mjsunit/regress/regress-crbug-158185.js +39 -0
  642. data/vendor/v8/test/mjsunit/regress/regress-crbug-160010.js +35 -0
  643. data/vendor/v8/test/mjsunit/regress/regress-crbug-162085.js +71 -0
  644. data/vendor/v8/test/mjsunit/regress/regress-crbug-168545.js +34 -0
  645. data/vendor/v8/test/mjsunit/regress/regress-crbug-170856.js +33 -0
  646. data/vendor/v8/test/mjsunit/regress/regress-crbug-172345.js +34 -0
  647. data/vendor/v8/test/mjsunit/regress/regress-crbug-173974.js +36 -0
  648. data/vendor/v8/test/mjsunit/regress/regress-crbug-18639.js +9 -5
  649. data/vendor/v8/test/mjsunit/regress/regress-debug-code-recompilation.js +2 -1
  650. data/vendor/v8/test/mjsunit/regress/regress-deep-proto.js +45 -0
  651. data/vendor/v8/test/mjsunit/regress/regress-delete-empty-double.js +40 -0
  652. data/vendor/v8/test/mjsunit/regress/regress-iteration-order.js +42 -0
  653. data/vendor/v8/test/mjsunit/regress/regress-json-stringify-gc.js +41 -0
  654. data/vendor/v8/test/mjsunit/regress/regress-latin-1.js +78 -0
  655. data/vendor/v8/test/mjsunit/regress/regress-load-elements.js +49 -0
  656. data/vendor/v8/test/mjsunit/regress/regress-observe-empty-double-array.js +38 -0
  657. data/vendor/v8/test/mjsunit/regress/regress-undefined-store-keyed-fast-element.js +37 -0
  658. data/vendor/v8/test/mjsunit/shift-for-integer-div.js +59 -0
  659. data/vendor/v8/test/mjsunit/stack-traces-gc.js +119 -0
  660. data/vendor/v8/test/mjsunit/stack-traces-overflow.js +122 -0
  661. data/vendor/v8/test/mjsunit/stack-traces.js +39 -1
  662. data/vendor/v8/test/mjsunit/str-to-num.js +7 -2
  663. data/vendor/v8/test/mjsunit/strict-mode.js +36 -11
  664. data/vendor/v8/test/mjsunit/string-charcodeat.js +3 -0
  665. data/vendor/v8/test/mjsunit/string-natives.js +72 -0
  666. data/vendor/v8/test/mjsunit/string-split.js +17 -0
  667. data/vendor/v8/test/mjsunit/testcfg.py +76 -6
  668. data/vendor/v8/test/mjsunit/tools/tickprocessor.js +4 -1
  669. data/vendor/v8/test/mjsunit/try-finally-continue.js +72 -0
  670. data/vendor/v8/test/mjsunit/typed-array-slice.js +61 -0
  671. data/vendor/v8/test/mjsunit/unbox-double-arrays.js +2 -0
  672. data/vendor/v8/test/mjsunit/uri.js +12 -0
  673. data/vendor/v8/test/mjsunit/with-readonly.js +4 -2
  674. data/vendor/v8/test/mozilla/mozilla.status +19 -113
  675. data/vendor/v8/test/mozilla/testcfg.py +122 -3
  676. data/vendor/v8/test/preparser/preparser.status +5 -0
  677. data/vendor/v8/test/preparser/strict-identifiers.pyt +1 -1
  678. data/vendor/v8/test/preparser/testcfg.py +101 -5
  679. data/vendor/v8/test/sputnik/sputnik.status +1 -1
  680. data/vendor/v8/test/sputnik/testcfg.py +5 -0
  681. data/vendor/v8/test/test262/README +2 -2
  682. data/vendor/v8/test/test262/test262.status +13 -36
  683. data/vendor/v8/test/test262/testcfg.py +102 -8
  684. data/vendor/v8/tools/android-build.sh +0 -0
  685. data/vendor/v8/tools/android-ll-prof.sh +69 -0
  686. data/vendor/v8/tools/android-run.py +109 -0
  687. data/vendor/v8/tools/android-sync.sh +105 -0
  688. data/vendor/v8/tools/bash-completion.sh +0 -0
  689. data/vendor/v8/tools/check-static-initializers.sh +0 -0
  690. data/vendor/v8/tools/common-includes.sh +15 -22
  691. data/vendor/v8/tools/disasm.py +4 -4
  692. data/vendor/v8/tools/fuzz-harness.sh +0 -0
  693. data/vendor/v8/tools/gen-postmortem-metadata.py +6 -8
  694. data/vendor/v8/tools/grokdump.py +404 -129
  695. data/vendor/v8/tools/gyp/v8.gyp +105 -43
  696. data/vendor/v8/tools/linux-tick-processor +5 -5
  697. data/vendor/v8/tools/ll_prof.py +75 -15
  698. data/vendor/v8/tools/merge-to-branch.sh +2 -2
  699. data/vendor/v8/tools/plot-timer-events +70 -0
  700. data/vendor/v8/tools/plot-timer-events.js +510 -0
  701. data/vendor/v8/tools/presubmit.py +1 -0
  702. data/vendor/v8/tools/push-to-trunk.sh +14 -4
  703. data/vendor/v8/tools/run-llprof.sh +69 -0
  704. data/vendor/v8/tools/run-tests.py +372 -0
  705. data/vendor/v8/tools/run-valgrind.py +1 -1
  706. data/vendor/v8/tools/status-file-converter.py +39 -0
  707. data/vendor/v8/tools/test-server.py +224 -0
  708. data/vendor/v8/tools/test-wrapper-gypbuild.py +13 -16
  709. data/vendor/v8/tools/test.py +10 -19
  710. data/vendor/v8/tools/testrunner/README +174 -0
  711. data/vendor/v8/tools/testrunner/__init__.py +26 -0
  712. data/vendor/v8/tools/testrunner/local/__init__.py +26 -0
  713. data/vendor/v8/tools/testrunner/local/commands.py +153 -0
  714. data/vendor/v8/tools/testrunner/local/execution.py +182 -0
  715. data/vendor/v8/tools/testrunner/local/old_statusfile.py +460 -0
  716. data/vendor/v8/tools/testrunner/local/progress.py +238 -0
  717. data/vendor/v8/tools/testrunner/local/statusfile.py +145 -0
  718. data/vendor/v8/tools/testrunner/local/testsuite.py +187 -0
  719. data/vendor/v8/tools/testrunner/local/utils.py +108 -0
  720. data/vendor/v8/tools/testrunner/local/verbose.py +99 -0
  721. data/vendor/v8/tools/testrunner/network/__init__.py +26 -0
  722. data/vendor/v8/tools/testrunner/network/distro.py +90 -0
  723. data/vendor/v8/tools/testrunner/network/endpoint.py +124 -0
  724. data/vendor/v8/tools/testrunner/network/network_execution.py +253 -0
  725. data/vendor/v8/tools/testrunner/network/perfdata.py +120 -0
  726. data/vendor/v8/tools/testrunner/objects/__init__.py +26 -0
  727. data/vendor/v8/tools/testrunner/objects/context.py +50 -0
  728. data/vendor/v8/tools/testrunner/objects/output.py +60 -0
  729. data/vendor/v8/tools/testrunner/objects/peer.py +80 -0
  730. data/vendor/v8/tools/testrunner/objects/testcase.py +83 -0
  731. data/vendor/v8/tools/testrunner/objects/workpacket.py +90 -0
  732. data/vendor/v8/tools/testrunner/server/__init__.py +26 -0
  733. data/vendor/v8/tools/testrunner/server/compression.py +111 -0
  734. data/vendor/v8/tools/testrunner/server/constants.py +51 -0
  735. data/vendor/v8/tools/testrunner/server/daemon.py +147 -0
  736. data/vendor/v8/tools/testrunner/server/local_handler.py +119 -0
  737. data/vendor/v8/tools/testrunner/server/main.py +245 -0
  738. data/vendor/v8/tools/testrunner/server/presence_handler.py +120 -0
  739. data/vendor/v8/tools/testrunner/server/signatures.py +63 -0
  740. data/vendor/v8/tools/testrunner/server/status_handler.py +112 -0
  741. data/vendor/v8/tools/testrunner/server/work_handler.py +150 -0
  742. data/vendor/v8/tools/tick-processor.html +168 -0
  743. data/vendor/v8/tools/tickprocessor-driver.js +5 -3
  744. data/vendor/v8/tools/tickprocessor.js +58 -15
  745. metadata +534 -30
  746. data/patches/add-freebsd9-and-freebsd10-to-gyp-GetFlavor.patch +0 -11
  747. data/patches/do-not-imply-vfp3-and-armv7.patch +0 -44
  748. data/patches/fPIC-on-x64.patch +0 -14
  749. data/vendor/v8/src/liveobjectlist-inl.h +0 -126
  750. data/vendor/v8/src/liveobjectlist.cc +0 -2631
  751. data/vendor/v8/src/liveobjectlist.h +0 -319
  752. data/vendor/v8/test/mjsunit/mul-exhaustive.js +0 -4629
  753. data/vendor/v8/test/mjsunit/numops-fuzz.js +0 -4609
  754. data/vendor/v8/test/mjsunit/regress/regress-1969.js +0 -5045
@@ -178,140 +178,9 @@ function JSONSerialize(key, holder, replacer, stack, indent, gap) {
178
178
  }
179
179
 
180
180
 
181
- function BasicSerializeArray(value, stack, builder) {
182
- var len = value.length;
183
- if (len == 0) {
184
- builder.push("[]");
185
- return;
186
- }
187
- if (!%PushIfAbsent(stack, value)) {
188
- throw MakeTypeError('circular_structure', $Array());
189
- }
190
- builder.push("[");
191
- var val = value[0];
192
- if (IS_STRING(val)) {
193
- // First entry is a string. Remaining entries are likely to be strings too.
194
- var array_string = %QuoteJSONStringArray(value);
195
- if (!IS_UNDEFINED(array_string)) {
196
- // array_string also includes bracket characters so we are done.
197
- builder[builder.length - 1] = array_string;
198
- stack.pop();
199
- return;
200
- } else {
201
- builder.push(%QuoteJSONString(val));
202
- for (var i = 1; i < len; i++) {
203
- val = value[i];
204
- if (IS_STRING(val)) {
205
- builder.push(%QuoteJSONStringComma(val));
206
- } else {
207
- builder.push(",");
208
- var before = builder.length;
209
- BasicJSONSerialize(i, val, stack, builder);
210
- if (before == builder.length) builder[before - 1] = ",null";
211
- }
212
- }
213
- }
214
- } else if (IS_NUMBER(val)) {
215
- // First entry is a number. Remaining entries are likely to be numbers too.
216
- builder.push(JSON_NUMBER_TO_STRING(val));
217
- for (var i = 1; i < len; i++) {
218
- builder.push(",");
219
- val = value[i];
220
- if (IS_NUMBER(val)) {
221
- builder.push(JSON_NUMBER_TO_STRING(val));
222
- } else {
223
- var before = builder.length;
224
- BasicJSONSerialize(i, val, stack, builder);
225
- if (before == builder.length) builder[before - 1] = ",null";
226
- }
227
- }
228
- } else {
229
- var before = builder.length;
230
- BasicJSONSerialize(0, val, stack, builder);
231
- if (before == builder.length) builder.push("null");
232
- for (var i = 1; i < len; i++) {
233
- builder.push(",");
234
- before = builder.length;
235
- BasicJSONSerialize(i, value[i], stack, builder);
236
- if (before == builder.length) builder[before - 1] = ",null";
237
- }
238
- }
239
- stack.pop();
240
- builder.push("]");
241
- }
242
-
243
-
244
- function BasicSerializeObject(value, stack, builder) {
245
- if (!%PushIfAbsent(stack, value)) {
246
- throw MakeTypeError('circular_structure', $Array());
247
- }
248
- builder.push("{");
249
- var first = true;
250
- for (var p in value) {
251
- if (%HasLocalProperty(value, p)) {
252
- if (!first) {
253
- builder.push(%QuoteJSONStringComma(p));
254
- } else {
255
- builder.push(%QuoteJSONString(p));
256
- }
257
- builder.push(":");
258
- var before = builder.length;
259
- BasicJSONSerialize(p, value[p], stack, builder);
260
- if (before == builder.length) {
261
- builder.pop();
262
- builder.pop();
263
- } else {
264
- first = false;
265
- }
266
- }
267
- }
268
- stack.pop();
269
- builder.push("}");
270
- }
271
-
272
-
273
- function BasicJSONSerialize(key, value, stack, builder) {
274
- if (IS_SPEC_OBJECT(value)) {
275
- var toJSON = value.toJSON;
276
- if (IS_SPEC_FUNCTION(toJSON)) {
277
- value = %_CallFunction(value, ToString(key), toJSON);
278
- }
279
- }
280
- if (IS_STRING(value)) {
281
- builder.push(value !== "" ? %QuoteJSONString(value) : '""');
282
- } else if (IS_NUMBER(value)) {
283
- builder.push(JSON_NUMBER_TO_STRING(value));
284
- } else if (IS_BOOLEAN(value)) {
285
- builder.push(value ? "true" : "false");
286
- } else if (IS_NULL(value)) {
287
- builder.push("null");
288
- } else if (IS_SPEC_OBJECT(value) && !(typeof value == "function")) {
289
- // Value is a non-callable object.
290
- // Unwrap value if necessary
291
- if (IS_NUMBER_WRAPPER(value)) {
292
- value = ToNumber(value);
293
- builder.push(JSON_NUMBER_TO_STRING(value));
294
- } else if (IS_STRING_WRAPPER(value)) {
295
- builder.push(%QuoteJSONString(ToString(value)));
296
- } else if (IS_BOOLEAN_WRAPPER(value)) {
297
- builder.push(%_ValueOf(value) ? "true" : "false");
298
- } else if (IS_ARRAY(value)) {
299
- BasicSerializeArray(value, stack, builder);
300
- } else {
301
- BasicSerializeObject(value, stack, builder);
302
- }
303
- }
304
- }
305
-
306
-
307
181
  function JSONStringify(value, replacer, space) {
308
182
  if (%_ArgumentsLength() == 1) {
309
- var builder = new InternalArray();
310
- BasicJSONSerialize('', value, new InternalArray(), builder);
311
- if (builder.length == 0) return;
312
- var result = %_FastAsciiArrayJoin(builder, "");
313
- if (!IS_UNDEFINED(result)) return result;
314
- return %StringBuilderConcat(builder, builder.length, "");
183
+ return %BasicJSONStringify(value);
315
184
  }
316
185
  if (IS_OBJECT(space)) {
317
186
  // Unwrap 'space' if it is wrapped
@@ -337,6 +206,7 @@ function JSONStringify(value, replacer, space) {
337
206
  return JSONSerialize('', {'': value}, replacer, new InternalArray(), "", gap);
338
207
  }
339
208
 
209
+
340
210
  function SetUpJSON() {
341
211
  %CheckIsBootstrapping();
342
212
  InstallFunctions($JSON, DONT_ENUM, $Array(
@@ -345,4 +215,12 @@ function SetUpJSON() {
345
215
  ));
346
216
  }
347
217
 
218
+
219
+ function JSONSerializeAdapter(key, object) {
220
+ var holder = {};
221
+ holder[key] = object;
222
+ // No need to pass the actual holder since there is no replacer function.
223
+ return JSONSerialize(key, holder, void 0, new InternalArray(), "", "");
224
+ }
225
+
348
226
  SetUpJSON();
@@ -0,0 +1,106 @@
1
+ // Copyright 2013 the V8 project authors. All rights reserved.
2
+ // Redistribution and use in source and binary forms, with or without
3
+ // modification, are permitted provided that the following conditions are
4
+ // met:
5
+ //
6
+ // * Redistributions of source code must retain the above copyright
7
+ // notice, this list of conditions and the following disclaimer.
8
+ // * Redistributions in binary form must reproduce the above
9
+ // copyright notice, this list of conditions and the following
10
+ // disclaimer in the documentation and/or other materials provided
11
+ // with the distribution.
12
+ // * Neither the name of Google Inc. nor the names of its
13
+ // contributors may be used to endorse or promote products derived
14
+ // from this software without specific prior written permission.
15
+ //
16
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
+ // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
+ // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
+ // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20
+ // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
+ // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
+ // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
+ // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
+ // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
+ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
+ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
+
28
+
29
+ #ifndef V8_JSREGEXP_INL_H_
30
+ #define V8_JSREGEXP_INL_H_
31
+
32
+ #include "allocation.h"
33
+ #include "handles.h"
34
+ #include "heap.h"
35
+ #include "jsregexp.h"
36
+ #include "objects.h"
37
+
38
+ namespace v8 {
39
+ namespace internal {
40
+
41
+
42
+ RegExpImpl::GlobalCache::~GlobalCache() {
43
+ // Deallocate the register array if we allocated it in the constructor
44
+ // (as opposed to using the existing jsregexp_static_offsets_vector).
45
+ if (register_array_size_ > Isolate::kJSRegexpStaticOffsetsVectorSize) {
46
+ DeleteArray(register_array_);
47
+ }
48
+ }
49
+
50
+
51
+ int32_t* RegExpImpl::GlobalCache::FetchNext() {
52
+ current_match_index_++;
53
+ if (current_match_index_ >= num_matches_) {
54
+ // Current batch of results exhausted.
55
+ // Fail if last batch was not even fully filled.
56
+ if (num_matches_ < max_matches_) {
57
+ num_matches_ = 0; // Signal failed match.
58
+ return NULL;
59
+ }
60
+
61
+ int32_t* last_match =
62
+ &register_array_[(current_match_index_ - 1) * registers_per_match_];
63
+ int last_end_index = last_match[1];
64
+
65
+ if (regexp_->TypeTag() == JSRegExp::ATOM) {
66
+ num_matches_ = RegExpImpl::AtomExecRaw(regexp_,
67
+ subject_,
68
+ last_end_index,
69
+ register_array_,
70
+ register_array_size_);
71
+ } else {
72
+ int last_start_index = last_match[0];
73
+ if (last_start_index == last_end_index) last_end_index++;
74
+ if (last_end_index > subject_->length()) {
75
+ num_matches_ = 0; // Signal failed match.
76
+ return NULL;
77
+ }
78
+ num_matches_ = RegExpImpl::IrregexpExecRaw(regexp_,
79
+ subject_,
80
+ last_end_index,
81
+ register_array_,
82
+ register_array_size_);
83
+ }
84
+
85
+ if (num_matches_ <= 0) return NULL;
86
+ current_match_index_ = 0;
87
+ return register_array_;
88
+ } else {
89
+ return &register_array_[current_match_index_ * registers_per_match_];
90
+ }
91
+ }
92
+
93
+
94
+ int32_t* RegExpImpl::GlobalCache::LastSuccessfulMatch() {
95
+ int index = current_match_index_ * registers_per_match_;
96
+ if (num_matches_ == 0) {
97
+ // After a failed match we shift back by one result.
98
+ index -= registers_per_match_;
99
+ }
100
+ return &register_array_[index];
101
+ }
102
+
103
+
104
+ } } // namespace v8::internal
105
+
106
+ #endif // V8_JSREGEXP_INL_H_
@@ -32,6 +32,7 @@
32
32
  #include "execution.h"
33
33
  #include "factory.h"
34
34
  #include "jsregexp.h"
35
+ #include "jsregexp-inl.h"
35
36
  #include "platform.h"
36
37
  #include "string-search.h"
37
38
  #include "runtime.h"
@@ -167,7 +168,9 @@ static bool HasFewDifferentCharacters(Handle<String> pattern) {
167
168
 
168
169
  Handle<Object> RegExpImpl::Compile(Handle<JSRegExp> re,
169
170
  Handle<String> pattern,
170
- Handle<String> flag_str) {
171
+ Handle<String> flag_str,
172
+ Zone* zone) {
173
+ ZoneScope zone_scope(zone, DELETE_ON_EXIT);
171
174
  Isolate* isolate = re->GetIsolate();
172
175
  JSRegExp::Flags flags = RegExpFlagsFromString(flag_str);
173
176
  CompilationCache* compilation_cache = isolate->compilation_cache();
@@ -181,12 +184,11 @@ Handle<Object> RegExpImpl::Compile(Handle<JSRegExp> re,
181
184
  return re;
182
185
  }
183
186
  pattern = FlattenGetString(pattern);
184
- ZoneScope zone_scope(isolate, DELETE_ON_EXIT);
185
187
  PostponeInterruptsScope postpone(isolate);
186
188
  RegExpCompileData parse_result;
187
189
  FlatStringReader reader(isolate, pattern);
188
190
  if (!RegExpParser::ParseRegExp(&reader, flags.is_multiline(),
189
- &parse_result)) {
191
+ &parse_result, zone)) {
190
192
  // Throw an exception if we fail to parse the pattern.
191
193
  ThrowRegExpException(re,
192
194
  pattern,
@@ -277,11 +279,12 @@ static void SetAtomLastCapture(FixedArray* array,
277
279
  }
278
280
 
279
281
 
280
- Handle<Object> RegExpImpl::AtomExec(Handle<JSRegExp> re,
281
- Handle<String> subject,
282
- int index,
283
- Handle<JSArray> last_match_info) {
284
- Isolate* isolate = re->GetIsolate();
282
+ int RegExpImpl::AtomExecRaw(Handle<JSRegExp> regexp,
283
+ Handle<String> subject,
284
+ int index,
285
+ int32_t* output,
286
+ int output_size) {
287
+ Isolate* isolate = regexp->GetIsolate();
285
288
 
286
289
  ASSERT(0 <= index);
287
290
  ASSERT(index <= subject->length());
@@ -289,15 +292,16 @@ Handle<Object> RegExpImpl::AtomExec(Handle<JSRegExp> re,
289
292
  if (!subject->IsFlat()) FlattenString(subject);
290
293
  AssertNoAllocation no_heap_allocation; // ensure vectors stay valid
291
294
 
292
- String* needle = String::cast(re->DataAt(JSRegExp::kAtomPatternIndex));
295
+ String* needle = String::cast(regexp->DataAt(JSRegExp::kAtomPatternIndex));
293
296
  int needle_len = needle->length();
294
297
  ASSERT(needle->IsFlat());
298
+ ASSERT_LT(0, needle_len);
295
299
 
296
- if (needle_len != 0) {
297
- if (index + needle_len > subject->length()) {
298
- return isolate->factory()->null_value();
299
- }
300
+ if (index + needle_len > subject->length()) {
301
+ return RegExpImpl::RE_FAILURE;
302
+ }
300
303
 
304
+ for (int i = 0; i < output_size; i += 2) {
301
305
  String::FlatContent needle_content = needle->GetFlatContent();
302
306
  String::FlatContent subject_content = subject->GetFlatContent();
303
307
  ASSERT(needle_content.IsFlat());
@@ -306,31 +310,52 @@ Handle<Object> RegExpImpl::AtomExec(Handle<JSRegExp> re,
306
310
  index = (needle_content.IsAscii()
307
311
  ? (subject_content.IsAscii()
308
312
  ? SearchString(isolate,
309
- subject_content.ToAsciiVector(),
310
- needle_content.ToAsciiVector(),
313
+ subject_content.ToOneByteVector(),
314
+ needle_content.ToOneByteVector(),
311
315
  index)
312
316
  : SearchString(isolate,
313
317
  subject_content.ToUC16Vector(),
314
- needle_content.ToAsciiVector(),
318
+ needle_content.ToOneByteVector(),
315
319
  index))
316
320
  : (subject_content.IsAscii()
317
321
  ? SearchString(isolate,
318
- subject_content.ToAsciiVector(),
322
+ subject_content.ToOneByteVector(),
319
323
  needle_content.ToUC16Vector(),
320
324
  index)
321
325
  : SearchString(isolate,
322
326
  subject_content.ToUC16Vector(),
323
327
  needle_content.ToUC16Vector(),
324
328
  index)));
325
- if (index == -1) return isolate->factory()->null_value();
329
+ if (index == -1) {
330
+ return i / 2; // Return number of matches.
331
+ } else {
332
+ output[i] = index;
333
+ output[i+1] = index + needle_len;
334
+ index += needle_len;
335
+ }
326
336
  }
327
- ASSERT(last_match_info->HasFastObjectElements());
337
+ return output_size / 2;
338
+ }
328
339
 
329
- {
330
- NoHandleAllocation no_handles;
331
- FixedArray* array = FixedArray::cast(last_match_info->elements());
332
- SetAtomLastCapture(array, *subject, index, index + needle_len);
333
- }
340
+
341
+ Handle<Object> RegExpImpl::AtomExec(Handle<JSRegExp> re,
342
+ Handle<String> subject,
343
+ int index,
344
+ Handle<JSArray> last_match_info) {
345
+ Isolate* isolate = re->GetIsolate();
346
+
347
+ static const int kNumRegisters = 2;
348
+ STATIC_ASSERT(kNumRegisters <= Isolate::kJSRegexpStaticOffsetsVectorSize);
349
+ int32_t* output_registers = isolate->jsregexp_static_offsets_vector();
350
+
351
+ int res = AtomExecRaw(re, subject, index, output_registers, kNumRegisters);
352
+
353
+ if (res == RegExpImpl::RE_FAILURE) return isolate->factory()->null_value();
354
+
355
+ ASSERT_EQ(res, RegExpImpl::RE_SUCCESS);
356
+ NoHandleAllocation no_handles;
357
+ FixedArray* array = FixedArray::cast(last_match_info->elements());
358
+ SetAtomLastCapture(array, *subject, output_registers[0], output_registers[1]);
334
359
  return last_match_info;
335
360
  }
336
361
 
@@ -385,7 +410,7 @@ bool RegExpImpl::CompileIrregexp(Handle<JSRegExp> re,
385
410
  bool is_ascii) {
386
411
  // Compile the RegExp.
387
412
  Isolate* isolate = re->GetIsolate();
388
- ZoneScope zone_scope(isolate, DELETE_ON_EXIT);
413
+ ZoneScope zone_scope(isolate->runtime_zone(), DELETE_ON_EXIT);
389
414
  PostponeInterruptsScope postpone(isolate);
390
415
  // If we had a compilation error the last time this is saved at the
391
416
  // saved code index.
@@ -416,8 +441,10 @@ bool RegExpImpl::CompileIrregexp(Handle<JSRegExp> re,
416
441
  if (!pattern->IsFlat()) FlattenString(pattern);
417
442
  RegExpCompileData compile_data;
418
443
  FlatStringReader reader(isolate, pattern);
444
+ Zone* zone = isolate->runtime_zone();
419
445
  if (!RegExpParser::ParseRegExp(&reader, flags.is_multiline(),
420
- &compile_data)) {
446
+ &compile_data,
447
+ zone)) {
421
448
  // Throw an exception if we fail to parse the pattern.
422
449
  // THIS SHOULD NOT HAPPEN. We already pre-parsed it successfully once.
423
450
  ThrowRegExpException(re,
@@ -433,7 +460,8 @@ bool RegExpImpl::CompileIrregexp(Handle<JSRegExp> re,
433
460
  flags.is_multiline(),
434
461
  pattern,
435
462
  sample_subject,
436
- is_ascii);
463
+ is_ascii,
464
+ zone);
437
465
  if (result.error_message != NULL) {
438
466
  // Unable to compile regexp.
439
467
  Handle<String> error_message =
@@ -502,12 +530,16 @@ int RegExpImpl::IrregexpPrepare(Handle<JSRegExp> regexp,
502
530
  if (!subject->IsFlat()) FlattenString(subject);
503
531
 
504
532
  // Check the asciiness of the underlying storage.
505
- bool is_ascii = subject->IsAsciiRepresentationUnderneath();
533
+ bool is_ascii = subject->IsOneByteRepresentationUnderneath();
506
534
  if (!EnsureCompiledIrregexp(regexp, subject, is_ascii)) return -1;
507
535
 
508
536
  #ifdef V8_INTERPRETED_REGEXP
509
537
  // Byte-code regexp needs space allocated for all its registers.
510
- return IrregexpNumberOfRegisters(FixedArray::cast(regexp->data()));
538
+ // The result captures are copied to the start of the registers array
539
+ // if the match succeeds. This way those registers are not clobbered
540
+ // when we set the last match info from last successful match.
541
+ return IrregexpNumberOfRegisters(FixedArray::cast(regexp->data())) +
542
+ (IrregexpNumberOfCaptures(FixedArray::cast(regexp->data())) + 1) * 2;
511
543
  #else // V8_INTERPRETED_REGEXP
512
544
  // Native regexp only needs room to output captures. Registers are handled
513
545
  // internally.
@@ -516,27 +548,11 @@ int RegExpImpl::IrregexpPrepare(Handle<JSRegExp> regexp,
516
548
  }
517
549
 
518
550
 
519
- int RegExpImpl::GlobalOffsetsVectorSize(Handle<JSRegExp> regexp,
520
- int registers_per_match,
521
- int* max_matches) {
522
- #ifdef V8_INTERPRETED_REGEXP
523
- // Global loop in interpreted regexp is not implemented. Therefore we choose
524
- // the size of the offsets vector so that it can only store one match.
525
- *max_matches = 1;
526
- return registers_per_match;
527
- #else // V8_INTERPRETED_REGEXP
528
- int size = Max(registers_per_match, OffsetsVector::kStaticOffsetsVectorSize);
529
- *max_matches = size / registers_per_match;
530
- return size;
531
- #endif // V8_INTERPRETED_REGEXP
532
- }
533
-
534
-
535
- int RegExpImpl::IrregexpExecRaw(
536
- Handle<JSRegExp> regexp,
537
- Handle<String> subject,
538
- int index,
539
- Vector<int> output) {
551
+ int RegExpImpl::IrregexpExecRaw(Handle<JSRegExp> regexp,
552
+ Handle<String> subject,
553
+ int index,
554
+ int32_t* output,
555
+ int output_size) {
540
556
  Isolate* isolate = regexp->GetIsolate();
541
557
 
542
558
  Handle<FixedArray> irregexp(FixedArray::cast(regexp->data()), isolate);
@@ -545,18 +561,22 @@ int RegExpImpl::IrregexpExecRaw(
545
561
  ASSERT(index <= subject->length());
546
562
  ASSERT(subject->IsFlat());
547
563
 
548
- bool is_ascii = subject->IsAsciiRepresentationUnderneath();
564
+ bool is_ascii = subject->IsOneByteRepresentationUnderneath();
549
565
 
550
566
  #ifndef V8_INTERPRETED_REGEXP
551
- ASSERT(output.length() >= (IrregexpNumberOfCaptures(*irregexp) + 1) * 2);
567
+ ASSERT(output_size >= (IrregexpNumberOfCaptures(*irregexp) + 1) * 2);
552
568
  do {
553
569
  EnsureCompiledIrregexp(regexp, subject, is_ascii);
554
570
  Handle<Code> code(IrregexpNativeCode(*irregexp, is_ascii), isolate);
571
+ // The stack is used to allocate registers for the compiled regexp code.
572
+ // This means that in case of failure, the output registers array is left
573
+ // untouched and contains the capture results from the previous successful
574
+ // match. We can use that to set the last match info lazily.
555
575
  NativeRegExpMacroAssembler::Result res =
556
576
  NativeRegExpMacroAssembler::Match(code,
557
577
  subject,
558
- output.start(),
559
- output.length(),
578
+ output,
579
+ output_size,
560
580
  index,
561
581
  isolate);
562
582
  if (res != NativeRegExpMacroAssembler::RETRY) {
@@ -577,28 +597,35 @@ int RegExpImpl::IrregexpExecRaw(
577
597
  // being internal and external, and even between being ASCII and UC16,
578
598
  // but the characters are always the same).
579
599
  IrregexpPrepare(regexp, subject);
580
- is_ascii = subject->IsAsciiRepresentationUnderneath();
600
+ is_ascii = subject->IsOneByteRepresentationUnderneath();
581
601
  } while (true);
582
602
  UNREACHABLE();
583
603
  return RE_EXCEPTION;
584
604
  #else // V8_INTERPRETED_REGEXP
585
605
 
586
- ASSERT(output.length() >= IrregexpNumberOfRegisters(*irregexp));
606
+ ASSERT(output_size >= IrregexpNumberOfRegisters(*irregexp));
587
607
  // We must have done EnsureCompiledIrregexp, so we can get the number of
588
608
  // registers.
589
- int* register_vector = output.start();
590
609
  int number_of_capture_registers =
591
610
  (IrregexpNumberOfCaptures(*irregexp) + 1) * 2;
611
+ int32_t* raw_output = &output[number_of_capture_registers];
612
+ // We do not touch the actual capture result registers until we know there
613
+ // has been a match so that we can use those capture results to set the
614
+ // last match info.
592
615
  for (int i = number_of_capture_registers - 1; i >= 0; i--) {
593
- register_vector[i] = -1;
616
+ raw_output[i] = -1;
594
617
  }
595
618
  Handle<ByteArray> byte_codes(IrregexpByteCode(*irregexp, is_ascii), isolate);
596
619
 
597
620
  IrregexpResult result = IrregexpInterpreter::Match(isolate,
598
621
  byte_codes,
599
622
  subject,
600
- register_vector,
623
+ raw_output,
601
624
  index);
625
+ if (result == RE_SUCCESS) {
626
+ // Copy capture results to the start of the registers array.
627
+ memcpy(output, raw_output, number_of_capture_registers * sizeof(int32_t));
628
+ }
602
629
  if (result == RE_EXCEPTION) {
603
630
  ASSERT(!isolate->has_pending_exception());
604
631
  isolate->StackOverflow();
@@ -608,50 +635,44 @@ int RegExpImpl::IrregexpExecRaw(
608
635
  }
609
636
 
610
637
 
611
- Handle<Object> RegExpImpl::IrregexpExec(Handle<JSRegExp> jsregexp,
638
+ Handle<Object> RegExpImpl::IrregexpExec(Handle<JSRegExp> regexp,
612
639
  Handle<String> subject,
613
640
  int previous_index,
614
641
  Handle<JSArray> last_match_info) {
615
- Isolate* isolate = jsregexp->GetIsolate();
616
- ASSERT_EQ(jsregexp->TypeTag(), JSRegExp::IRREGEXP);
642
+ Isolate* isolate = regexp->GetIsolate();
643
+ ASSERT_EQ(regexp->TypeTag(), JSRegExp::IRREGEXP);
617
644
 
618
645
  // Prepare space for the return values.
619
- #ifdef V8_INTERPRETED_REGEXP
620
- #ifdef DEBUG
646
+ #if defined(V8_INTERPRETED_REGEXP) && defined(DEBUG)
621
647
  if (FLAG_trace_regexp_bytecodes) {
622
- String* pattern = jsregexp->Pattern();
648
+ String* pattern = regexp->Pattern();
623
649
  PrintF("\n\nRegexp match: /%s/\n\n", *(pattern->ToCString()));
624
650
  PrintF("\n\nSubject string: '%s'\n\n", *(subject->ToCString()));
625
651
  }
626
652
  #endif
627
- #endif
628
- int required_registers = RegExpImpl::IrregexpPrepare(jsregexp, subject);
653
+ int required_registers = RegExpImpl::IrregexpPrepare(regexp, subject);
629
654
  if (required_registers < 0) {
630
655
  // Compiling failed with an exception.
631
656
  ASSERT(isolate->has_pending_exception());
632
657
  return Handle<Object>::null();
633
658
  }
634
659
 
635
- OffsetsVector registers(required_registers, isolate);
660
+ int32_t* output_registers = NULL;
661
+ if (required_registers > Isolate::kJSRegexpStaticOffsetsVectorSize) {
662
+ output_registers = NewArray<int32_t>(required_registers);
663
+ }
664
+ SmartArrayPointer<int32_t> auto_release(output_registers);
665
+ if (output_registers == NULL) {
666
+ output_registers = isolate->jsregexp_static_offsets_vector();
667
+ }
636
668
 
637
669
  int res = RegExpImpl::IrregexpExecRaw(
638
- jsregexp, subject, previous_index, Vector<int>(registers.vector(),
639
- registers.length()));
670
+ regexp, subject, previous_index, output_registers, required_registers);
640
671
  if (res == RE_SUCCESS) {
641
- int capture_register_count =
642
- (IrregexpNumberOfCaptures(FixedArray::cast(jsregexp->data())) + 1) * 2;
643
- last_match_info->EnsureSize(capture_register_count + kLastMatchOverhead);
644
- AssertNoAllocation no_gc;
645
- int* register_vector = registers.vector();
646
- FixedArray* array = FixedArray::cast(last_match_info->elements());
647
- for (int i = 0; i < capture_register_count; i += 2) {
648
- SetCapture(array, i, register_vector[i]);
649
- SetCapture(array, i + 1, register_vector[i + 1]);
650
- }
651
- SetLastCaptureCount(array, capture_register_count);
652
- SetLastSubject(array, *subject);
653
- SetLastInput(array, *subject);
654
- return last_match_info;
672
+ int capture_count =
673
+ IrregexpNumberOfCaptures(FixedArray::cast(regexp->data()));
674
+ return SetLastMatchInfo(
675
+ last_match_info, subject, capture_count, output_registers);
655
676
  }
656
677
  if (res == RE_EXCEPTION) {
657
678
  ASSERT(isolate->has_pending_exception());
@@ -662,6 +683,84 @@ Handle<Object> RegExpImpl::IrregexpExec(Handle<JSRegExp> jsregexp,
662
683
  }
663
684
 
664
685
 
686
+ Handle<JSArray> RegExpImpl::SetLastMatchInfo(Handle<JSArray> last_match_info,
687
+ Handle<String> subject,
688
+ int capture_count,
689
+ int32_t* match) {
690
+ int capture_register_count = (capture_count + 1) * 2;
691
+ last_match_info->EnsureSize(capture_register_count + kLastMatchOverhead);
692
+ AssertNoAllocation no_gc;
693
+ FixedArray* array = FixedArray::cast(last_match_info->elements());
694
+ if (match != NULL) {
695
+ for (int i = 0; i < capture_register_count; i += 2) {
696
+ SetCapture(array, i, match[i]);
697
+ SetCapture(array, i + 1, match[i + 1]);
698
+ }
699
+ }
700
+ SetLastCaptureCount(array, capture_register_count);
701
+ SetLastSubject(array, *subject);
702
+ SetLastInput(array, *subject);
703
+ return last_match_info;
704
+ }
705
+
706
+
707
+ RegExpImpl::GlobalCache::GlobalCache(Handle<JSRegExp> regexp,
708
+ Handle<String> subject,
709
+ bool is_global,
710
+ Isolate* isolate)
711
+ : register_array_(NULL),
712
+ register_array_size_(0),
713
+ regexp_(regexp),
714
+ subject_(subject) {
715
+ #ifdef V8_INTERPRETED_REGEXP
716
+ bool interpreted = true;
717
+ #else
718
+ bool interpreted = false;
719
+ #endif // V8_INTERPRETED_REGEXP
720
+
721
+ if (regexp_->TypeTag() == JSRegExp::ATOM) {
722
+ static const int kAtomRegistersPerMatch = 2;
723
+ registers_per_match_ = kAtomRegistersPerMatch;
724
+ // There is no distinction between interpreted and native for atom regexps.
725
+ interpreted = false;
726
+ } else {
727
+ registers_per_match_ = RegExpImpl::IrregexpPrepare(regexp_, subject_);
728
+ if (registers_per_match_ < 0) {
729
+ num_matches_ = -1; // Signal exception.
730
+ return;
731
+ }
732
+ }
733
+
734
+ if (is_global && !interpreted) {
735
+ register_array_size_ =
736
+ Max(registers_per_match_, Isolate::kJSRegexpStaticOffsetsVectorSize);
737
+ max_matches_ = register_array_size_ / registers_per_match_;
738
+ } else {
739
+ // Global loop in interpreted regexp is not implemented. We choose
740
+ // the size of the offsets vector so that it can only store one match.
741
+ register_array_size_ = registers_per_match_;
742
+ max_matches_ = 1;
743
+ }
744
+
745
+ if (register_array_size_ > Isolate::kJSRegexpStaticOffsetsVectorSize) {
746
+ register_array_ = NewArray<int32_t>(register_array_size_);
747
+ } else {
748
+ register_array_ = isolate->jsregexp_static_offsets_vector();
749
+ }
750
+
751
+ // Set state so that fetching the results the first time triggers a call
752
+ // to the compiled regexp.
753
+ current_match_index_ = max_matches_ - 1;
754
+ num_matches_ = max_matches_;
755
+ ASSERT(registers_per_match_ >= 2); // Each match has at least one capture.
756
+ ASSERT_GE(register_array_size_, registers_per_match_);
757
+ int32_t* last_match =
758
+ &register_array_[current_match_index_ * registers_per_match_];
759
+ last_match[0] = -1;
760
+ last_match[1] = 0;
761
+ }
762
+
763
+
665
764
  // -------------------------------------------------------------------
666
765
  // Implementation of the Irregexp regular expression engine.
667
766
  //
@@ -812,24 +911,24 @@ Handle<Object> RegExpImpl::IrregexpExec(Handle<JSRegExp> jsregexp,
812
911
  // the event that code generation is requested for an identical trace.
813
912
 
814
913
 
815
- void RegExpTree::AppendToText(RegExpText* text) {
914
+ void RegExpTree::AppendToText(RegExpText* text, Zone* zone) {
816
915
  UNREACHABLE();
817
916
  }
818
917
 
819
918
 
820
- void RegExpAtom::AppendToText(RegExpText* text) {
821
- text->AddElement(TextElement::Atom(this));
919
+ void RegExpAtom::AppendToText(RegExpText* text, Zone* zone) {
920
+ text->AddElement(TextElement::Atom(this), zone);
822
921
  }
823
922
 
824
923
 
825
- void RegExpCharacterClass::AppendToText(RegExpText* text) {
826
- text->AddElement(TextElement::CharClass(this));
924
+ void RegExpCharacterClass::AppendToText(RegExpText* text, Zone* zone) {
925
+ text->AddElement(TextElement::CharClass(this), zone);
827
926
  }
828
927
 
829
928
 
830
- void RegExpText::AppendToText(RegExpText* text) {
929
+ void RegExpText::AppendToText(RegExpText* text, Zone* zone) {
831
930
  for (int i = 0; i < elements()->length(); i++)
832
- text->AddElement(elements()->at(i));
931
+ text->AddElement(elements()->at(i), zone);
833
932
  }
834
933
 
835
934
 
@@ -860,8 +959,8 @@ int TextElement::length() {
860
959
 
861
960
  DispatchTable* ChoiceNode::GetTable(bool ignore_case) {
862
961
  if (table_ == NULL) {
863
- table_ = new DispatchTable();
864
- DispatchTableConstructor cons(table_, ignore_case);
962
+ table_ = new(zone()) DispatchTable(zone());
963
+ DispatchTableConstructor cons(table_, ignore_case, zone());
865
964
  cons.BuildTable(this);
866
965
  }
867
966
  return table_;
@@ -917,7 +1016,8 @@ class FrequencyCollator {
917
1016
 
918
1017
  class RegExpCompiler {
919
1018
  public:
920
- RegExpCompiler(int capture_count, bool ignore_case, bool is_ascii);
1019
+ RegExpCompiler(int capture_count, bool ignore_case, bool is_ascii,
1020
+ Zone* zone);
921
1021
 
922
1022
  int AllocateRegister() {
923
1023
  if (next_register_ >= RegExpMacroAssembler::kMaxRegister) {
@@ -957,6 +1057,8 @@ class RegExpCompiler {
957
1057
  current_expansion_factor_ = value;
958
1058
  }
959
1059
 
1060
+ Zone* zone() const { return zone_; }
1061
+
960
1062
  static const int kNoRegister = -1;
961
1063
 
962
1064
  private:
@@ -970,6 +1072,7 @@ class RegExpCompiler {
970
1072
  bool reg_exp_too_big_;
971
1073
  int current_expansion_factor_;
972
1074
  FrequencyCollator frequency_collator_;
1075
+ Zone* zone_;
973
1076
  };
974
1077
 
975
1078
 
@@ -991,7 +1094,8 @@ static RegExpEngine::CompilationResult IrregexpRegExpTooBig() {
991
1094
 
992
1095
  // Attempts to compile the regexp using an Irregexp code generator. Returns
993
1096
  // a fixed array or a null handle depending on whether it succeeded.
994
- RegExpCompiler::RegExpCompiler(int capture_count, bool ignore_case, bool ascii)
1097
+ RegExpCompiler::RegExpCompiler(int capture_count, bool ignore_case, bool ascii,
1098
+ Zone* zone)
995
1099
  : next_register_(2 * (capture_count + 1)),
996
1100
  work_list_(NULL),
997
1101
  recursion_depth_(0),
@@ -999,8 +1103,9 @@ RegExpCompiler::RegExpCompiler(int capture_count, bool ignore_case, bool ascii)
999
1103
  ascii_(ascii),
1000
1104
  reg_exp_too_big_(false),
1001
1105
  current_expansion_factor_(1),
1002
- frequency_collator_() {
1003
- accept_ = new EndNode(EndNode::ACCEPT);
1106
+ frequency_collator_(),
1107
+ zone_(zone) {
1108
+ accept_ = new(zone) EndNode(EndNode::ACCEPT, zone);
1004
1109
  ASSERT(next_register_ - 1 <= RegExpMacroAssembler::kMaxRegister);
1005
1110
  }
1006
1111
 
@@ -1096,7 +1201,8 @@ bool Trace::GetStoredPosition(int reg, int* cp_offset) {
1096
1201
  }
1097
1202
 
1098
1203
 
1099
- int Trace::FindAffectedRegisters(OutSet* affected_registers) {
1204
+ int Trace::FindAffectedRegisters(OutSet* affected_registers,
1205
+ Zone* zone) {
1100
1206
  int max_register = RegExpCompiler::kNoRegister;
1101
1207
  for (DeferredAction* action = actions_;
1102
1208
  action != NULL;
@@ -1104,10 +1210,10 @@ int Trace::FindAffectedRegisters(OutSet* affected_registers) {
1104
1210
  if (action->type() == ActionNode::CLEAR_CAPTURES) {
1105
1211
  Interval range = static_cast<DeferredClearCaptures*>(action)->range();
1106
1212
  for (int i = range.from(); i <= range.to(); i++)
1107
- affected_registers->Set(i);
1213
+ affected_registers->Set(i, zone);
1108
1214
  if (range.to() > max_register) max_register = range.to();
1109
1215
  } else {
1110
- affected_registers->Set(action->reg());
1216
+ affected_registers->Set(action->reg(), zone);
1111
1217
  if (action->reg() > max_register) max_register = action->reg();
1112
1218
  }
1113
1219
  }
@@ -1136,7 +1242,8 @@ void Trace::PerformDeferredActions(RegExpMacroAssembler* assembler,
1136
1242
  int max_register,
1137
1243
  OutSet& affected_registers,
1138
1244
  OutSet* registers_to_pop,
1139
- OutSet* registers_to_clear) {
1245
+ OutSet* registers_to_clear,
1246
+ Zone* zone) {
1140
1247
  // The "+1" is to avoid a push_limit of zero if stack_limit_slack() is 1.
1141
1248
  const int push_limit = (assembler->stack_limit_slack() + 1) / 2;
1142
1249
 
@@ -1242,9 +1349,9 @@ void Trace::PerformDeferredActions(RegExpMacroAssembler* assembler,
1242
1349
  }
1243
1350
 
1244
1351
  assembler->PushRegister(reg, stack_check);
1245
- registers_to_pop->Set(reg);
1352
+ registers_to_pop->Set(reg, zone);
1246
1353
  } else if (undo_action == CLEAR) {
1247
- registers_to_clear->Set(reg);
1354
+ registers_to_clear->Set(reg, zone);
1248
1355
  }
1249
1356
  // Perform the chronologically last action (or accumulated increment)
1250
1357
  // for the register.
@@ -1290,14 +1397,16 @@ void Trace::Flush(RegExpCompiler* compiler, RegExpNode* successor) {
1290
1397
  assembler->PushCurrentPosition();
1291
1398
  }
1292
1399
 
1293
- int max_register = FindAffectedRegisters(&affected_registers);
1400
+ int max_register = FindAffectedRegisters(&affected_registers,
1401
+ compiler->zone());
1294
1402
  OutSet registers_to_pop;
1295
1403
  OutSet registers_to_clear;
1296
1404
  PerformDeferredActions(assembler,
1297
1405
  max_register,
1298
1406
  affected_registers,
1299
1407
  &registers_to_pop,
1300
- &registers_to_clear);
1408
+ &registers_to_clear,
1409
+ compiler->zone());
1301
1410
  if (cp_offset_ != 0) {
1302
1411
  assembler->AdvanceCurrentPosition(cp_offset_);
1303
1412
  }
@@ -1374,17 +1483,18 @@ void EndNode::Emit(RegExpCompiler* compiler, Trace* trace) {
1374
1483
  }
1375
1484
 
1376
1485
 
1377
- void GuardedAlternative::AddGuard(Guard* guard) {
1486
+ void GuardedAlternative::AddGuard(Guard* guard, Zone* zone) {
1378
1487
  if (guards_ == NULL)
1379
- guards_ = new ZoneList<Guard*>(1);
1380
- guards_->Add(guard);
1488
+ guards_ = new(zone) ZoneList<Guard*>(1, zone);
1489
+ guards_->Add(guard, zone);
1381
1490
  }
1382
1491
 
1383
1492
 
1384
1493
  ActionNode* ActionNode::SetRegister(int reg,
1385
1494
  int val,
1386
1495
  RegExpNode* on_success) {
1387
- ActionNode* result = new ActionNode(SET_REGISTER, on_success);
1496
+ ActionNode* result =
1497
+ new(on_success->zone()) ActionNode(SET_REGISTER, on_success);
1388
1498
  result->data_.u_store_register.reg = reg;
1389
1499
  result->data_.u_store_register.value = val;
1390
1500
  return result;
@@ -1392,7 +1502,8 @@ ActionNode* ActionNode::SetRegister(int reg,
1392
1502
 
1393
1503
 
1394
1504
  ActionNode* ActionNode::IncrementRegister(int reg, RegExpNode* on_success) {
1395
- ActionNode* result = new ActionNode(INCREMENT_REGISTER, on_success);
1505
+ ActionNode* result =
1506
+ new(on_success->zone()) ActionNode(INCREMENT_REGISTER, on_success);
1396
1507
  result->data_.u_increment_register.reg = reg;
1397
1508
  return result;
1398
1509
  }
@@ -1401,7 +1512,8 @@ ActionNode* ActionNode::IncrementRegister(int reg, RegExpNode* on_success) {
1401
1512
  ActionNode* ActionNode::StorePosition(int reg,
1402
1513
  bool is_capture,
1403
1514
  RegExpNode* on_success) {
1404
- ActionNode* result = new ActionNode(STORE_POSITION, on_success);
1515
+ ActionNode* result =
1516
+ new(on_success->zone()) ActionNode(STORE_POSITION, on_success);
1405
1517
  result->data_.u_position_register.reg = reg;
1406
1518
  result->data_.u_position_register.is_capture = is_capture;
1407
1519
  return result;
@@ -1410,7 +1522,8 @@ ActionNode* ActionNode::StorePosition(int reg,
1410
1522
 
1411
1523
  ActionNode* ActionNode::ClearCaptures(Interval range,
1412
1524
  RegExpNode* on_success) {
1413
- ActionNode* result = new ActionNode(CLEAR_CAPTURES, on_success);
1525
+ ActionNode* result =
1526
+ new(on_success->zone()) ActionNode(CLEAR_CAPTURES, on_success);
1414
1527
  result->data_.u_clear_captures.range_from = range.from();
1415
1528
  result->data_.u_clear_captures.range_to = range.to();
1416
1529
  return result;
@@ -1420,7 +1533,8 @@ ActionNode* ActionNode::ClearCaptures(Interval range,
1420
1533
  ActionNode* ActionNode::BeginSubmatch(int stack_reg,
1421
1534
  int position_reg,
1422
1535
  RegExpNode* on_success) {
1423
- ActionNode* result = new ActionNode(BEGIN_SUBMATCH, on_success);
1536
+ ActionNode* result =
1537
+ new(on_success->zone()) ActionNode(BEGIN_SUBMATCH, on_success);
1424
1538
  result->data_.u_submatch.stack_pointer_register = stack_reg;
1425
1539
  result->data_.u_submatch.current_position_register = position_reg;
1426
1540
  return result;
@@ -1432,7 +1546,8 @@ ActionNode* ActionNode::PositiveSubmatchSuccess(int stack_reg,
1432
1546
  int clear_register_count,
1433
1547
  int clear_register_from,
1434
1548
  RegExpNode* on_success) {
1435
- ActionNode* result = new ActionNode(POSITIVE_SUBMATCH_SUCCESS, on_success);
1549
+ ActionNode* result =
1550
+ new(on_success->zone()) ActionNode(POSITIVE_SUBMATCH_SUCCESS, on_success);
1436
1551
  result->data_.u_submatch.stack_pointer_register = stack_reg;
1437
1552
  result->data_.u_submatch.current_position_register = position_reg;
1438
1553
  result->data_.u_submatch.clear_register_count = clear_register_count;
@@ -1445,7 +1560,8 @@ ActionNode* ActionNode::EmptyMatchCheck(int start_register,
1445
1560
  int repetition_register,
1446
1561
  int repetition_limit,
1447
1562
  RegExpNode* on_success) {
1448
- ActionNode* result = new ActionNode(EMPTY_MATCH_CHECK, on_success);
1563
+ ActionNode* result =
1564
+ new(on_success->zone()) ActionNode(EMPTY_MATCH_CHECK, on_success);
1449
1565
  result->data_.u_empty_match_check.start_register = start_register;
1450
1566
  result->data_.u_empty_match_check.repetition_register = repetition_register;
1451
1567
  result->data_.u_empty_match_check.repetition_limit = repetition_limit;
@@ -1504,7 +1620,7 @@ static int GetCaseIndependentLetters(Isolate* isolate,
1504
1620
  letters[0] = character;
1505
1621
  length = 1;
1506
1622
  }
1507
- if (!ascii_subject || character <= String::kMaxAsciiCharCode) {
1623
+ if (!ascii_subject || character <= String::kMaxOneByteCharCode) {
1508
1624
  return length;
1509
1625
  }
1510
1626
  // The standard requires that non-ASCII characters cannot have ASCII
@@ -1555,7 +1671,7 @@ static inline bool EmitAtomNonLetter(Isolate* isolate,
1555
1671
  bool checked = false;
1556
1672
  // We handle the length > 1 case in a later pass.
1557
1673
  if (length == 1) {
1558
- if (ascii && c > String::kMaxAsciiCharCodeU) {
1674
+ if (ascii && c > String::kMaxOneByteCharCodeU) {
1559
1675
  // Can't match - see above.
1560
1676
  return false; // Bounds not checked.
1561
1677
  }
@@ -1576,7 +1692,7 @@ static bool ShortCutEmitCharacterPair(RegExpMacroAssembler* macro_assembler,
1576
1692
  Label* on_failure) {
1577
1693
  uc16 char_mask;
1578
1694
  if (ascii) {
1579
- char_mask = String::kMaxAsciiCharCode;
1695
+ char_mask = String::kMaxOneByteCharCode;
1580
1696
  } else {
1581
1697
  char_mask = String::kMaxUtf16CodeUnit;
1582
1698
  }
@@ -1830,7 +1946,7 @@ static void SplitSearchSpace(ZoneList<int>* ranges,
1830
1946
  // range with a single not-taken branch, speeding up this important
1831
1947
  // character range (even non-ASCII charset-based text has spaces and
1832
1948
  // punctuation).
1833
- if (*border - 1 > String::kMaxAsciiCharCode && // ASCII case.
1949
+ if (*border - 1 > String::kMaxOneByteCharCode && // ASCII case.
1834
1950
  end_index - start_index > (*new_start_index - start_index) * 2 &&
1835
1951
  last - first > kSize * 2 &&
1836
1952
  binary_chop_index > *new_start_index &&
@@ -2025,15 +2141,16 @@ static void EmitCharClass(RegExpMacroAssembler* macro_assembler,
2025
2141
  Label* on_failure,
2026
2142
  int cp_offset,
2027
2143
  bool check_offset,
2028
- bool preloaded) {
2029
- ZoneList<CharacterRange>* ranges = cc->ranges();
2144
+ bool preloaded,
2145
+ Zone* zone) {
2146
+ ZoneList<CharacterRange>* ranges = cc->ranges(zone);
2030
2147
  if (!CharacterRange::IsCanonical(ranges)) {
2031
2148
  CharacterRange::Canonicalize(ranges);
2032
2149
  }
2033
2150
 
2034
2151
  int max_char;
2035
2152
  if (ascii) {
2036
- max_char = String::kMaxAsciiCharCode;
2153
+ max_char = String::kMaxOneByteCharCode;
2037
2154
  } else {
2038
2155
  max_char = String::kMaxUtf16CodeUnit;
2039
2156
  }
@@ -2085,7 +2202,7 @@ static void EmitCharClass(RegExpMacroAssembler* macro_assembler,
2085
2202
  macro_assembler->LoadCurrentCharacter(cp_offset, on_failure, check_offset);
2086
2203
  }
2087
2204
 
2088
- if (cc->is_standard() &&
2205
+ if (cc->is_standard(zone) &&
2089
2206
  macro_assembler->CheckSpecialCharacterClass(cc->standard_type(),
2090
2207
  on_failure)) {
2091
2208
  return;
@@ -2098,7 +2215,8 @@ static void EmitCharClass(RegExpMacroAssembler* macro_assembler,
2098
2215
  // entry at zero which goes to the failure label, but if there
2099
2216
  // was already one there we fall through for success on that entry.
2100
2217
  // Subsequent entries have alternating meaning (success/failure).
2101
- ZoneList<int>* range_boundaries = new ZoneList<int>(last_valid_range);
2218
+ ZoneList<int>* range_boundaries =
2219
+ new(zone) ZoneList<int>(last_valid_range, zone);
2102
2220
 
2103
2221
  bool zeroth_entry_is_failure = !cc->is_negated();
2104
2222
 
@@ -2108,9 +2226,9 @@ static void EmitCharClass(RegExpMacroAssembler* macro_assembler,
2108
2226
  ASSERT_EQ(i, 0);
2109
2227
  zeroth_entry_is_failure = !zeroth_entry_is_failure;
2110
2228
  } else {
2111
- range_boundaries->Add(range.from());
2229
+ range_boundaries->Add(range.from(), zone);
2112
2230
  }
2113
- range_boundaries->Add(range.to() + 1);
2231
+ range_boundaries->Add(range.to() + 1, zone);
2114
2232
  }
2115
2233
  int end_index = range_boundaries->length() - 1;
2116
2234
  if (range_boundaries->at(end_index) > max_char) {
@@ -2192,12 +2310,14 @@ int ActionNode::EatsAtLeast(int still_to_find,
2192
2310
 
2193
2311
  void ActionNode::FillInBMInfo(int offset,
2194
2312
  int recursion_depth,
2313
+ int budget,
2195
2314
  BoyerMooreLookahead* bm,
2196
2315
  bool not_at_start) {
2197
2316
  if (type_ == BEGIN_SUBMATCH) {
2198
2317
  bm->SetRest(offset);
2199
2318
  } else if (type_ != POSITIVE_SUBMATCH_SUCCESS) {
2200
- on_success()->FillInBMInfo(offset, recursion_depth + 1, bm, not_at_start);
2319
+ on_success()->FillInBMInfo(
2320
+ offset, recursion_depth + 1, budget - 1, bm, not_at_start);
2201
2321
  }
2202
2322
  SaveBMInfo(bm, not_at_start, offset);
2203
2323
  }
@@ -2221,11 +2341,13 @@ int AssertionNode::EatsAtLeast(int still_to_find,
2221
2341
 
2222
2342
  void AssertionNode::FillInBMInfo(int offset,
2223
2343
  int recursion_depth,
2344
+ int budget,
2224
2345
  BoyerMooreLookahead* bm,
2225
2346
  bool not_at_start) {
2226
2347
  // Match the behaviour of EatsAtLeast on this node.
2227
2348
  if (type() == AT_START && not_at_start) return;
2228
- on_success()->FillInBMInfo(offset, recursion_depth + 1, bm, not_at_start);
2349
+ on_success()->FillInBMInfo(
2350
+ offset, recursion_depth + 1, budget - 1, bm, not_at_start);
2229
2351
  SaveBMInfo(bm, not_at_start, offset);
2230
2352
  }
2231
2353
 
@@ -2330,7 +2452,7 @@ bool QuickCheckDetails::Rationalize(bool asc) {
2330
2452
  bool found_useful_op = false;
2331
2453
  uint32_t char_mask;
2332
2454
  if (asc) {
2333
- char_mask = String::kMaxAsciiCharCode;
2455
+ char_mask = String::kMaxOneByteCharCode;
2334
2456
  } else {
2335
2457
  char_mask = String::kMaxUtf16CodeUnit;
2336
2458
  }
@@ -2339,7 +2461,7 @@ bool QuickCheckDetails::Rationalize(bool asc) {
2339
2461
  int char_shift = 0;
2340
2462
  for (int i = 0; i < characters_; i++) {
2341
2463
  Position* pos = &positions_[i];
2342
- if ((pos->mask & String::kMaxAsciiCharCode) != 0) {
2464
+ if ((pos->mask & String::kMaxOneByteCharCode) != 0) {
2343
2465
  found_useful_op = true;
2344
2466
  }
2345
2467
  mask_ |= (pos->mask & char_mask) << char_shift;
@@ -2382,7 +2504,7 @@ bool RegExpNode::EmitQuickCheck(RegExpCompiler* compiler,
2382
2504
  // load so the value is already masked down.
2383
2505
  uint32_t char_mask;
2384
2506
  if (compiler->ascii()) {
2385
- char_mask = String::kMaxAsciiCharCode;
2507
+ char_mask = String::kMaxOneByteCharCode;
2386
2508
  } else {
2387
2509
  char_mask = String::kMaxUtf16CodeUnit;
2388
2510
  }
@@ -2392,7 +2514,11 @@ bool RegExpNode::EmitQuickCheck(RegExpCompiler* compiler,
2392
2514
  // For 2-character preloads in ASCII mode or 1-character preloads in
2393
2515
  // TWO_BYTE mode we also use a 16 bit load with zero extend.
2394
2516
  if (details->characters() == 2 && compiler->ascii()) {
2395
- if ((mask & 0x7f7f) == 0x7f7f) need_mask = false;
2517
+ #ifndef ENABLE_LATIN_1
2518
+ if ((mask & 0x7f7f) == 0xffff) need_mask = false;
2519
+ #else
2520
+ if ((mask & 0xffff) == 0xffff) need_mask = false;
2521
+ #endif
2396
2522
  } else if (details->characters() == 1 && !compiler->ascii()) {
2397
2523
  if ((mask & 0xffff) == 0xffff) need_mask = false;
2398
2524
  } else {
@@ -2434,7 +2560,7 @@ void TextNode::GetQuickCheckDetails(QuickCheckDetails* details,
2434
2560
  int characters = details->characters();
2435
2561
  int char_mask;
2436
2562
  if (compiler->ascii()) {
2437
- char_mask = String::kMaxAsciiCharCode;
2563
+ char_mask = String::kMaxOneByteCharCode;
2438
2564
  } else {
2439
2565
  char_mask = String::kMaxUtf16CodeUnit;
2440
2566
  }
@@ -2504,7 +2630,7 @@ void TextNode::GetQuickCheckDetails(QuickCheckDetails* details,
2504
2630
  QuickCheckDetails::Position* pos =
2505
2631
  details->positions(characters_filled_in);
2506
2632
  RegExpCharacterClass* tree = elm.data.u_char_class;
2507
- ZoneList<CharacterRange>* ranges = tree->ranges();
2633
+ ZoneList<CharacterRange>* ranges = tree->ranges(zone());
2508
2634
  if (tree->is_negated()) {
2509
2635
  // A quick check uses multi-character mask and compare. There is no
2510
2636
  // useful way to incorporate a negative char class into this scheme
@@ -2651,24 +2777,47 @@ class VisitMarker {
2651
2777
  };
2652
2778
 
2653
2779
 
2654
- RegExpNode* SeqRegExpNode::FilterASCII(int depth) {
2780
+ RegExpNode* SeqRegExpNode::FilterASCII(int depth, bool ignore_case) {
2655
2781
  if (info()->replacement_calculated) return replacement();
2656
2782
  if (depth < 0) return this;
2657
2783
  ASSERT(!info()->visited);
2658
2784
  VisitMarker marker(info());
2659
- return FilterSuccessor(depth - 1);
2785
+ return FilterSuccessor(depth - 1, ignore_case);
2660
2786
  }
2661
2787
 
2662
2788
 
2663
- RegExpNode* SeqRegExpNode::FilterSuccessor(int depth) {
2664
- RegExpNode* next = on_success_->FilterASCII(depth - 1);
2789
+ RegExpNode* SeqRegExpNode::FilterSuccessor(int depth, bool ignore_case) {
2790
+ RegExpNode* next = on_success_->FilterASCII(depth - 1, ignore_case);
2665
2791
  if (next == NULL) return set_replacement(NULL);
2666
2792
  on_success_ = next;
2667
2793
  return set_replacement(this);
2668
2794
  }
2669
2795
 
2670
2796
 
2671
- RegExpNode* TextNode::FilterASCII(int depth) {
2797
+ // We need to check for the following characters: 0x39c 0x3bc 0x178.
2798
+ static inline bool RangeContainsLatin1Equivalents(CharacterRange range) {
2799
+ #ifdef ENABLE_LATIN_1
2800
+ // TODO(dcarney): this could be a lot more efficient.
2801
+ return range.Contains(0x39c) ||
2802
+ range.Contains(0x3bc) || range.Contains(0x178);
2803
+ #else
2804
+ return false;
2805
+ #endif
2806
+ }
2807
+
2808
+
2809
+ #ifdef ENABLE_LATIN_1
2810
+ static bool RangesContainLatin1Equivalents(ZoneList<CharacterRange>* ranges) {
2811
+ for (int i = 0; i < ranges->length(); i++) {
2812
+ // TODO(dcarney): this could be a lot more efficient.
2813
+ if (RangeContainsLatin1Equivalents(ranges->at(i))) return true;
2814
+ }
2815
+ return false;
2816
+ }
2817
+ #endif
2818
+
2819
+
2820
+ RegExpNode* TextNode::FilterASCII(int depth, bool ignore_case) {
2672
2821
  if (info()->replacement_calculated) return replacement();
2673
2822
  if (depth < 0) return this;
2674
2823
  ASSERT(!info()->visited);
@@ -2679,17 +2828,28 @@ RegExpNode* TextNode::FilterASCII(int depth) {
2679
2828
  if (elm.type == TextElement::ATOM) {
2680
2829
  Vector<const uc16> quarks = elm.data.u_atom->data();
2681
2830
  for (int j = 0; j < quarks.length(); j++) {
2682
- // We don't need special handling for case independence
2683
- // because of the rule that case independence cannot make
2684
- // a non-ASCII character match an ASCII character.
2685
- if (quarks[j] > String::kMaxAsciiCharCode) {
2831
+ #ifndef ENABLE_LATIN_1
2832
+ if (quarks[j] > String::kMaxOneByteCharCode) {
2686
2833
  return set_replacement(NULL);
2687
2834
  }
2835
+ #else
2836
+ uint16_t c = quarks[j];
2837
+ if (c <= String::kMaxOneByteCharCode) continue;
2838
+ if (!ignore_case) return set_replacement(NULL);
2839
+ // Here, we need to check for characters whose upper and lower cases
2840
+ // are outside the Latin-1 range.
2841
+ uint16_t converted = unibrow::Latin1::ConvertNonLatin1ToLatin1(c);
2842
+ // Character is outside Latin-1 completely
2843
+ if (converted == 0) return set_replacement(NULL);
2844
+ // Convert quark to Latin-1 in place.
2845
+ uint16_t* copy = const_cast<uint16_t*>(quarks.start());
2846
+ copy[j] = converted;
2847
+ #endif
2688
2848
  }
2689
2849
  } else {
2690
2850
  ASSERT(elm.type == TextElement::CHAR_CLASS);
2691
2851
  RegExpCharacterClass* cc = elm.data.u_char_class;
2692
- ZoneList<CharacterRange>* ranges = cc->ranges();
2852
+ ZoneList<CharacterRange>* ranges = cc->ranges(zone());
2693
2853
  if (!CharacterRange::IsCanonical(ranges)) {
2694
2854
  CharacterRange::Canonicalize(ranges);
2695
2855
  }
@@ -2698,49 +2858,68 @@ RegExpNode* TextNode::FilterASCII(int depth) {
2698
2858
  if (cc->is_negated()) {
2699
2859
  if (range_count != 0 &&
2700
2860
  ranges->at(0).from() == 0 &&
2701
- ranges->at(0).to() >= String::kMaxAsciiCharCode) {
2861
+ ranges->at(0).to() >= String::kMaxOneByteCharCode) {
2862
+ #ifdef ENABLE_LATIN_1
2863
+ // This will be handled in a later filter.
2864
+ if (ignore_case && RangesContainLatin1Equivalents(ranges)) continue;
2865
+ #endif
2702
2866
  return set_replacement(NULL);
2703
2867
  }
2704
2868
  } else {
2705
2869
  if (range_count == 0 ||
2706
- ranges->at(0).from() > String::kMaxAsciiCharCode) {
2870
+ ranges->at(0).from() > String::kMaxOneByteCharCode) {
2871
+ #ifdef ENABLE_LATIN_1
2872
+ // This will be handled in a later filter.
2873
+ if (ignore_case && RangesContainLatin1Equivalents(ranges)) continue;
2874
+ #endif
2707
2875
  return set_replacement(NULL);
2708
2876
  }
2709
2877
  }
2710
2878
  }
2711
2879
  }
2712
- return FilterSuccessor(depth - 1);
2880
+ return FilterSuccessor(depth - 1, ignore_case);
2713
2881
  }
2714
2882
 
2715
2883
 
2716
- RegExpNode* LoopChoiceNode::FilterASCII(int depth) {
2884
+ RegExpNode* LoopChoiceNode::FilterASCII(int depth, bool ignore_case) {
2717
2885
  if (info()->replacement_calculated) return replacement();
2718
2886
  if (depth < 0) return this;
2719
2887
  if (info()->visited) return this;
2720
2888
  {
2721
2889
  VisitMarker marker(info());
2722
2890
 
2723
- RegExpNode* continue_replacement = continue_node_->FilterASCII(depth - 1);
2891
+ RegExpNode* continue_replacement =
2892
+ continue_node_->FilterASCII(depth - 1, ignore_case);
2724
2893
  // If we can't continue after the loop then there is no sense in doing the
2725
2894
  // loop.
2726
2895
  if (continue_replacement == NULL) return set_replacement(NULL);
2727
2896
  }
2728
2897
 
2729
- return ChoiceNode::FilterASCII(depth - 1);
2898
+ return ChoiceNode::FilterASCII(depth - 1, ignore_case);
2730
2899
  }
2731
2900
 
2732
2901
 
2733
- RegExpNode* ChoiceNode::FilterASCII(int depth) {
2902
+ RegExpNode* ChoiceNode::FilterASCII(int depth, bool ignore_case) {
2734
2903
  if (info()->replacement_calculated) return replacement();
2735
2904
  if (depth < 0) return this;
2736
2905
  if (info()->visited) return this;
2737
2906
  VisitMarker marker(info());
2738
2907
  int choice_count = alternatives_->length();
2908
+
2909
+ for (int i = 0; i < choice_count; i++) {
2910
+ GuardedAlternative alternative = alternatives_->at(i);
2911
+ if (alternative.guards() != NULL && alternative.guards()->length() != 0) {
2912
+ set_replacement(this);
2913
+ return this;
2914
+ }
2915
+ }
2916
+
2739
2917
  int surviving = 0;
2740
2918
  RegExpNode* survivor = NULL;
2741
2919
  for (int i = 0; i < choice_count; i++) {
2742
2920
  GuardedAlternative alternative = alternatives_->at(i);
2743
- RegExpNode* replacement = alternative.node()->FilterASCII(depth - 1);
2921
+ RegExpNode* replacement =
2922
+ alternative.node()->FilterASCII(depth - 1, ignore_case);
2744
2923
  ASSERT(replacement != this); // No missing EMPTY_MATCH_CHECK.
2745
2924
  if (replacement != NULL) {
2746
2925
  alternatives_->at(i).set_node(replacement);
@@ -2757,13 +2936,13 @@ RegExpNode* ChoiceNode::FilterASCII(int depth) {
2757
2936
  // Only some of the nodes survived the filtering. We need to rebuild the
2758
2937
  // alternatives list.
2759
2938
  ZoneList<GuardedAlternative>* new_alternatives =
2760
- new ZoneList<GuardedAlternative>(surviving);
2939
+ new(zone()) ZoneList<GuardedAlternative>(surviving, zone());
2761
2940
  for (int i = 0; i < choice_count; i++) {
2762
2941
  RegExpNode* replacement =
2763
- alternatives_->at(i).node()->FilterASCII(depth - 1);
2942
+ alternatives_->at(i).node()->FilterASCII(depth - 1, ignore_case);
2764
2943
  if (replacement != NULL) {
2765
2944
  alternatives_->at(i).set_node(replacement);
2766
- new_alternatives->Add(alternatives_->at(i));
2945
+ new_alternatives->Add(alternatives_->at(i), zone());
2767
2946
  }
2768
2947
  }
2769
2948
  alternatives_ = new_alternatives;
@@ -2771,7 +2950,8 @@ RegExpNode* ChoiceNode::FilterASCII(int depth) {
2771
2950
  }
2772
2951
 
2773
2952
 
2774
- RegExpNode* NegativeLookaheadChoiceNode::FilterASCII(int depth) {
2953
+ RegExpNode* NegativeLookaheadChoiceNode::FilterASCII(int depth,
2954
+ bool ignore_case) {
2775
2955
  if (info()->replacement_calculated) return replacement();
2776
2956
  if (depth < 0) return this;
2777
2957
  if (info()->visited) return this;
@@ -2779,12 +2959,12 @@ RegExpNode* NegativeLookaheadChoiceNode::FilterASCII(int depth) {
2779
2959
  // Alternative 0 is the negative lookahead, alternative 1 is what comes
2780
2960
  // afterwards.
2781
2961
  RegExpNode* node = alternatives_->at(1).node();
2782
- RegExpNode* replacement = node->FilterASCII(depth - 1);
2962
+ RegExpNode* replacement = node->FilterASCII(depth - 1, ignore_case);
2783
2963
  if (replacement == NULL) return set_replacement(NULL);
2784
2964
  alternatives_->at(1).set_node(replacement);
2785
2965
 
2786
2966
  RegExpNode* neg_node = alternatives_->at(0).node();
2787
- RegExpNode* neg_replacement = neg_node->FilterASCII(depth - 1);
2967
+ RegExpNode* neg_replacement = neg_node->FilterASCII(depth - 1, ignore_case);
2788
2968
  // If the negative lookahead is always going to fail then
2789
2969
  // we don't need to check it.
2790
2970
  if (neg_replacement == NULL) return set_replacement(replacement);
@@ -2808,15 +2988,18 @@ void LoopChoiceNode::GetQuickCheckDetails(QuickCheckDetails* details,
2808
2988
 
2809
2989
  void LoopChoiceNode::FillInBMInfo(int offset,
2810
2990
  int recursion_depth,
2991
+ int budget,
2811
2992
  BoyerMooreLookahead* bm,
2812
2993
  bool not_at_start) {
2813
2994
  if (body_can_be_zero_length_ ||
2814
- recursion_depth > RegExpCompiler::kMaxRecursion) {
2995
+ recursion_depth > RegExpCompiler::kMaxRecursion ||
2996
+ budget <= 0) {
2815
2997
  bm->SetRest(offset);
2816
2998
  SaveBMInfo(bm, not_at_start, offset);
2817
2999
  return;
2818
3000
  }
2819
- ChoiceNode::FillInBMInfo(offset, recursion_depth + 1, bm, not_at_start);
3001
+ ChoiceNode::FillInBMInfo(
3002
+ offset, recursion_depth + 1, budget - 1, bm, not_at_start);
2820
3003
  SaveBMInfo(bm, not_at_start, offset);
2821
3004
  }
2822
3005
 
@@ -2917,8 +3100,8 @@ void AssertionNode::EmitBoundaryCheck(RegExpCompiler* compiler, Trace* trace) {
2917
3100
  EatsAtLeast(kMaxLookaheadForBoyerMoore, 0, not_at_start));
2918
3101
  if (eats_at_least >= 1) {
2919
3102
  BoyerMooreLookahead* bm =
2920
- new BoyerMooreLookahead(eats_at_least, compiler);
2921
- FillInBMInfo(0, 0, bm, not_at_start);
3103
+ new(zone()) BoyerMooreLookahead(eats_at_least, compiler, zone());
3104
+ FillInBMInfo(0, 0, kFillInBMBudget, bm, not_at_start);
2922
3105
  if (bm->at(0)->is_non_word()) next_is_word_character = Trace::FALSE;
2923
3106
  if (bm->at(0)->is_word()) next_is_word_character = Trace::TRUE;
2924
3107
  }
@@ -3104,7 +3287,7 @@ void TextNode::TextEmitPass(RegExpCompiler* compiler,
3104
3287
  switch (pass) {
3105
3288
  case NON_ASCII_MATCH:
3106
3289
  ASSERT(ascii);
3107
- if (quarks[j] > String::kMaxAsciiCharCode) {
3290
+ if (quarks[j] > String::kMaxOneByteCharCode) {
3108
3291
  assembler->GoTo(backtrack);
3109
3292
  return;
3110
3293
  }
@@ -3144,7 +3327,8 @@ void TextNode::TextEmitPass(RegExpCompiler* compiler,
3144
3327
  backtrack,
3145
3328
  cp_offset,
3146
3329
  *checked_up_to < cp_offset,
3147
- preloaded);
3330
+ preloaded,
3331
+ zone());
3148
3332
  UpdateBoundsCheck(cp_offset, checked_up_to);
3149
3333
  }
3150
3334
  }
@@ -3265,11 +3449,11 @@ void TextNode::MakeCaseIndependent(bool is_ascii) {
3265
3449
  RegExpCharacterClass* cc = elm.data.u_char_class;
3266
3450
  // None of the standard character classes is different in the case
3267
3451
  // independent case and it slows us down if we don't know that.
3268
- if (cc->is_standard()) continue;
3269
- ZoneList<CharacterRange>* ranges = cc->ranges();
3452
+ if (cc->is_standard(zone())) continue;
3453
+ ZoneList<CharacterRange>* ranges = cc->ranges(zone());
3270
3454
  int range_count = ranges->length();
3271
3455
  for (int j = 0; j < range_count; j++) {
3272
- ranges->at(j).AddCaseEquivalents(ranges, is_ascii);
3456
+ ranges->at(j).AddCaseEquivalents(ranges, is_ascii, zone());
3273
3457
  }
3274
3458
  }
3275
3459
  }
@@ -3292,7 +3476,7 @@ RegExpNode* TextNode::GetSuccessorOfOmnivorousTextNode(
3292
3476
  TextElement elm = elms_->at(0);
3293
3477
  if (elm.type != TextElement::CHAR_CLASS) return NULL;
3294
3478
  RegExpCharacterClass* node = elm.data.u_char_class;
3295
- ZoneList<CharacterRange>* ranges = node->ranges();
3479
+ ZoneList<CharacterRange>* ranges = node->ranges(zone());
3296
3480
  if (!CharacterRange::IsCanonical(ranges)) {
3297
3481
  CharacterRange::Canonicalize(ranges);
3298
3482
  }
@@ -3302,7 +3486,7 @@ RegExpNode* TextNode::GetSuccessorOfOmnivorousTextNode(
3302
3486
  if (ranges->length() != 1) return NULL;
3303
3487
  uint32_t max_char;
3304
3488
  if (compiler->ascii()) {
3305
- max_char = String::kMaxAsciiCharCode;
3489
+ max_char = String::kMaxOneByteCharCode;
3306
3490
  } else {
3307
3491
  max_char = String::kMaxUtf16CodeUnit;
3308
3492
  }
@@ -3414,13 +3598,13 @@ class AlternativeGeneration: public Malloced {
3414
3598
  // size then it is on the stack, otherwise the excess is on the heap.
3415
3599
  class AlternativeGenerationList {
3416
3600
  public:
3417
- explicit AlternativeGenerationList(int count)
3418
- : alt_gens_(count) {
3601
+ AlternativeGenerationList(int count, Zone* zone)
3602
+ : alt_gens_(count, zone) {
3419
3603
  for (int i = 0; i < count && i < kAFew; i++) {
3420
- alt_gens_.Add(a_few_alt_gens_ + i);
3604
+ alt_gens_.Add(a_few_alt_gens_ + i, zone);
3421
3605
  }
3422
3606
  for (int i = kAFew; i < count; i++) {
3423
- alt_gens_.Add(new AlternativeGeneration());
3607
+ alt_gens_.Add(new AlternativeGeneration(), zone);
3424
3608
  }
3425
3609
  }
3426
3610
  ~AlternativeGenerationList() {
@@ -3498,17 +3682,17 @@ void BoyerMoorePositionInfo::SetAll() {
3498
3682
 
3499
3683
 
3500
3684
  BoyerMooreLookahead::BoyerMooreLookahead(
3501
- int length, RegExpCompiler* compiler)
3685
+ int length, RegExpCompiler* compiler, Zone* zone)
3502
3686
  : length_(length),
3503
3687
  compiler_(compiler) {
3504
3688
  if (compiler->ascii()) {
3505
- max_char_ = String::kMaxAsciiCharCode;
3689
+ max_char_ = String::kMaxOneByteCharCode;
3506
3690
  } else {
3507
3691
  max_char_ = String::kMaxUtf16CodeUnit;
3508
3692
  }
3509
- bitmaps_ = new ZoneList<BoyerMoorePositionInfo*>(length);
3693
+ bitmaps_ = new(zone) ZoneList<BoyerMoorePositionInfo*>(length, zone);
3510
3694
  for (int i = 0; i < length; i++) {
3511
- bitmaps_->Add(new BoyerMoorePositionInfo());
3695
+ bitmaps_->Add(new(zone) BoyerMoorePositionInfo(zone), zone);
3512
3696
  }
3513
3697
  }
3514
3698
 
@@ -3854,9 +4038,11 @@ void ChoiceNode::Emit(RegExpCompiler* compiler, Trace* trace) {
3854
4038
  EatsAtLeast(kMaxLookaheadForBoyerMoore, 0, not_at_start));
3855
4039
  if (eats_at_least >= 1) {
3856
4040
  BoyerMooreLookahead* bm =
3857
- new BoyerMooreLookahead(eats_at_least, compiler);
4041
+ new(zone()) BoyerMooreLookahead(eats_at_least,
4042
+ compiler,
4043
+ zone());
3858
4044
  GuardedAlternative alt0 = alternatives_->at(0);
3859
- alt0.node()->FillInBMInfo(0, 0, bm, not_at_start);
4045
+ alt0.node()->FillInBMInfo(0, 0, kFillInBMBudget, bm, not_at_start);
3860
4046
  skip_was_emitted = bm->EmitSkipInstructions(macro_assembler);
3861
4047
  }
3862
4048
  } else {
@@ -3876,7 +4062,7 @@ void ChoiceNode::Emit(RegExpCompiler* compiler, Trace* trace) {
3876
4062
  (current_trace->characters_preloaded() == preload_characters);
3877
4063
  bool preload_has_checked_bounds = preload_is_current;
3878
4064
 
3879
- AlternativeGenerationList alt_gens(choice_count);
4065
+ AlternativeGenerationList alt_gens(choice_count, zone());
3880
4066
 
3881
4067
  // For now we just call all choices one after the other. The idea ultimately
3882
4068
  // is to use the Dispatch table to try only the relevant ones.
@@ -4356,6 +4542,7 @@ void DotPrinter::VisitChoice(ChoiceNode* that) {
4356
4542
 
4357
4543
 
4358
4544
  void DotPrinter::VisitText(TextNode* that) {
4545
+ Zone* zone = that->zone();
4359
4546
  stream()->Add(" n%p [label=\"", that);
4360
4547
  for (int i = 0; i < that->elements()->length(); i++) {
4361
4548
  if (i > 0) stream()->Add(" ");
@@ -4370,8 +4557,8 @@ void DotPrinter::VisitText(TextNode* that) {
4370
4557
  stream()->Add("[");
4371
4558
  if (node->is_negated())
4372
4559
  stream()->Add("^");
4373
- for (int j = 0; j < node->ranges()->length(); j++) {
4374
- CharacterRange range = node->ranges()->at(j);
4560
+ for (int j = 0; j < node->ranges(zone)->length(); j++) {
4561
+ CharacterRange range = node->ranges(zone)->at(j);
4375
4562
  stream()->Add("%k-%k", range.from(), range.to());
4376
4563
  }
4377
4564
  stream()->Add("]");
@@ -4529,15 +4716,16 @@ void RegExpEngine::DotPrint(const char* label,
4529
4716
 
4530
4717
  RegExpNode* RegExpAtom::ToNode(RegExpCompiler* compiler,
4531
4718
  RegExpNode* on_success) {
4532
- ZoneList<TextElement>* elms = new ZoneList<TextElement>(1);
4533
- elms->Add(TextElement::Atom(this));
4534
- return new TextNode(elms, on_success);
4719
+ ZoneList<TextElement>* elms =
4720
+ new(compiler->zone()) ZoneList<TextElement>(1, compiler->zone());
4721
+ elms->Add(TextElement::Atom(this), compiler->zone());
4722
+ return new(compiler->zone()) TextNode(elms, on_success);
4535
4723
  }
4536
4724
 
4537
4725
 
4538
4726
  RegExpNode* RegExpText::ToNode(RegExpCompiler* compiler,
4539
4727
  RegExpNode* on_success) {
4540
- return new TextNode(elements(), on_success);
4728
+ return new(compiler->zone()) TextNode(elements(), on_success);
4541
4729
  }
4542
4730
 
4543
4731
 
@@ -4591,7 +4779,7 @@ static bool CompareRanges(ZoneList<CharacterRange>* ranges,
4591
4779
  }
4592
4780
 
4593
4781
 
4594
- bool RegExpCharacterClass::is_standard() {
4782
+ bool RegExpCharacterClass::is_standard(Zone* zone) {
4595
4783
  // TODO(lrn): Remove need for this function, by not throwing away information
4596
4784
  // along the way.
4597
4785
  if (is_negated_) {
@@ -4600,31 +4788,31 @@ bool RegExpCharacterClass::is_standard() {
4600
4788
  if (set_.is_standard()) {
4601
4789
  return true;
4602
4790
  }
4603
- if (CompareRanges(set_.ranges(), kSpaceRanges, kSpaceRangeCount)) {
4791
+ if (CompareRanges(set_.ranges(zone), kSpaceRanges, kSpaceRangeCount)) {
4604
4792
  set_.set_standard_set_type('s');
4605
4793
  return true;
4606
4794
  }
4607
- if (CompareInverseRanges(set_.ranges(), kSpaceRanges, kSpaceRangeCount)) {
4795
+ if (CompareInverseRanges(set_.ranges(zone), kSpaceRanges, kSpaceRangeCount)) {
4608
4796
  set_.set_standard_set_type('S');
4609
4797
  return true;
4610
4798
  }
4611
- if (CompareInverseRanges(set_.ranges(),
4799
+ if (CompareInverseRanges(set_.ranges(zone),
4612
4800
  kLineTerminatorRanges,
4613
4801
  kLineTerminatorRangeCount)) {
4614
4802
  set_.set_standard_set_type('.');
4615
4803
  return true;
4616
4804
  }
4617
- if (CompareRanges(set_.ranges(),
4805
+ if (CompareRanges(set_.ranges(zone),
4618
4806
  kLineTerminatorRanges,
4619
4807
  kLineTerminatorRangeCount)) {
4620
4808
  set_.set_standard_set_type('n');
4621
4809
  return true;
4622
4810
  }
4623
- if (CompareRanges(set_.ranges(), kWordRanges, kWordRangeCount)) {
4811
+ if (CompareRanges(set_.ranges(zone), kWordRanges, kWordRangeCount)) {
4624
4812
  set_.set_standard_set_type('w');
4625
4813
  return true;
4626
4814
  }
4627
- if (CompareInverseRanges(set_.ranges(), kWordRanges, kWordRangeCount)) {
4815
+ if (CompareInverseRanges(set_.ranges(zone), kWordRanges, kWordRangeCount)) {
4628
4816
  set_.set_standard_set_type('W');
4629
4817
  return true;
4630
4818
  }
@@ -4634,7 +4822,7 @@ bool RegExpCharacterClass::is_standard() {
4634
4822
 
4635
4823
  RegExpNode* RegExpCharacterClass::ToNode(RegExpCompiler* compiler,
4636
4824
  RegExpNode* on_success) {
4637
- return new TextNode(this, on_success);
4825
+ return new(compiler->zone()) TextNode(this, on_success);
4638
4826
  }
4639
4827
 
4640
4828
 
@@ -4642,7 +4830,8 @@ RegExpNode* RegExpDisjunction::ToNode(RegExpCompiler* compiler,
4642
4830
  RegExpNode* on_success) {
4643
4831
  ZoneList<RegExpTree*>* alternatives = this->alternatives();
4644
4832
  int length = alternatives->length();
4645
- ChoiceNode* result = new ChoiceNode(length);
4833
+ ChoiceNode* result =
4834
+ new(compiler->zone()) ChoiceNode(length, compiler->zone());
4646
4835
  for (int i = 0; i < length; i++) {
4647
4836
  GuardedAlternative alternative(alternatives->at(i)->ToNode(compiler,
4648
4837
  on_success));
@@ -4735,6 +4924,8 @@ RegExpNode* RegExpQuantifier::ToNode(int min,
4735
4924
  int body_start_reg = RegExpCompiler::kNoRegister;
4736
4925
  Interval capture_registers = body->CaptureRegisters();
4737
4926
  bool needs_capture_clearing = !capture_registers.is_empty();
4927
+ Zone* zone = compiler->zone();
4928
+
4738
4929
  if (body_can_be_empty) {
4739
4930
  body_start_reg = compiler->AllocateRegister();
4740
4931
  } else if (FLAG_regexp_optimization && !needs_capture_clearing) {
@@ -4765,7 +4956,7 @@ RegExpNode* RegExpQuantifier::ToNode(int min,
4765
4956
  // Unroll the optional matches up to max.
4766
4957
  RegExpNode* answer = on_success;
4767
4958
  for (int i = 0; i < max; i++) {
4768
- ChoiceNode* alternation = new ChoiceNode(2);
4959
+ ChoiceNode* alternation = new(zone) ChoiceNode(2, zone);
4769
4960
  if (is_greedy) {
4770
4961
  alternation->AddAlternative(
4771
4962
  GuardedAlternative(body->ToNode(compiler, answer)));
@@ -4788,7 +4979,8 @@ RegExpNode* RegExpQuantifier::ToNode(int min,
4788
4979
  int reg_ctr = needs_counter
4789
4980
  ? compiler->AllocateRegister()
4790
4981
  : RegExpCompiler::kNoRegister;
4791
- LoopChoiceNode* center = new LoopChoiceNode(body->min_match() == 0);
4982
+ LoopChoiceNode* center = new(zone) LoopChoiceNode(body->min_match() == 0,
4983
+ zone);
4792
4984
  if (not_at_start) center->set_not_at_start();
4793
4985
  RegExpNode* loop_return = needs_counter
4794
4986
  ? static_cast<RegExpNode*>(ActionNode::IncrementRegister(reg_ctr, center))
@@ -4813,13 +5005,14 @@ RegExpNode* RegExpQuantifier::ToNode(int min,
4813
5005
  }
4814
5006
  GuardedAlternative body_alt(body_node);
4815
5007
  if (has_max) {
4816
- Guard* body_guard = new Guard(reg_ctr, Guard::LT, max);
4817
- body_alt.AddGuard(body_guard);
5008
+ Guard* body_guard =
5009
+ new(zone) Guard(reg_ctr, Guard::LT, max);
5010
+ body_alt.AddGuard(body_guard, zone);
4818
5011
  }
4819
5012
  GuardedAlternative rest_alt(on_success);
4820
5013
  if (has_min) {
4821
- Guard* rest_guard = new Guard(reg_ctr, Guard::GEQ, min);
4822
- rest_alt.AddGuard(rest_guard);
5014
+ Guard* rest_guard = new(compiler->zone()) Guard(reg_ctr, Guard::GEQ, min);
5015
+ rest_alt.AddGuard(rest_guard, zone);
4823
5016
  }
4824
5017
  if (is_greedy) {
4825
5018
  center->AddLoopAlternative(body_alt);
@@ -4839,6 +5032,8 @@ RegExpNode* RegExpQuantifier::ToNode(int min,
4839
5032
  RegExpNode* RegExpAssertion::ToNode(RegExpCompiler* compiler,
4840
5033
  RegExpNode* on_success) {
4841
5034
  NodeInfo info;
5035
+ Zone* zone = compiler->zone();
5036
+
4842
5037
  switch (type()) {
4843
5038
  case START_OF_LINE:
4844
5039
  return AssertionNode::AfterNewline(on_success);
@@ -4857,13 +5052,13 @@ RegExpNode* RegExpAssertion::ToNode(RegExpCompiler* compiler,
4857
5052
  int stack_pointer_register = compiler->AllocateRegister();
4858
5053
  int position_register = compiler->AllocateRegister();
4859
5054
  // The ChoiceNode to distinguish between a newline and end-of-input.
4860
- ChoiceNode* result = new ChoiceNode(2);
5055
+ ChoiceNode* result = new(zone) ChoiceNode(2, zone);
4861
5056
  // Create a newline atom.
4862
5057
  ZoneList<CharacterRange>* newline_ranges =
4863
- new ZoneList<CharacterRange>(3);
4864
- CharacterRange::AddClassEscape('n', newline_ranges);
4865
- RegExpCharacterClass* newline_atom = new RegExpCharacterClass('n');
4866
- TextNode* newline_matcher = new TextNode(
5058
+ new(zone) ZoneList<CharacterRange>(3, zone);
5059
+ CharacterRange::AddClassEscape('n', newline_ranges, zone);
5060
+ RegExpCharacterClass* newline_atom = new(zone) RegExpCharacterClass('n');
5061
+ TextNode* newline_matcher = new(zone) TextNode(
4867
5062
  newline_atom,
4868
5063
  ActionNode::PositiveSubmatchSuccess(stack_pointer_register,
4869
5064
  position_register,
@@ -4891,9 +5086,10 @@ RegExpNode* RegExpAssertion::ToNode(RegExpCompiler* compiler,
4891
5086
 
4892
5087
  RegExpNode* RegExpBackReference::ToNode(RegExpCompiler* compiler,
4893
5088
  RegExpNode* on_success) {
4894
- return new BackReferenceNode(RegExpCapture::StartRegister(index()),
4895
- RegExpCapture::EndRegister(index()),
4896
- on_success);
5089
+ return new(compiler->zone())
5090
+ BackReferenceNode(RegExpCapture::StartRegister(index()),
5091
+ RegExpCapture::EndRegister(index()),
5092
+ on_success);
4897
5093
  }
4898
5094
 
4899
5095
 
@@ -4938,16 +5134,20 @@ RegExpNode* RegExpLookahead::ToNode(RegExpCompiler* compiler,
4938
5134
  // for a negative lookahead. The NegativeLookaheadChoiceNode is a special
4939
5135
  // ChoiceNode that knows to ignore the first exit when calculating quick
4940
5136
  // checks.
5137
+ Zone* zone = compiler->zone();
5138
+
4941
5139
  GuardedAlternative body_alt(
4942
5140
  body()->ToNode(
4943
5141
  compiler,
4944
- success = new NegativeSubmatchSuccess(stack_pointer_register,
4945
- position_register,
4946
- register_count,
4947
- register_start)));
5142
+ success = new(zone) NegativeSubmatchSuccess(stack_pointer_register,
5143
+ position_register,
5144
+ register_count,
5145
+ register_start,
5146
+ zone)));
4948
5147
  ChoiceNode* choice_node =
4949
- new NegativeLookaheadChoiceNode(body_alt,
4950
- GuardedAlternative(on_success));
5148
+ new(zone) NegativeLookaheadChoiceNode(body_alt,
5149
+ GuardedAlternative(on_success),
5150
+ zone);
4951
5151
  return ActionNode::BeginSubmatch(stack_pointer_register,
4952
5152
  position_register,
4953
5153
  choice_node);
@@ -4986,19 +5186,21 @@ RegExpNode* RegExpAlternative::ToNode(RegExpCompiler* compiler,
4986
5186
 
4987
5187
  static void AddClass(const int* elmv,
4988
5188
  int elmc,
4989
- ZoneList<CharacterRange>* ranges) {
5189
+ ZoneList<CharacterRange>* ranges,
5190
+ Zone* zone) {
4990
5191
  elmc--;
4991
5192
  ASSERT(elmv[elmc] == 0x10000);
4992
5193
  for (int i = 0; i < elmc; i += 2) {
4993
5194
  ASSERT(elmv[i] < elmv[i + 1]);
4994
- ranges->Add(CharacterRange(elmv[i], elmv[i + 1] - 1));
5195
+ ranges->Add(CharacterRange(elmv[i], elmv[i + 1] - 1), zone);
4995
5196
  }
4996
5197
  }
4997
5198
 
4998
5199
 
4999
5200
  static void AddClassNegated(const int *elmv,
5000
5201
  int elmc,
5001
- ZoneList<CharacterRange>* ranges) {
5202
+ ZoneList<CharacterRange>* ranges,
5203
+ Zone* zone) {
5002
5204
  elmc--;
5003
5205
  ASSERT(elmv[elmc] == 0x10000);
5004
5206
  ASSERT(elmv[0] != 0x0000);
@@ -5007,51 +5209,54 @@ static void AddClassNegated(const int *elmv,
5007
5209
  for (int i = 0; i < elmc; i += 2) {
5008
5210
  ASSERT(last <= elmv[i] - 1);
5009
5211
  ASSERT(elmv[i] < elmv[i + 1]);
5010
- ranges->Add(CharacterRange(last, elmv[i] - 1));
5212
+ ranges->Add(CharacterRange(last, elmv[i] - 1), zone);
5011
5213
  last = elmv[i + 1];
5012
5214
  }
5013
- ranges->Add(CharacterRange(last, String::kMaxUtf16CodeUnit));
5215
+ ranges->Add(CharacterRange(last, String::kMaxUtf16CodeUnit), zone);
5014
5216
  }
5015
5217
 
5016
5218
 
5017
5219
  void CharacterRange::AddClassEscape(uc16 type,
5018
- ZoneList<CharacterRange>* ranges) {
5220
+ ZoneList<CharacterRange>* ranges,
5221
+ Zone* zone) {
5019
5222
  switch (type) {
5020
5223
  case 's':
5021
- AddClass(kSpaceRanges, kSpaceRangeCount, ranges);
5224
+ AddClass(kSpaceRanges, kSpaceRangeCount, ranges, zone);
5022
5225
  break;
5023
5226
  case 'S':
5024
- AddClassNegated(kSpaceRanges, kSpaceRangeCount, ranges);
5227
+ AddClassNegated(kSpaceRanges, kSpaceRangeCount, ranges, zone);
5025
5228
  break;
5026
5229
  case 'w':
5027
- AddClass(kWordRanges, kWordRangeCount, ranges);
5230
+ AddClass(kWordRanges, kWordRangeCount, ranges, zone);
5028
5231
  break;
5029
5232
  case 'W':
5030
- AddClassNegated(kWordRanges, kWordRangeCount, ranges);
5233
+ AddClassNegated(kWordRanges, kWordRangeCount, ranges, zone);
5031
5234
  break;
5032
5235
  case 'd':
5033
- AddClass(kDigitRanges, kDigitRangeCount, ranges);
5236
+ AddClass(kDigitRanges, kDigitRangeCount, ranges, zone);
5034
5237
  break;
5035
5238
  case 'D':
5036
- AddClassNegated(kDigitRanges, kDigitRangeCount, ranges);
5239
+ AddClassNegated(kDigitRanges, kDigitRangeCount, ranges, zone);
5037
5240
  break;
5038
5241
  case '.':
5039
5242
  AddClassNegated(kLineTerminatorRanges,
5040
5243
  kLineTerminatorRangeCount,
5041
- ranges);
5244
+ ranges,
5245
+ zone);
5042
5246
  break;
5043
5247
  // This is not a character range as defined by the spec but a
5044
5248
  // convenient shorthand for a character class that matches any
5045
5249
  // character.
5046
5250
  case '*':
5047
- ranges->Add(CharacterRange::Everything());
5251
+ ranges->Add(CharacterRange::Everything(), zone);
5048
5252
  break;
5049
5253
  // This is the set of characters matched by the $ and ^ symbols
5050
5254
  // in multiline mode.
5051
5255
  case 'n':
5052
5256
  AddClass(kLineTerminatorRanges,
5053
5257
  kLineTerminatorRangeCount,
5054
- ranges);
5258
+ ranges,
5259
+ zone);
5055
5260
  break;
5056
5261
  default:
5057
5262
  UNREACHABLE();
@@ -5067,9 +5272,11 @@ Vector<const int> CharacterRange::GetWordBounds() {
5067
5272
  class CharacterRangeSplitter {
5068
5273
  public:
5069
5274
  CharacterRangeSplitter(ZoneList<CharacterRange>** included,
5070
- ZoneList<CharacterRange>** excluded)
5275
+ ZoneList<CharacterRange>** excluded,
5276
+ Zone* zone)
5071
5277
  : included_(included),
5072
- excluded_(excluded) { }
5278
+ excluded_(excluded),
5279
+ zone_(zone) { }
5073
5280
  void Call(uc16 from, DispatchTable::Entry entry);
5074
5281
 
5075
5282
  static const int kInBase = 0;
@@ -5078,6 +5285,7 @@ class CharacterRangeSplitter {
5078
5285
  private:
5079
5286
  ZoneList<CharacterRange>** included_;
5080
5287
  ZoneList<CharacterRange>** excluded_;
5288
+ Zone* zone_;
5081
5289
  };
5082
5290
 
5083
5291
 
@@ -5086,37 +5294,39 @@ void CharacterRangeSplitter::Call(uc16 from, DispatchTable::Entry entry) {
5086
5294
  ZoneList<CharacterRange>** target = entry.out_set()->Get(kInOverlay)
5087
5295
  ? included_
5088
5296
  : excluded_;
5089
- if (*target == NULL) *target = new ZoneList<CharacterRange>(2);
5090
- (*target)->Add(CharacterRange(entry.from(), entry.to()));
5297
+ if (*target == NULL) *target = new(zone_) ZoneList<CharacterRange>(2, zone_);
5298
+ (*target)->Add(CharacterRange(entry.from(), entry.to()), zone_);
5091
5299
  }
5092
5300
 
5093
5301
 
5094
5302
  void CharacterRange::Split(ZoneList<CharacterRange>* base,
5095
5303
  Vector<const int> overlay,
5096
5304
  ZoneList<CharacterRange>** included,
5097
- ZoneList<CharacterRange>** excluded) {
5305
+ ZoneList<CharacterRange>** excluded,
5306
+ Zone* zone) {
5098
5307
  ASSERT_EQ(NULL, *included);
5099
5308
  ASSERT_EQ(NULL, *excluded);
5100
- DispatchTable table;
5309
+ DispatchTable table(zone);
5101
5310
  for (int i = 0; i < base->length(); i++)
5102
- table.AddRange(base->at(i), CharacterRangeSplitter::kInBase);
5311
+ table.AddRange(base->at(i), CharacterRangeSplitter::kInBase, zone);
5103
5312
  for (int i = 0; i < overlay.length(); i += 2) {
5104
5313
  table.AddRange(CharacterRange(overlay[i], overlay[i + 1] - 1),
5105
- CharacterRangeSplitter::kInOverlay);
5314
+ CharacterRangeSplitter::kInOverlay, zone);
5106
5315
  }
5107
- CharacterRangeSplitter callback(included, excluded);
5316
+ CharacterRangeSplitter callback(included, excluded, zone);
5108
5317
  table.ForEach(&callback);
5109
5318
  }
5110
5319
 
5111
5320
 
5112
5321
  void CharacterRange::AddCaseEquivalents(ZoneList<CharacterRange>* ranges,
5113
- bool is_ascii) {
5322
+ bool is_ascii,
5323
+ Zone* zone) {
5114
5324
  Isolate* isolate = Isolate::Current();
5115
5325
  uc16 bottom = from();
5116
5326
  uc16 top = to();
5117
- if (is_ascii) {
5118
- if (bottom > String::kMaxAsciiCharCode) return;
5119
- if (top > String::kMaxAsciiCharCode) top = String::kMaxAsciiCharCode;
5327
+ if (is_ascii && !RangeContainsLatin1Equivalents(*this)) {
5328
+ if (bottom > String::kMaxOneByteCharCode) return;
5329
+ if (top > String::kMaxOneByteCharCode) top = String::kMaxOneByteCharCode;
5120
5330
  }
5121
5331
  unibrow::uchar chars[unibrow::Ecma262UnCanonicalize::kMaxWidth];
5122
5332
  if (top == bottom) {
@@ -5125,7 +5335,7 @@ void CharacterRange::AddCaseEquivalents(ZoneList<CharacterRange>* ranges,
5125
5335
  for (int i = 0; i < length; i++) {
5126
5336
  uc32 chr = chars[i];
5127
5337
  if (chr != bottom) {
5128
- ranges->Add(CharacterRange::Singleton(chars[i]));
5338
+ ranges->Add(CharacterRange::Singleton(chars[i]), zone);
5129
5339
  }
5130
5340
  }
5131
5341
  } else {
@@ -5165,7 +5375,7 @@ void CharacterRange::AddCaseEquivalents(ZoneList<CharacterRange>* ranges,
5165
5375
  uc16 range_from = c - (block_end - pos);
5166
5376
  uc16 range_to = c - (block_end - end);
5167
5377
  if (!(bottom <= range_from && range_to <= top)) {
5168
- ranges->Add(CharacterRange(range_from, range_to));
5378
+ ranges->Add(CharacterRange(range_from, range_to), zone);
5169
5379
  }
5170
5380
  }
5171
5381
  pos = end + 1;
@@ -5188,10 +5398,10 @@ bool CharacterRange::IsCanonical(ZoneList<CharacterRange>* ranges) {
5188
5398
  }
5189
5399
 
5190
5400
 
5191
- ZoneList<CharacterRange>* CharacterSet::ranges() {
5401
+ ZoneList<CharacterRange>* CharacterSet::ranges(Zone* zone) {
5192
5402
  if (ranges_ == NULL) {
5193
- ranges_ = new ZoneList<CharacterRange>(2);
5194
- CharacterRange::AddClassEscape(standard_set_type_, ranges_);
5403
+ ranges_ = new(zone) ZoneList<CharacterRange>(2, zone);
5404
+ CharacterRange::AddClassEscape(standard_set_type_, ranges_, zone);
5195
5405
  }
5196
5406
  return ranges_;
5197
5407
  }
@@ -5320,7 +5530,8 @@ void CharacterRange::Canonicalize(ZoneList<CharacterRange>* character_ranges) {
5320
5530
 
5321
5531
 
5322
5532
  void CharacterRange::Negate(ZoneList<CharacterRange>* ranges,
5323
- ZoneList<CharacterRange>* negated_ranges) {
5533
+ ZoneList<CharacterRange>* negated_ranges,
5534
+ Zone* zone) {
5324
5535
  ASSERT(CharacterRange::IsCanonical(ranges));
5325
5536
  ASSERT_EQ(0, negated_ranges->length());
5326
5537
  int range_count = ranges->length();
@@ -5332,12 +5543,13 @@ void CharacterRange::Negate(ZoneList<CharacterRange>* ranges,
5332
5543
  }
5333
5544
  while (i < range_count) {
5334
5545
  CharacterRange range = ranges->at(i);
5335
- negated_ranges->Add(CharacterRange(from + 1, range.from() - 1));
5546
+ negated_ranges->Add(CharacterRange(from + 1, range.from() - 1), zone);
5336
5547
  from = range.to();
5337
5548
  i++;
5338
5549
  }
5339
5550
  if (from < String::kMaxUtf16CodeUnit) {
5340
- negated_ranges->Add(CharacterRange(from + 1, String::kMaxUtf16CodeUnit));
5551
+ negated_ranges->Add(CharacterRange(from + 1, String::kMaxUtf16CodeUnit),
5552
+ zone);
5341
5553
  }
5342
5554
  }
5343
5555
 
@@ -5346,33 +5558,33 @@ void CharacterRange::Negate(ZoneList<CharacterRange>* ranges,
5346
5558
  // Splay tree
5347
5559
 
5348
5560
 
5349
- OutSet* OutSet::Extend(unsigned value) {
5561
+ OutSet* OutSet::Extend(unsigned value, Zone* zone) {
5350
5562
  if (Get(value))
5351
5563
  return this;
5352
- if (successors() != NULL) {
5353
- for (int i = 0; i < successors()->length(); i++) {
5354
- OutSet* successor = successors()->at(i);
5564
+ if (successors(zone) != NULL) {
5565
+ for (int i = 0; i < successors(zone)->length(); i++) {
5566
+ OutSet* successor = successors(zone)->at(i);
5355
5567
  if (successor->Get(value))
5356
5568
  return successor;
5357
5569
  }
5358
5570
  } else {
5359
- successors_ = new ZoneList<OutSet*>(2);
5571
+ successors_ = new(zone) ZoneList<OutSet*>(2, zone);
5360
5572
  }
5361
- OutSet* result = new OutSet(first_, remaining_);
5362
- result->Set(value);
5363
- successors()->Add(result);
5573
+ OutSet* result = new(zone) OutSet(first_, remaining_);
5574
+ result->Set(value, zone);
5575
+ successors(zone)->Add(result, zone);
5364
5576
  return result;
5365
5577
  }
5366
5578
 
5367
5579
 
5368
- void OutSet::Set(unsigned value) {
5580
+ void OutSet::Set(unsigned value, Zone *zone) {
5369
5581
  if (value < kFirstLimit) {
5370
5582
  first_ |= (1 << value);
5371
5583
  } else {
5372
5584
  if (remaining_ == NULL)
5373
- remaining_ = new ZoneList<unsigned>(1);
5585
+ remaining_ = new(zone) ZoneList<unsigned>(1, zone);
5374
5586
  if (remaining_->is_empty() || !remaining_->Contains(value))
5375
- remaining_->Add(value);
5587
+ remaining_->Add(value, zone);
5376
5588
  }
5377
5589
  }
5378
5590
 
@@ -5391,13 +5603,15 @@ bool OutSet::Get(unsigned value) {
5391
5603
  const uc16 DispatchTable::Config::kNoKey = unibrow::Utf8::kBadChar;
5392
5604
 
5393
5605
 
5394
- void DispatchTable::AddRange(CharacterRange full_range, int value) {
5606
+ void DispatchTable::AddRange(CharacterRange full_range, int value,
5607
+ Zone* zone) {
5395
5608
  CharacterRange current = full_range;
5396
5609
  if (tree()->is_empty()) {
5397
5610
  // If this is the first range we just insert into the table.
5398
5611
  ZoneSplayTree<Config>::Locator loc;
5399
5612
  ASSERT_RESULT(tree()->Insert(current.from(), &loc));
5400
- loc.set_value(Entry(current.from(), current.to(), empty()->Extend(value)));
5613
+ loc.set_value(Entry(current.from(), current.to(),
5614
+ empty()->Extend(value, zone)));
5401
5615
  return;
5402
5616
  }
5403
5617
  // First see if there is a range to the left of this one that
@@ -5440,7 +5654,7 @@ void DispatchTable::AddRange(CharacterRange full_range, int value) {
5440
5654
  ASSERT_RESULT(tree()->Insert(current.from(), &ins));
5441
5655
  ins.set_value(Entry(current.from(),
5442
5656
  entry->from() - 1,
5443
- empty()->Extend(value)));
5657
+ empty()->Extend(value, zone)));
5444
5658
  current.set_from(entry->from());
5445
5659
  }
5446
5660
  ASSERT_EQ(current.from(), entry->from());
@@ -5458,7 +5672,7 @@ void DispatchTable::AddRange(CharacterRange full_range, int value) {
5458
5672
  // The overlapping range is now completely contained by the range
5459
5673
  // we're adding so we can just update it and move the start point
5460
5674
  // of the range we're adding just past it.
5461
- entry->AddValue(value);
5675
+ entry->AddValue(value, zone);
5462
5676
  // Bail out if the last interval ended at 0xFFFF since otherwise
5463
5677
  // adding 1 will wrap around to 0.
5464
5678
  if (entry->to() == String::kMaxUtf16CodeUnit)
@@ -5471,7 +5685,7 @@ void DispatchTable::AddRange(CharacterRange full_range, int value) {
5471
5685
  ASSERT_RESULT(tree()->Insert(current.from(), &ins));
5472
5686
  ins.set_value(Entry(current.from(),
5473
5687
  current.to(),
5474
- empty()->Extend(value)));
5688
+ empty()->Extend(value, zone)));
5475
5689
  break;
5476
5690
  }
5477
5691
  }
@@ -5597,6 +5811,7 @@ void Analysis::VisitAssertion(AssertionNode* that) {
5597
5811
 
5598
5812
  void BackReferenceNode::FillInBMInfo(int offset,
5599
5813
  int recursion_depth,
5814
+ int budget,
5600
5815
  BoyerMooreLookahead* bm,
5601
5816
  bool not_at_start) {
5602
5817
  // Working out the set of characters that a backreference can match is too
@@ -5612,9 +5827,11 @@ STATIC_ASSERT(BoyerMoorePositionInfo::kMapSize ==
5612
5827
 
5613
5828
  void ChoiceNode::FillInBMInfo(int offset,
5614
5829
  int recursion_depth,
5830
+ int budget,
5615
5831
  BoyerMooreLookahead* bm,
5616
5832
  bool not_at_start) {
5617
5833
  ZoneList<GuardedAlternative>* alts = alternatives();
5834
+ budget = (budget - 1) / alts->length();
5618
5835
  for (int i = 0; i < alts->length(); i++) {
5619
5836
  GuardedAlternative& alt = alts->at(i);
5620
5837
  if (alt.guards() != NULL && alt.guards()->length() != 0) {
@@ -5622,7 +5839,8 @@ void ChoiceNode::FillInBMInfo(int offset,
5622
5839
  SaveBMInfo(bm, not_at_start, offset);
5623
5840
  return;
5624
5841
  }
5625
- alt.node()->FillInBMInfo(offset, recursion_depth + 1, bm, not_at_start);
5842
+ alt.node()->FillInBMInfo(
5843
+ offset, recursion_depth + 1, budget, bm, not_at_start);
5626
5844
  }
5627
5845
  SaveBMInfo(bm, not_at_start, offset);
5628
5846
  }
@@ -5630,6 +5848,7 @@ void ChoiceNode::FillInBMInfo(int offset,
5630
5848
 
5631
5849
  void TextNode::FillInBMInfo(int initial_offset,
5632
5850
  int recursion_depth,
5851
+ int budget,
5633
5852
  BoyerMooreLookahead* bm,
5634
5853
  bool not_at_start) {
5635
5854
  if (initial_offset >= bm->length()) return;
@@ -5654,7 +5873,7 @@ void TextNode::FillInBMInfo(int initial_offset,
5654
5873
  int length = GetCaseIndependentLetters(
5655
5874
  ISOLATE,
5656
5875
  character,
5657
- bm->max_char() == String::kMaxAsciiCharCode,
5876
+ bm->max_char() == String::kMaxOneByteCharCode,
5658
5877
  chars);
5659
5878
  for (int j = 0; j < length; j++) {
5660
5879
  bm->Set(offset, chars[j]);
@@ -5666,7 +5885,7 @@ void TextNode::FillInBMInfo(int initial_offset,
5666
5885
  } else {
5667
5886
  ASSERT(text.type == TextElement::CHAR_CLASS);
5668
5887
  RegExpCharacterClass* char_class = text.data.u_char_class;
5669
- ZoneList<CharacterRange>* ranges = char_class->ranges();
5888
+ ZoneList<CharacterRange>* ranges = char_class->ranges(zone());
5670
5889
  if (char_class->is_negated()) {
5671
5890
  bm->SetAll(offset);
5672
5891
  } else {
@@ -5686,6 +5905,7 @@ void TextNode::FillInBMInfo(int initial_offset,
5686
5905
  }
5687
5906
  on_success()->FillInBMInfo(offset,
5688
5907
  recursion_depth + 1,
5908
+ budget - 1,
5689
5909
  bm,
5690
5910
  true); // Not at start after a text node.
5691
5911
  if (initial_offset == 0) set_bm_info(not_at_start, bm);
@@ -5785,7 +6005,7 @@ void DispatchTableConstructor::VisitText(TextNode* that) {
5785
6005
  }
5786
6006
  case TextElement::CHAR_CLASS: {
5787
6007
  RegExpCharacterClass* tree = elm.data.u_char_class;
5788
- ZoneList<CharacterRange>* ranges = tree->ranges();
6008
+ ZoneList<CharacterRange>* ranges = tree->ranges(that->zone());
5789
6009
  if (tree->is_negated()) {
5790
6010
  AddInverse(ranges);
5791
6011
  } else {
@@ -5814,11 +6034,12 @@ RegExpEngine::CompilationResult RegExpEngine::Compile(
5814
6034
  bool is_multiline,
5815
6035
  Handle<String> pattern,
5816
6036
  Handle<String> sample_subject,
5817
- bool is_ascii) {
6037
+ bool is_ascii,
6038
+ Zone* zone) {
5818
6039
  if ((data->capture_count + 1) * 2 - 1 > RegExpMacroAssembler::kMaxRegister) {
5819
6040
  return IrregexpRegExpTooBig();
5820
6041
  }
5821
- RegExpCompiler compiler(data->capture_count, ignore_case, is_ascii);
6042
+ RegExpCompiler compiler(data->capture_count, ignore_case, is_ascii, zone);
5822
6043
 
5823
6044
  // Sample some characters from the middle of the string.
5824
6045
  static const int kSampleSize = 128;
@@ -5848,7 +6069,7 @@ RegExpEngine::CompilationResult RegExpEngine::Compile(
5848
6069
  RegExpQuantifier::ToNode(0,
5849
6070
  RegExpTree::kInfinity,
5850
6071
  false,
5851
- new RegExpCharacterClass('*'),
6072
+ new(zone) RegExpCharacterClass('*'),
5852
6073
  &compiler,
5853
6074
  captured_body,
5854
6075
  data->contains_anchor);
@@ -5856,23 +6077,25 @@ RegExpEngine::CompilationResult RegExpEngine::Compile(
5856
6077
  if (data->contains_anchor) {
5857
6078
  // Unroll loop once, to take care of the case that might start
5858
6079
  // at the start of input.
5859
- ChoiceNode* first_step_node = new ChoiceNode(2);
6080
+ ChoiceNode* first_step_node = new(zone) ChoiceNode(2, zone);
5860
6081
  first_step_node->AddAlternative(GuardedAlternative(captured_body));
5861
6082
  first_step_node->AddAlternative(GuardedAlternative(
5862
- new TextNode(new RegExpCharacterClass('*'), loop_node)));
6083
+ new(zone) TextNode(new(zone) RegExpCharacterClass('*'), loop_node)));
5863
6084
  node = first_step_node;
5864
6085
  } else {
5865
6086
  node = loop_node;
5866
6087
  }
5867
6088
  }
5868
6089
  if (is_ascii) {
5869
- node = node->FilterASCII(RegExpCompiler::kMaxRecursion);
6090
+ node = node->FilterASCII(RegExpCompiler::kMaxRecursion, ignore_case);
5870
6091
  // Do it again to propagate the new nodes to places where they were not
5871
6092
  // put because they had not been calculated yet.
5872
- if (node != NULL) node = node->FilterASCII(RegExpCompiler::kMaxRecursion);
6093
+ if (node != NULL) {
6094
+ node = node->FilterASCII(RegExpCompiler::kMaxRecursion, ignore_case);
6095
+ }
5873
6096
  }
5874
6097
 
5875
- if (node == NULL) node = new EndNode(EndNode::BACKTRACK);
6098
+ if (node == NULL) node = new(zone) EndNode(EndNode::BACKTRACK, zone);
5876
6099
  data->node = node;
5877
6100
  Analysis analysis(ignore_case, is_ascii);
5878
6101
  analysis.EnsureAnalyzed(node);
@@ -5890,19 +6113,23 @@ RegExpEngine::CompilationResult RegExpEngine::Compile(
5890
6113
  : NativeRegExpMacroAssembler::UC16;
5891
6114
 
5892
6115
  #if V8_TARGET_ARCH_IA32
5893
- RegExpMacroAssemblerIA32 macro_assembler(mode, (data->capture_count + 1) * 2);
6116
+ RegExpMacroAssemblerIA32 macro_assembler(mode, (data->capture_count + 1) * 2,
6117
+ zone);
5894
6118
  #elif V8_TARGET_ARCH_X64
5895
- RegExpMacroAssemblerX64 macro_assembler(mode, (data->capture_count + 1) * 2);
6119
+ RegExpMacroAssemblerX64 macro_assembler(mode, (data->capture_count + 1) * 2,
6120
+ zone);
5896
6121
  #elif V8_TARGET_ARCH_ARM
5897
- RegExpMacroAssemblerARM macro_assembler(mode, (data->capture_count + 1) * 2);
6122
+ RegExpMacroAssemblerARM macro_assembler(mode, (data->capture_count + 1) * 2,
6123
+ zone);
5898
6124
  #elif V8_TARGET_ARCH_MIPS
5899
- RegExpMacroAssemblerMIPS macro_assembler(mode, (data->capture_count + 1) * 2);
6125
+ RegExpMacroAssemblerMIPS macro_assembler(mode, (data->capture_count + 1) * 2,
6126
+ zone);
5900
6127
  #endif
5901
6128
 
5902
6129
  #else // V8_INTERPRETED_REGEXP
5903
6130
  // Interpreted regexp implementation.
5904
6131
  EmbeddedVector<byte, 1024> codes;
5905
- RegExpMacroAssemblerIrregexp macro_assembler(codes);
6132
+ RegExpMacroAssemblerIrregexp macro_assembler(codes, zone);
5906
6133
  #endif // V8_INTERPRETED_REGEXP
5907
6134
 
5908
6135
  // Inserted here, instead of in Assembler, because it depends on information
@@ -5914,7 +6141,12 @@ RegExpEngine::CompilationResult RegExpEngine::Compile(
5914
6141
  macro_assembler.SetCurrentPositionFromEnd(max_length);
5915
6142
  }
5916
6143
 
5917
- macro_assembler.set_global(is_global);
6144
+ if (is_global) {
6145
+ macro_assembler.set_global_mode(
6146
+ (data->tree->min_match() > 0)
6147
+ ? RegExpMacroAssembler::GLOBAL_NO_ZERO_LENGTH_CHECK
6148
+ : RegExpMacroAssembler::GLOBAL);
6149
+ }
5918
6150
 
5919
6151
  return compiler.Assemble(&macro_assembler,
5920
6152
  node,