libv8 3.10.8.0 → 3.11.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (215) hide show
  1. data/Rakefile +10 -3
  2. data/ext/libv8/compiler.rb +46 -0
  3. data/ext/libv8/extconf.rb +5 -1
  4. data/ext/libv8/make.rb +13 -0
  5. data/lib/libv8/version.rb +1 -1
  6. data/patches/add-freebsd9-and-freebsd10-to-gyp-GetFlavor.patch +11 -0
  7. data/patches/src_platform-freebsd.cc.patch +10 -0
  8. data/vendor/v8/ChangeLog +124 -0
  9. data/vendor/v8/DEPS +27 -0
  10. data/vendor/v8/Makefile +7 -0
  11. data/vendor/v8/SConstruct +15 -2
  12. data/vendor/v8/build/common.gypi +129 -157
  13. data/vendor/v8/build/gyp_v8 +11 -25
  14. data/vendor/v8/build/standalone.gypi +9 -3
  15. data/vendor/v8/include/v8.h +5 -3
  16. data/vendor/v8/src/SConscript +1 -0
  17. data/vendor/v8/src/api.cc +4 -33
  18. data/vendor/v8/src/api.h +2 -2
  19. data/vendor/v8/src/arm/builtins-arm.cc +5 -4
  20. data/vendor/v8/src/arm/code-stubs-arm.cc +21 -14
  21. data/vendor/v8/src/arm/codegen-arm.cc +2 -2
  22. data/vendor/v8/src/arm/debug-arm.cc +3 -1
  23. data/vendor/v8/src/arm/full-codegen-arm.cc +3 -102
  24. data/vendor/v8/src/arm/ic-arm.cc +30 -33
  25. data/vendor/v8/src/arm/lithium-arm.cc +20 -7
  26. data/vendor/v8/src/arm/lithium-arm.h +10 -4
  27. data/vendor/v8/src/arm/lithium-codegen-arm.cc +106 -60
  28. data/vendor/v8/src/arm/macro-assembler-arm.cc +49 -39
  29. data/vendor/v8/src/arm/macro-assembler-arm.h +5 -4
  30. data/vendor/v8/src/arm/regexp-macro-assembler-arm.cc +115 -55
  31. data/vendor/v8/src/arm/regexp-macro-assembler-arm.h +7 -6
  32. data/vendor/v8/src/arm/simulator-arm.h +6 -6
  33. data/vendor/v8/src/arm/stub-cache-arm.cc +64 -19
  34. data/vendor/v8/src/array.js +7 -3
  35. data/vendor/v8/src/ast.cc +11 -6
  36. data/vendor/v8/src/bootstrapper.cc +9 -11
  37. data/vendor/v8/src/builtins.cc +61 -31
  38. data/vendor/v8/src/code-stubs.cc +23 -9
  39. data/vendor/v8/src/code-stubs.h +1 -0
  40. data/vendor/v8/src/codegen.h +3 -3
  41. data/vendor/v8/src/compiler.cc +1 -1
  42. data/vendor/v8/src/contexts.h +2 -18
  43. data/vendor/v8/src/d8.cc +94 -93
  44. data/vendor/v8/src/d8.h +1 -1
  45. data/vendor/v8/src/debug-agent.cc +3 -3
  46. data/vendor/v8/src/debug.cc +41 -1
  47. data/vendor/v8/src/debug.h +50 -0
  48. data/vendor/v8/src/elements-kind.cc +134 -0
  49. data/vendor/v8/src/elements-kind.h +210 -0
  50. data/vendor/v8/src/elements.cc +356 -190
  51. data/vendor/v8/src/elements.h +36 -28
  52. data/vendor/v8/src/factory.cc +44 -4
  53. data/vendor/v8/src/factory.h +11 -7
  54. data/vendor/v8/src/flag-definitions.h +3 -0
  55. data/vendor/v8/src/frames.h +3 -0
  56. data/vendor/v8/src/full-codegen.cc +2 -1
  57. data/vendor/v8/src/func-name-inferrer.h +2 -0
  58. data/vendor/v8/src/globals.h +3 -0
  59. data/vendor/v8/src/heap-inl.h +16 -4
  60. data/vendor/v8/src/heap.cc +38 -32
  61. data/vendor/v8/src/heap.h +3 -17
  62. data/vendor/v8/src/hydrogen-instructions.cc +28 -5
  63. data/vendor/v8/src/hydrogen-instructions.h +142 -44
  64. data/vendor/v8/src/hydrogen.cc +160 -55
  65. data/vendor/v8/src/hydrogen.h +2 -0
  66. data/vendor/v8/src/ia32/assembler-ia32.h +3 -0
  67. data/vendor/v8/src/ia32/builtins-ia32.cc +5 -4
  68. data/vendor/v8/src/ia32/code-stubs-ia32.cc +22 -16
  69. data/vendor/v8/src/ia32/codegen-ia32.cc +2 -2
  70. data/vendor/v8/src/ia32/debug-ia32.cc +29 -2
  71. data/vendor/v8/src/ia32/full-codegen-ia32.cc +8 -101
  72. data/vendor/v8/src/ia32/ic-ia32.cc +23 -19
  73. data/vendor/v8/src/ia32/lithium-codegen-ia32.cc +126 -80
  74. data/vendor/v8/src/ia32/lithium-codegen-ia32.h +2 -1
  75. data/vendor/v8/src/ia32/lithium-ia32.cc +15 -9
  76. data/vendor/v8/src/ia32/lithium-ia32.h +14 -6
  77. data/vendor/v8/src/ia32/macro-assembler-ia32.cc +50 -40
  78. data/vendor/v8/src/ia32/macro-assembler-ia32.h +5 -4
  79. data/vendor/v8/src/ia32/regexp-macro-assembler-ia32.cc +113 -43
  80. data/vendor/v8/src/ia32/regexp-macro-assembler-ia32.h +9 -4
  81. data/vendor/v8/src/ia32/simulator-ia32.h +4 -4
  82. data/vendor/v8/src/ia32/stub-cache-ia32.cc +52 -14
  83. data/vendor/v8/src/ic.cc +77 -20
  84. data/vendor/v8/src/ic.h +18 -2
  85. data/vendor/v8/src/incremental-marking-inl.h +21 -5
  86. data/vendor/v8/src/incremental-marking.cc +35 -8
  87. data/vendor/v8/src/incremental-marking.h +12 -3
  88. data/vendor/v8/src/isolate.cc +12 -2
  89. data/vendor/v8/src/isolate.h +1 -1
  90. data/vendor/v8/src/jsregexp.cc +66 -26
  91. data/vendor/v8/src/jsregexp.h +60 -31
  92. data/vendor/v8/src/list-inl.h +8 -0
  93. data/vendor/v8/src/list.h +3 -0
  94. data/vendor/v8/src/lithium.cc +5 -2
  95. data/vendor/v8/src/liveedit.cc +57 -5
  96. data/vendor/v8/src/mark-compact-inl.h +17 -11
  97. data/vendor/v8/src/mark-compact.cc +100 -143
  98. data/vendor/v8/src/mark-compact.h +44 -20
  99. data/vendor/v8/src/messages.js +131 -99
  100. data/vendor/v8/src/mips/builtins-mips.cc +5 -4
  101. data/vendor/v8/src/mips/code-stubs-mips.cc +23 -15
  102. data/vendor/v8/src/mips/codegen-mips.cc +2 -2
  103. data/vendor/v8/src/mips/debug-mips.cc +3 -1
  104. data/vendor/v8/src/mips/full-codegen-mips.cc +4 -102
  105. data/vendor/v8/src/mips/ic-mips.cc +34 -36
  106. data/vendor/v8/src/mips/lithium-codegen-mips.cc +116 -68
  107. data/vendor/v8/src/mips/lithium-mips.cc +20 -7
  108. data/vendor/v8/src/mips/lithium-mips.h +11 -4
  109. data/vendor/v8/src/mips/macro-assembler-mips.cc +50 -39
  110. data/vendor/v8/src/mips/macro-assembler-mips.h +5 -4
  111. data/vendor/v8/src/mips/regexp-macro-assembler-mips.cc +110 -50
  112. data/vendor/v8/src/mips/regexp-macro-assembler-mips.h +6 -5
  113. data/vendor/v8/src/mips/simulator-mips.h +5 -5
  114. data/vendor/v8/src/mips/stub-cache-mips.cc +66 -20
  115. data/vendor/v8/src/mksnapshot.cc +5 -1
  116. data/vendor/v8/src/objects-debug.cc +103 -6
  117. data/vendor/v8/src/objects-inl.h +215 -116
  118. data/vendor/v8/src/objects-printer.cc +13 -8
  119. data/vendor/v8/src/objects.cc +608 -331
  120. data/vendor/v8/src/objects.h +129 -94
  121. data/vendor/v8/src/parser.cc +16 -4
  122. data/vendor/v8/src/platform-freebsd.cc +1 -0
  123. data/vendor/v8/src/platform-linux.cc +9 -30
  124. data/vendor/v8/src/platform-posix.cc +28 -7
  125. data/vendor/v8/src/platform-win32.cc +15 -3
  126. data/vendor/v8/src/platform.h +2 -1
  127. data/vendor/v8/src/profile-generator-inl.h +25 -2
  128. data/vendor/v8/src/profile-generator.cc +300 -822
  129. data/vendor/v8/src/profile-generator.h +97 -214
  130. data/vendor/v8/src/regexp-macro-assembler-irregexp.cc +2 -1
  131. data/vendor/v8/src/regexp-macro-assembler-irregexp.h +2 -2
  132. data/vendor/v8/src/regexp-macro-assembler-tracer.cc +6 -5
  133. data/vendor/v8/src/regexp-macro-assembler-tracer.h +1 -1
  134. data/vendor/v8/src/regexp-macro-assembler.cc +7 -3
  135. data/vendor/v8/src/regexp-macro-assembler.h +10 -2
  136. data/vendor/v8/src/regexp.js +6 -0
  137. data/vendor/v8/src/runtime.cc +265 -212
  138. data/vendor/v8/src/runtime.h +6 -5
  139. data/vendor/v8/src/scopes.cc +20 -0
  140. data/vendor/v8/src/scopes.h +6 -3
  141. data/vendor/v8/src/spaces.cc +0 -2
  142. data/vendor/v8/src/string-stream.cc +2 -2
  143. data/vendor/v8/src/v8-counters.h +0 -2
  144. data/vendor/v8/src/v8natives.js +2 -2
  145. data/vendor/v8/src/v8utils.h +6 -3
  146. data/vendor/v8/src/version.cc +1 -1
  147. data/vendor/v8/src/x64/assembler-x64.h +2 -1
  148. data/vendor/v8/src/x64/builtins-x64.cc +5 -4
  149. data/vendor/v8/src/x64/code-stubs-x64.cc +25 -16
  150. data/vendor/v8/src/x64/codegen-x64.cc +2 -2
  151. data/vendor/v8/src/x64/debug-x64.cc +14 -1
  152. data/vendor/v8/src/x64/disasm-x64.cc +1 -1
  153. data/vendor/v8/src/x64/full-codegen-x64.cc +10 -106
  154. data/vendor/v8/src/x64/ic-x64.cc +20 -16
  155. data/vendor/v8/src/x64/lithium-codegen-x64.cc +156 -79
  156. data/vendor/v8/src/x64/lithium-codegen-x64.h +2 -1
  157. data/vendor/v8/src/x64/lithium-x64.cc +18 -8
  158. data/vendor/v8/src/x64/lithium-x64.h +7 -2
  159. data/vendor/v8/src/x64/macro-assembler-x64.cc +50 -40
  160. data/vendor/v8/src/x64/macro-assembler-x64.h +5 -4
  161. data/vendor/v8/src/x64/regexp-macro-assembler-x64.cc +122 -51
  162. data/vendor/v8/src/x64/regexp-macro-assembler-x64.h +17 -8
  163. data/vendor/v8/src/x64/simulator-x64.h +4 -4
  164. data/vendor/v8/src/x64/stub-cache-x64.cc +55 -17
  165. data/vendor/v8/test/cctest/cctest.status +1 -0
  166. data/vendor/v8/test/cctest/test-api.cc +24 -0
  167. data/vendor/v8/test/cctest/test-func-name-inference.cc +38 -0
  168. data/vendor/v8/test/cctest/test-heap-profiler.cc +21 -77
  169. data/vendor/v8/test/cctest/test-heap.cc +164 -3
  170. data/vendor/v8/test/cctest/test-list.cc +12 -0
  171. data/vendor/v8/test/cctest/test-mark-compact.cc +5 -5
  172. data/vendor/v8/test/cctest/test-regexp.cc +14 -8
  173. data/vendor/v8/test/cctest/testcfg.py +2 -0
  174. data/vendor/v8/test/mjsunit/accessor-map-sharing.js +176 -0
  175. data/vendor/v8/test/mjsunit/array-construct-transition.js +3 -3
  176. data/vendor/v8/test/mjsunit/array-literal-transitions.js +10 -10
  177. data/vendor/v8/test/mjsunit/big-array-literal.js +3 -0
  178. data/vendor/v8/test/mjsunit/compiler/inline-construct.js +4 -2
  179. data/vendor/v8/test/mjsunit/debug-liveedit-stack-padding.js +88 -0
  180. data/vendor/v8/test/mjsunit/elements-kind.js +4 -4
  181. data/vendor/v8/test/mjsunit/elements-transition-hoisting.js +2 -2
  182. data/vendor/v8/test/mjsunit/elements-transition.js +5 -5
  183. data/vendor/v8/test/mjsunit/error-constructors.js +68 -33
  184. data/vendor/v8/test/mjsunit/harmony/proxies.js +14 -6
  185. data/vendor/v8/test/mjsunit/mjsunit.status +1 -0
  186. data/vendor/v8/test/mjsunit/packed-elements.js +112 -0
  187. data/vendor/v8/test/mjsunit/regexp-capture-3.js +6 -0
  188. data/vendor/v8/test/mjsunit/regexp-global.js +132 -0
  189. data/vendor/v8/test/mjsunit/regexp.js +11 -0
  190. data/vendor/v8/test/mjsunit/regress/regress-117409.js +52 -0
  191. data/vendor/v8/test/mjsunit/regress/regress-126412.js +33 -0
  192. data/vendor/v8/test/mjsunit/regress/regress-128018.js +35 -0
  193. data/vendor/v8/test/mjsunit/regress/regress-128146.js +33 -0
  194. data/vendor/v8/test/mjsunit/regress/regress-1639-2.js +4 -1
  195. data/vendor/v8/test/mjsunit/regress/regress-1639.js +14 -8
  196. data/vendor/v8/test/mjsunit/regress/regress-1849.js +3 -3
  197. data/vendor/v8/test/mjsunit/regress/regress-1878.js +2 -2
  198. data/vendor/v8/test/mjsunit/regress/regress-2071.js +79 -0
  199. data/vendor/v8/test/mjsunit/regress/regress-2153.js +32 -0
  200. data/vendor/v8/test/mjsunit/regress/regress-crbug-122271.js +4 -4
  201. data/vendor/v8/test/mjsunit/regress/regress-crbug-126414.js +32 -0
  202. data/vendor/v8/test/mjsunit/regress/regress-smi-only-concat.js +2 -2
  203. data/vendor/v8/test/mjsunit/regress/regress-transcendental.js +49 -0
  204. data/vendor/v8/test/mjsunit/stack-traces.js +14 -0
  205. data/vendor/v8/test/mjsunit/unbox-double-arrays.js +4 -3
  206. data/vendor/v8/test/test262/testcfg.py +6 -1
  207. data/vendor/v8/tools/check-static-initializers.sh +11 -3
  208. data/vendor/v8/tools/fuzz-harness.sh +92 -0
  209. data/vendor/v8/tools/grokdump.py +658 -67
  210. data/vendor/v8/tools/gyp/v8.gyp +21 -39
  211. data/vendor/v8/tools/js2c.py +3 -3
  212. data/vendor/v8/tools/jsmin.py +2 -2
  213. data/vendor/v8/tools/presubmit.py +2 -1
  214. data/vendor/v8/tools/test-wrapper-gypbuild.py +25 -11
  215. metadata +624 -612
@@ -1,4 +1,4 @@
1
- // Copyright 2011 the V8 project authors. All rights reserved.
1
+ // Copyright 2012 the V8 project authors. All rights reserved.
2
2
  // Redistribution and use in source and binary forms, with or without
3
3
  // modification, are permitted provided that the following conditions are
4
4
  // met:
@@ -42,6 +42,7 @@ IncrementalMarking::IncrementalMarking(Heap* heap)
42
42
  state_(STOPPED),
43
43
  marking_deque_memory_(NULL),
44
44
  marking_deque_memory_committed_(false),
45
+ marker_(this, heap->mark_compact_collector()),
45
46
  steps_count_(0),
46
47
  steps_took_(0),
47
48
  longest_step_(0.0),
@@ -663,6 +664,22 @@ void IncrementalMarking::Hurry() {
663
664
  } else if (map == global_context_map) {
664
665
  // Global contexts have weak fields.
665
666
  VisitGlobalContext(Context::cast(obj), &marking_visitor);
667
+ } else if (map->instance_type() == MAP_TYPE) {
668
+ Map* map = Map::cast(obj);
669
+ heap_->ClearCacheOnMap(map);
670
+
671
+ // When map collection is enabled we have to mark through map's
672
+ // transitions and back pointers in a special way to make these links
673
+ // weak. Only maps for subclasses of JSReceiver can have transitions.
674
+ STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE);
675
+ if (FLAG_collect_maps &&
676
+ map->instance_type() >= FIRST_JS_RECEIVER_TYPE) {
677
+ marker_.MarkMapContents(map);
678
+ } else {
679
+ marking_visitor.VisitPointers(
680
+ HeapObject::RawField(map, Map::kPointerFieldsBeginOffset),
681
+ HeapObject::RawField(map, Map::kPointerFieldsEndOffset));
682
+ }
666
683
  } else {
667
684
  obj->Iterate(&marking_visitor);
668
685
  }
@@ -807,12 +824,6 @@ void IncrementalMarking::Step(intptr_t allocated_bytes,
807
824
  Map* map = obj->map();
808
825
  if (map == filler_map) continue;
809
826
 
810
- if (obj->IsMap()) {
811
- Map* map = Map::cast(obj);
812
- heap_->ClearCacheOnMap(map);
813
- }
814
-
815
-
816
827
  int size = obj->SizeFromMap(map);
817
828
  bytes_to_process -= size;
818
829
  MarkBit map_mark_bit = Marking::MarkBitFrom(map);
@@ -830,6 +841,22 @@ void IncrementalMarking::Step(intptr_t allocated_bytes,
830
841
  MarkObjectGreyDoNotEnqueue(ctx->normalized_map_cache());
831
842
 
832
843
  VisitGlobalContext(ctx, &marking_visitor);
844
+ } else if (map->instance_type() == MAP_TYPE) {
845
+ Map* map = Map::cast(obj);
846
+ heap_->ClearCacheOnMap(map);
847
+
848
+ // When map collection is enabled we have to mark through map's
849
+ // transitions and back pointers in a special way to make these links
850
+ // weak. Only maps for subclasses of JSReceiver can have transitions.
851
+ STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE);
852
+ if (FLAG_collect_maps &&
853
+ map->instance_type() >= FIRST_JS_RECEIVER_TYPE) {
854
+ marker_.MarkMapContents(map);
855
+ } else {
856
+ marking_visitor.VisitPointers(
857
+ HeapObject::RawField(map, Map::kPointerFieldsBeginOffset),
858
+ HeapObject::RawField(map, Map::kPointerFieldsEndOffset));
859
+ }
833
860
  } else if (map->instance_type() == JS_FUNCTION_TYPE) {
834
861
  marking_visitor.VisitPointers(
835
862
  HeapObject::RawField(obj, JSFunction::kPropertiesOffset),
@@ -951,7 +978,7 @@ void IncrementalMarking::ResetStepCounters() {
951
978
 
952
979
 
953
980
  int64_t IncrementalMarking::SpaceLeftInOldSpace() {
954
- return heap_->MaxOldGenerationSize() - heap_->PromotedSpaceSize();
981
+ return heap_->MaxOldGenerationSize() - heap_->PromotedSpaceSizeOfObjects();
955
982
  }
956
983
 
957
984
  } } // namespace v8::internal
@@ -1,4 +1,4 @@
1
- // Copyright 2011 the V8 project authors. All rights reserved.
1
+ // Copyright 2012 the V8 project authors. All rights reserved.
2
2
  // Redistribution and use in source and binary forms, with or without
3
3
  // modification, are permitted provided that the following conditions are
4
4
  // met:
@@ -154,8 +154,6 @@ class IncrementalMarking {
154
154
 
155
155
  inline void WhiteToGreyAndPush(HeapObject* obj, MarkBit mark_bit);
156
156
 
157
- inline void WhiteToGrey(HeapObject* obj, MarkBit mark_bit);
158
-
159
157
  // Does white->black or keeps gray or black color. Returns true if converting
160
158
  // white to black.
161
159
  inline bool MarkBlackOrKeepGrey(MarkBit mark_bit) {
@@ -169,6 +167,16 @@ class IncrementalMarking {
169
167
  return true;
170
168
  }
171
169
 
170
+ // Marks the object grey and pushes it on the marking stack.
171
+ // Returns true if object needed marking and false otherwise.
172
+ // This is for incremental marking only.
173
+ INLINE(bool MarkObjectAndPush(HeapObject* obj));
174
+
175
+ // Marks the object black without pushing it on the marking stack.
176
+ // Returns true if object needed marking and false otherwise.
177
+ // This is for incremental marking only.
178
+ INLINE(bool MarkObjectWithoutPush(HeapObject* obj));
179
+
172
180
  inline int steps_count() {
173
181
  return steps_count_;
174
182
  }
@@ -260,6 +268,7 @@ class IncrementalMarking {
260
268
  VirtualMemory* marking_deque_memory_;
261
269
  bool marking_deque_memory_committed_;
262
270
  MarkingDeque marking_deque_;
271
+ Marker<IncrementalMarking> marker_;
263
272
 
264
273
  int steps_count_;
265
274
  double steps_took_;
@@ -1131,8 +1131,18 @@ void Isolate::DoThrow(Object* exception, MessageLocation* location) {
1131
1131
  // to the console for easier debugging.
1132
1132
  int line_number = GetScriptLineNumberSafe(location->script(),
1133
1133
  location->start_pos());
1134
- OS::PrintError("Extension or internal compilation error at line %d.\n",
1135
- line_number);
1134
+ if (exception->IsString()) {
1135
+ OS::PrintError(
1136
+ "Extension or internal compilation error: %s in %s at line %d.\n",
1137
+ *String::cast(exception)->ToCString(),
1138
+ *String::cast(location->script()->name())->ToCString(),
1139
+ line_number);
1140
+ } else {
1141
+ OS::PrintError(
1142
+ "Extension or internal compilation error in %s at line %d.\n",
1143
+ *String::cast(location->script()->name())->ToCString(),
1144
+ line_number);
1145
+ }
1136
1146
  }
1137
1147
  }
1138
1148
 
@@ -965,7 +965,7 @@ class Isolate {
965
965
  // SerializerDeserializer state.
966
966
  static const int kPartialSnapshotCacheCapacity = 1400;
967
967
 
968
- static const int kJSRegexpStaticOffsetsVectorSize = 50;
968
+ static const int kJSRegexpStaticOffsetsVectorSize = 128;
969
969
 
970
970
  Address external_callback() {
971
971
  return thread_local_top_.external_callback_;
@@ -1,4 +1,4 @@
1
- // Copyright 2011 the V8 project authors. All rights reserved.
1
+ // Copyright 2012 the V8 project authors. All rights reserved.
2
2
  // Redistribution and use in source and binary forms, with or without
3
3
  // modification, are permitted provided that the following conditions are
4
4
  // met:
@@ -324,7 +324,7 @@ Handle<Object> RegExpImpl::AtomExec(Handle<JSRegExp> re,
324
324
  index)));
325
325
  if (index == -1) return isolate->factory()->null_value();
326
326
  }
327
- ASSERT(last_match_info->HasFastElements());
327
+ ASSERT(last_match_info->HasFastObjectElements());
328
328
 
329
329
  {
330
330
  NoHandleAllocation no_handles;
@@ -429,6 +429,7 @@ bool RegExpImpl::CompileIrregexp(Handle<JSRegExp> re,
429
429
  RegExpEngine::CompilationResult result =
430
430
  RegExpEngine::Compile(&compile_data,
431
431
  flags.is_ignore_case(),
432
+ flags.is_global(),
432
433
  flags.is_multiline(),
433
434
  pattern,
434
435
  sample_subject,
@@ -515,7 +516,23 @@ int RegExpImpl::IrregexpPrepare(Handle<JSRegExp> regexp,
515
516
  }
516
517
 
517
518
 
518
- RegExpImpl::IrregexpResult RegExpImpl::IrregexpExecOnce(
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(
519
536
  Handle<JSRegExp> regexp,
520
537
  Handle<String> subject,
521
538
  int index,
@@ -617,7 +634,7 @@ Handle<Object> RegExpImpl::IrregexpExec(Handle<JSRegExp> jsregexp,
617
634
 
618
635
  OffsetsVector registers(required_registers, isolate);
619
636
 
620
- IrregexpResult res = RegExpImpl::IrregexpExecOnce(
637
+ int res = RegExpImpl::IrregexpExecRaw(
621
638
  jsregexp, subject, previous_index, Vector<int>(registers.vector(),
622
639
  registers.length()));
623
640
  if (res == RE_SUCCESS) {
@@ -2174,12 +2191,13 @@ int ActionNode::EatsAtLeast(int still_to_find,
2174
2191
 
2175
2192
 
2176
2193
  void ActionNode::FillInBMInfo(int offset,
2194
+ int recursion_depth,
2177
2195
  BoyerMooreLookahead* bm,
2178
2196
  bool not_at_start) {
2179
2197
  if (type_ == BEGIN_SUBMATCH) {
2180
2198
  bm->SetRest(offset);
2181
2199
  } else if (type_ != POSITIVE_SUBMATCH_SUCCESS) {
2182
- on_success()->FillInBMInfo(offset, bm, not_at_start);
2200
+ on_success()->FillInBMInfo(offset, recursion_depth + 1, bm, not_at_start);
2183
2201
  }
2184
2202
  SaveBMInfo(bm, not_at_start, offset);
2185
2203
  }
@@ -2201,11 +2219,13 @@ int AssertionNode::EatsAtLeast(int still_to_find,
2201
2219
  }
2202
2220
 
2203
2221
 
2204
- void AssertionNode::FillInBMInfo(
2205
- int offset, BoyerMooreLookahead* bm, bool not_at_start) {
2222
+ void AssertionNode::FillInBMInfo(int offset,
2223
+ int recursion_depth,
2224
+ BoyerMooreLookahead* bm,
2225
+ bool not_at_start) {
2206
2226
  // Match the behaviour of EatsAtLeast on this node.
2207
2227
  if (type() == AT_START && not_at_start) return;
2208
- on_success()->FillInBMInfo(offset, bm, not_at_start);
2228
+ on_success()->FillInBMInfo(offset, recursion_depth + 1, bm, not_at_start);
2209
2229
  SaveBMInfo(bm, not_at_start, offset);
2210
2230
  }
2211
2231
 
@@ -2722,8 +2742,8 @@ RegExpNode* ChoiceNode::FilterASCII(int depth) {
2722
2742
  GuardedAlternative alternative = alternatives_->at(i);
2723
2743
  RegExpNode* replacement = alternative.node()->FilterASCII(depth - 1);
2724
2744
  ASSERT(replacement != this); // No missing EMPTY_MATCH_CHECK.
2725
- alternatives_->at(i).set_node(replacement);
2726
2745
  if (replacement != NULL) {
2746
+ alternatives_->at(i).set_node(replacement);
2727
2747
  surviving++;
2728
2748
  survivor = replacement;
2729
2749
  }
@@ -2739,9 +2759,11 @@ RegExpNode* ChoiceNode::FilterASCII(int depth) {
2739
2759
  ZoneList<GuardedAlternative>* new_alternatives =
2740
2760
  new ZoneList<GuardedAlternative>(surviving);
2741
2761
  for (int i = 0; i < choice_count; i++) {
2742
- GuardedAlternative alternative = alternatives_->at(i);
2743
- if (alternative.node() != NULL) {
2744
- new_alternatives->Add(alternative);
2762
+ RegExpNode* replacement =
2763
+ alternatives_->at(i).node()->FilterASCII(depth - 1);
2764
+ if (replacement != NULL) {
2765
+ alternatives_->at(i).set_node(replacement);
2766
+ new_alternatives->Add(alternatives_->at(i));
2745
2767
  }
2746
2768
  }
2747
2769
  alternatives_ = new_alternatives;
@@ -2784,14 +2806,17 @@ void LoopChoiceNode::GetQuickCheckDetails(QuickCheckDetails* details,
2784
2806
  }
2785
2807
 
2786
2808
 
2787
- void LoopChoiceNode::FillInBMInfo(
2788
- int offset, BoyerMooreLookahead* bm, bool not_at_start) {
2789
- if (body_can_be_zero_length_) {
2809
+ void LoopChoiceNode::FillInBMInfo(int offset,
2810
+ int recursion_depth,
2811
+ BoyerMooreLookahead* bm,
2812
+ bool not_at_start) {
2813
+ if (body_can_be_zero_length_ ||
2814
+ recursion_depth > RegExpCompiler::kMaxRecursion) {
2790
2815
  bm->SetRest(offset);
2791
2816
  SaveBMInfo(bm, not_at_start, offset);
2792
2817
  return;
2793
2818
  }
2794
- ChoiceNode::FillInBMInfo(offset, bm, not_at_start);
2819
+ ChoiceNode::FillInBMInfo(offset, recursion_depth + 1, bm, not_at_start);
2795
2820
  SaveBMInfo(bm, not_at_start, offset);
2796
2821
  }
2797
2822
 
@@ -2893,7 +2918,7 @@ void AssertionNode::EmitBoundaryCheck(RegExpCompiler* compiler, Trace* trace) {
2893
2918
  if (eats_at_least >= 1) {
2894
2919
  BoyerMooreLookahead* bm =
2895
2920
  new BoyerMooreLookahead(eats_at_least, compiler);
2896
- FillInBMInfo(0, bm, not_at_start);
2921
+ FillInBMInfo(0, 0, bm, not_at_start);
2897
2922
  if (bm->at(0)->is_non_word()) next_is_word_character = Trace::FALSE;
2898
2923
  if (bm->at(0)->is_word()) next_is_word_character = Trace::TRUE;
2899
2924
  }
@@ -3831,7 +3856,7 @@ void ChoiceNode::Emit(RegExpCompiler* compiler, Trace* trace) {
3831
3856
  BoyerMooreLookahead* bm =
3832
3857
  new BoyerMooreLookahead(eats_at_least, compiler);
3833
3858
  GuardedAlternative alt0 = alternatives_->at(0);
3834
- alt0.node()->FillInBMInfo(0, bm, not_at_start);
3859
+ alt0.node()->FillInBMInfo(0, 0, bm, not_at_start);
3835
3860
  skip_was_emitted = bm->EmitSkipInstructions(macro_assembler);
3836
3861
  }
3837
3862
  } else {
@@ -5570,8 +5595,10 @@ void Analysis::VisitAssertion(AssertionNode* that) {
5570
5595
  }
5571
5596
 
5572
5597
 
5573
- void BackReferenceNode::FillInBMInfo(
5574
- int offset, BoyerMooreLookahead* bm, bool not_at_start) {
5598
+ void BackReferenceNode::FillInBMInfo(int offset,
5599
+ int recursion_depth,
5600
+ BoyerMooreLookahead* bm,
5601
+ bool not_at_start) {
5575
5602
  // Working out the set of characters that a backreference can match is too
5576
5603
  // hard, so we just say that any character can match.
5577
5604
  bm->SetRest(offset);
@@ -5583,8 +5610,10 @@ STATIC_ASSERT(BoyerMoorePositionInfo::kMapSize ==
5583
5610
  RegExpMacroAssembler::kTableSize);
5584
5611
 
5585
5612
 
5586
- void ChoiceNode::FillInBMInfo(
5587
- int offset, BoyerMooreLookahead* bm, bool not_at_start) {
5613
+ void ChoiceNode::FillInBMInfo(int offset,
5614
+ int recursion_depth,
5615
+ BoyerMooreLookahead* bm,
5616
+ bool not_at_start) {
5588
5617
  ZoneList<GuardedAlternative>* alts = alternatives();
5589
5618
  for (int i = 0; i < alts->length(); i++) {
5590
5619
  GuardedAlternative& alt = alts->at(i);
@@ -5593,14 +5622,16 @@ void ChoiceNode::FillInBMInfo(
5593
5622
  SaveBMInfo(bm, not_at_start, offset);
5594
5623
  return;
5595
5624
  }
5596
- alt.node()->FillInBMInfo(offset, bm, not_at_start);
5625
+ alt.node()->FillInBMInfo(offset, recursion_depth + 1, bm, not_at_start);
5597
5626
  }
5598
5627
  SaveBMInfo(bm, not_at_start, offset);
5599
5628
  }
5600
5629
 
5601
5630
 
5602
- void TextNode::FillInBMInfo(
5603
- int initial_offset, BoyerMooreLookahead* bm, bool not_at_start) {
5631
+ void TextNode::FillInBMInfo(int initial_offset,
5632
+ int recursion_depth,
5633
+ BoyerMooreLookahead* bm,
5634
+ bool not_at_start) {
5604
5635
  if (initial_offset >= bm->length()) return;
5605
5636
  int offset = initial_offset;
5606
5637
  int max_char = bm->max_char();
@@ -5654,6 +5685,7 @@ void TextNode::FillInBMInfo(
5654
5685
  return;
5655
5686
  }
5656
5687
  on_success()->FillInBMInfo(offset,
5688
+ recursion_depth + 1,
5657
5689
  bm,
5658
5690
  true); // Not at start after a text node.
5659
5691
  if (initial_offset == 0) set_bm_info(not_at_start, bm);
@@ -5778,6 +5810,7 @@ void DispatchTableConstructor::VisitAction(ActionNode* that) {
5778
5810
  RegExpEngine::CompilationResult RegExpEngine::Compile(
5779
5811
  RegExpCompileData* data,
5780
5812
  bool ignore_case,
5813
+ bool is_global,
5781
5814
  bool is_multiline,
5782
5815
  Handle<String> pattern,
5783
5816
  Handle<String> sample_subject,
@@ -5832,7 +5865,12 @@ RegExpEngine::CompilationResult RegExpEngine::Compile(
5832
5865
  node = loop_node;
5833
5866
  }
5834
5867
  }
5835
- if (is_ascii) node = node->FilterASCII(RegExpCompiler::kMaxRecursion);
5868
+ if (is_ascii) {
5869
+ node = node->FilterASCII(RegExpCompiler::kMaxRecursion);
5870
+ // Do it again to propagate the new nodes to places where they were not
5871
+ // put because they had not been calculated yet.
5872
+ if (node != NULL) node = node->FilterASCII(RegExpCompiler::kMaxRecursion);
5873
+ }
5836
5874
 
5837
5875
  if (node == NULL) node = new EndNode(EndNode::BACKTRACK);
5838
5876
  data->node = node;
@@ -5876,6 +5914,8 @@ RegExpEngine::CompilationResult RegExpEngine::Compile(
5876
5914
  macro_assembler.SetCurrentPositionFromEnd(max_length);
5877
5915
  }
5878
5916
 
5917
+ macro_assembler.set_global(is_global);
5918
+
5879
5919
  return compiler.Assemble(&macro_assembler,
5880
5920
  node,
5881
5921
  data->capture_count,
@@ -109,16 +109,22 @@ class RegExpImpl {
109
109
  static int IrregexpPrepare(Handle<JSRegExp> regexp,
110
110
  Handle<String> subject);
111
111
 
112
- // Execute a regular expression once on the subject, starting from
113
- // character "index".
114
- // If successful, returns RE_SUCCESS and set the capture positions
115
- // in the first registers.
112
+ // Calculate the size of offsets vector for the case of global regexp
113
+ // and the number of matches this vector is able to store.
114
+ static int GlobalOffsetsVectorSize(Handle<JSRegExp> regexp,
115
+ int registers_per_match,
116
+ int* max_matches);
117
+
118
+ // Execute a regular expression on the subject, starting from index.
119
+ // If matching succeeds, return the number of matches. This can be larger
120
+ // than one in the case of global regular expressions.
121
+ // The captures and subcaptures are stored into the registers vector.
116
122
  // If matching fails, returns RE_FAILURE.
117
123
  // If execution fails, sets a pending exception and returns RE_EXCEPTION.
118
- static IrregexpResult IrregexpExecOnce(Handle<JSRegExp> regexp,
119
- Handle<String> subject,
120
- int index,
121
- Vector<int> registers);
124
+ static int IrregexpExecRaw(Handle<JSRegExp> regexp,
125
+ Handle<String> subject,
126
+ int index,
127
+ Vector<int> registers);
122
128
 
123
129
  // Execute an Irregexp bytecode pattern.
124
130
  // On a successful match, the result is a JSArray containing
@@ -575,8 +581,10 @@ class RegExpNode: public ZoneObject {
575
581
  // we look forward. This is used for a Boyer-Moore-like string searching
576
582
  // implementation. TODO(erikcorry): This should share more code with
577
583
  // EatsAtLeast, GetQuickCheckDetails.
578
- virtual void FillInBMInfo(
579
- int offset, BoyerMooreLookahead* bm, bool not_at_start) {
584
+ virtual void FillInBMInfo(int offset,
585
+ int recursion_depth,
586
+ BoyerMooreLookahead* bm,
587
+ bool not_at_start) {
580
588
  UNREACHABLE();
581
589
  }
582
590
 
@@ -675,9 +683,11 @@ class SeqRegExpNode: public RegExpNode {
675
683
  RegExpNode* on_success() { return on_success_; }
676
684
  void set_on_success(RegExpNode* node) { on_success_ = node; }
677
685
  virtual RegExpNode* FilterASCII(int depth);
678
- virtual void FillInBMInfo(
679
- int offset, BoyerMooreLookahead* bm, bool not_at_start) {
680
- on_success_->FillInBMInfo(offset, bm, not_at_start);
686
+ virtual void FillInBMInfo(int offset,
687
+ int recursion_depth,
688
+ BoyerMooreLookahead* bm,
689
+ bool not_at_start) {
690
+ on_success_->FillInBMInfo(offset, recursion_depth + 1, bm, not_at_start);
681
691
  if (offset == 0) set_bm_info(not_at_start, bm);
682
692
  }
683
693
 
@@ -730,8 +740,10 @@ class ActionNode: public SeqRegExpNode {
730
740
  return on_success()->GetQuickCheckDetails(
731
741
  details, compiler, filled_in, not_at_start);
732
742
  }
733
- virtual void FillInBMInfo(
734
- int offset, BoyerMooreLookahead* bm, bool not_at_start);
743
+ virtual void FillInBMInfo(int offset,
744
+ int recursion_depth,
745
+ BoyerMooreLookahead* bm,
746
+ bool not_at_start);
735
747
  Type type() { return type_; }
736
748
  // TODO(erikcorry): We should allow some action nodes in greedy loops.
737
749
  virtual int GreedyLoopTextLength() { return kNodeIsTooComplexForGreedyLoops; }
@@ -799,8 +811,10 @@ class TextNode: public SeqRegExpNode {
799
811
  virtual int GreedyLoopTextLength();
800
812
  virtual RegExpNode* GetSuccessorOfOmnivorousTextNode(
801
813
  RegExpCompiler* compiler);
802
- virtual void FillInBMInfo(
803
- int offset, BoyerMooreLookahead* bm, bool not_at_start);
814
+ virtual void FillInBMInfo(int offset,
815
+ int recursion_depth,
816
+ BoyerMooreLookahead* bm,
817
+ bool not_at_start);
804
818
  void CalculateOffsets();
805
819
  virtual RegExpNode* FilterASCII(int depth);
806
820
 
@@ -859,8 +873,10 @@ class AssertionNode: public SeqRegExpNode {
859
873
  RegExpCompiler* compiler,
860
874
  int filled_in,
861
875
  bool not_at_start);
862
- virtual void FillInBMInfo(
863
- int offset, BoyerMooreLookahead* bm, bool not_at_start);
876
+ virtual void FillInBMInfo(int offset,
877
+ int recursion_depth,
878
+ BoyerMooreLookahead* bm,
879
+ bool not_at_start);
864
880
  AssertionNodeType type() { return type_; }
865
881
  void set_type(AssertionNodeType type) { type_ = type; }
866
882
 
@@ -897,8 +913,10 @@ class BackReferenceNode: public SeqRegExpNode {
897
913
  bool not_at_start) {
898
914
  return;
899
915
  }
900
- virtual void FillInBMInfo(
901
- int offset, BoyerMooreLookahead* bm, bool not_at_start);
916
+ virtual void FillInBMInfo(int offset,
917
+ int recursion_depth,
918
+ BoyerMooreLookahead* bm,
919
+ bool not_at_start);
902
920
 
903
921
  private:
904
922
  int start_reg_;
@@ -922,8 +940,10 @@ class EndNode: public RegExpNode {
922
940
  // Returning 0 from EatsAtLeast should ensure we never get here.
923
941
  UNREACHABLE();
924
942
  }
925
- virtual void FillInBMInfo(
926
- int offset, BoyerMooreLookahead* bm, bool not_at_start) {
943
+ virtual void FillInBMInfo(int offset,
944
+ int recursion_depth,
945
+ BoyerMooreLookahead* bm,
946
+ bool not_at_start) {
927
947
  // Returning 0 from EatsAtLeast should ensure we never get here.
928
948
  UNREACHABLE();
929
949
  }
@@ -1012,8 +1032,10 @@ class ChoiceNode: public RegExpNode {
1012
1032
  RegExpCompiler* compiler,
1013
1033
  int characters_filled_in,
1014
1034
  bool not_at_start);
1015
- virtual void FillInBMInfo(
1016
- int offset, BoyerMooreLookahead* bm, bool not_at_start);
1035
+ virtual void FillInBMInfo(int offset,
1036
+ int recursion_depth,
1037
+ BoyerMooreLookahead* bm,
1038
+ bool not_at_start);
1017
1039
 
1018
1040
  bool being_calculated() { return being_calculated_; }
1019
1041
  bool not_at_start() { return not_at_start_; }
@@ -1062,9 +1084,12 @@ class NegativeLookaheadChoiceNode: public ChoiceNode {
1062
1084
  RegExpCompiler* compiler,
1063
1085
  int characters_filled_in,
1064
1086
  bool not_at_start);
1065
- virtual void FillInBMInfo(
1066
- int offset, BoyerMooreLookahead* bm, bool not_at_start) {
1067
- alternatives_->at(1).node()->FillInBMInfo(offset, bm, not_at_start);
1087
+ virtual void FillInBMInfo(int offset,
1088
+ int recursion_depth,
1089
+ BoyerMooreLookahead* bm,
1090
+ bool not_at_start) {
1091
+ alternatives_->at(1).node()->FillInBMInfo(
1092
+ offset, recursion_depth + 1, bm, not_at_start);
1068
1093
  if (offset == 0) set_bm_info(not_at_start, bm);
1069
1094
  }
1070
1095
  // For a negative lookahead we don't emit the quick check for the
@@ -1094,8 +1119,10 @@ class LoopChoiceNode: public ChoiceNode {
1094
1119
  RegExpCompiler* compiler,
1095
1120
  int characters_filled_in,
1096
1121
  bool not_at_start);
1097
- virtual void FillInBMInfo(
1098
- int offset, BoyerMooreLookahead* bm, bool not_at_start);
1122
+ virtual void FillInBMInfo(int offset,
1123
+ int recursion_depth,
1124
+ BoyerMooreLookahead* bm,
1125
+ bool not_at_start);
1099
1126
  RegExpNode* loop_node() { return loop_node_; }
1100
1127
  RegExpNode* continue_node() { return continue_node_; }
1101
1128
  bool body_can_be_zero_length() { return body_can_be_zero_length_; }
@@ -1545,6 +1572,7 @@ class RegExpEngine: public AllStatic {
1545
1572
 
1546
1573
  static CompilationResult Compile(RegExpCompileData* input,
1547
1574
  bool ignore_case,
1575
+ bool global,
1548
1576
  bool multiline,
1549
1577
  Handle<String> pattern,
1550
1578
  Handle<String> sample_subject,
@@ -1573,7 +1601,8 @@ class OffsetsVector {
1573
1601
  inline int* vector() { return vector_; }
1574
1602
  inline int length() { return offsets_vector_length_; }
1575
1603
 
1576
- static const int kStaticOffsetsVectorSize = 50;
1604
+ static const int kStaticOffsetsVectorSize =
1605
+ Isolate::kJSRegexpStaticOffsetsVectorSize;
1577
1606
 
1578
1607
  private:
1579
1608
  static Address static_offsets_vector_address(Isolate* isolate) {