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.
- data/Rakefile +10 -3
- data/ext/libv8/compiler.rb +46 -0
- data/ext/libv8/extconf.rb +5 -1
- data/ext/libv8/make.rb +13 -0
- data/lib/libv8/version.rb +1 -1
- data/patches/add-freebsd9-and-freebsd10-to-gyp-GetFlavor.patch +11 -0
- data/patches/src_platform-freebsd.cc.patch +10 -0
- data/vendor/v8/ChangeLog +124 -0
- data/vendor/v8/DEPS +27 -0
- data/vendor/v8/Makefile +7 -0
- data/vendor/v8/SConstruct +15 -2
- data/vendor/v8/build/common.gypi +129 -157
- data/vendor/v8/build/gyp_v8 +11 -25
- data/vendor/v8/build/standalone.gypi +9 -3
- data/vendor/v8/include/v8.h +5 -3
- data/vendor/v8/src/SConscript +1 -0
- data/vendor/v8/src/api.cc +4 -33
- data/vendor/v8/src/api.h +2 -2
- data/vendor/v8/src/arm/builtins-arm.cc +5 -4
- data/vendor/v8/src/arm/code-stubs-arm.cc +21 -14
- data/vendor/v8/src/arm/codegen-arm.cc +2 -2
- data/vendor/v8/src/arm/debug-arm.cc +3 -1
- data/vendor/v8/src/arm/full-codegen-arm.cc +3 -102
- data/vendor/v8/src/arm/ic-arm.cc +30 -33
- data/vendor/v8/src/arm/lithium-arm.cc +20 -7
- data/vendor/v8/src/arm/lithium-arm.h +10 -4
- data/vendor/v8/src/arm/lithium-codegen-arm.cc +106 -60
- data/vendor/v8/src/arm/macro-assembler-arm.cc +49 -39
- data/vendor/v8/src/arm/macro-assembler-arm.h +5 -4
- data/vendor/v8/src/arm/regexp-macro-assembler-arm.cc +115 -55
- data/vendor/v8/src/arm/regexp-macro-assembler-arm.h +7 -6
- data/vendor/v8/src/arm/simulator-arm.h +6 -6
- data/vendor/v8/src/arm/stub-cache-arm.cc +64 -19
- data/vendor/v8/src/array.js +7 -3
- data/vendor/v8/src/ast.cc +11 -6
- data/vendor/v8/src/bootstrapper.cc +9 -11
- data/vendor/v8/src/builtins.cc +61 -31
- data/vendor/v8/src/code-stubs.cc +23 -9
- data/vendor/v8/src/code-stubs.h +1 -0
- data/vendor/v8/src/codegen.h +3 -3
- data/vendor/v8/src/compiler.cc +1 -1
- data/vendor/v8/src/contexts.h +2 -18
- data/vendor/v8/src/d8.cc +94 -93
- data/vendor/v8/src/d8.h +1 -1
- data/vendor/v8/src/debug-agent.cc +3 -3
- data/vendor/v8/src/debug.cc +41 -1
- data/vendor/v8/src/debug.h +50 -0
- data/vendor/v8/src/elements-kind.cc +134 -0
- data/vendor/v8/src/elements-kind.h +210 -0
- data/vendor/v8/src/elements.cc +356 -190
- data/vendor/v8/src/elements.h +36 -28
- data/vendor/v8/src/factory.cc +44 -4
- data/vendor/v8/src/factory.h +11 -7
- data/vendor/v8/src/flag-definitions.h +3 -0
- data/vendor/v8/src/frames.h +3 -0
- data/vendor/v8/src/full-codegen.cc +2 -1
- data/vendor/v8/src/func-name-inferrer.h +2 -0
- data/vendor/v8/src/globals.h +3 -0
- data/vendor/v8/src/heap-inl.h +16 -4
- data/vendor/v8/src/heap.cc +38 -32
- data/vendor/v8/src/heap.h +3 -17
- data/vendor/v8/src/hydrogen-instructions.cc +28 -5
- data/vendor/v8/src/hydrogen-instructions.h +142 -44
- data/vendor/v8/src/hydrogen.cc +160 -55
- data/vendor/v8/src/hydrogen.h +2 -0
- data/vendor/v8/src/ia32/assembler-ia32.h +3 -0
- data/vendor/v8/src/ia32/builtins-ia32.cc +5 -4
- data/vendor/v8/src/ia32/code-stubs-ia32.cc +22 -16
- data/vendor/v8/src/ia32/codegen-ia32.cc +2 -2
- data/vendor/v8/src/ia32/debug-ia32.cc +29 -2
- data/vendor/v8/src/ia32/full-codegen-ia32.cc +8 -101
- data/vendor/v8/src/ia32/ic-ia32.cc +23 -19
- data/vendor/v8/src/ia32/lithium-codegen-ia32.cc +126 -80
- data/vendor/v8/src/ia32/lithium-codegen-ia32.h +2 -1
- data/vendor/v8/src/ia32/lithium-ia32.cc +15 -9
- data/vendor/v8/src/ia32/lithium-ia32.h +14 -6
- data/vendor/v8/src/ia32/macro-assembler-ia32.cc +50 -40
- data/vendor/v8/src/ia32/macro-assembler-ia32.h +5 -4
- data/vendor/v8/src/ia32/regexp-macro-assembler-ia32.cc +113 -43
- data/vendor/v8/src/ia32/regexp-macro-assembler-ia32.h +9 -4
- data/vendor/v8/src/ia32/simulator-ia32.h +4 -4
- data/vendor/v8/src/ia32/stub-cache-ia32.cc +52 -14
- data/vendor/v8/src/ic.cc +77 -20
- data/vendor/v8/src/ic.h +18 -2
- data/vendor/v8/src/incremental-marking-inl.h +21 -5
- data/vendor/v8/src/incremental-marking.cc +35 -8
- data/vendor/v8/src/incremental-marking.h +12 -3
- data/vendor/v8/src/isolate.cc +12 -2
- data/vendor/v8/src/isolate.h +1 -1
- data/vendor/v8/src/jsregexp.cc +66 -26
- data/vendor/v8/src/jsregexp.h +60 -31
- data/vendor/v8/src/list-inl.h +8 -0
- data/vendor/v8/src/list.h +3 -0
- data/vendor/v8/src/lithium.cc +5 -2
- data/vendor/v8/src/liveedit.cc +57 -5
- data/vendor/v8/src/mark-compact-inl.h +17 -11
- data/vendor/v8/src/mark-compact.cc +100 -143
- data/vendor/v8/src/mark-compact.h +44 -20
- data/vendor/v8/src/messages.js +131 -99
- data/vendor/v8/src/mips/builtins-mips.cc +5 -4
- data/vendor/v8/src/mips/code-stubs-mips.cc +23 -15
- data/vendor/v8/src/mips/codegen-mips.cc +2 -2
- data/vendor/v8/src/mips/debug-mips.cc +3 -1
- data/vendor/v8/src/mips/full-codegen-mips.cc +4 -102
- data/vendor/v8/src/mips/ic-mips.cc +34 -36
- data/vendor/v8/src/mips/lithium-codegen-mips.cc +116 -68
- data/vendor/v8/src/mips/lithium-mips.cc +20 -7
- data/vendor/v8/src/mips/lithium-mips.h +11 -4
- data/vendor/v8/src/mips/macro-assembler-mips.cc +50 -39
- data/vendor/v8/src/mips/macro-assembler-mips.h +5 -4
- data/vendor/v8/src/mips/regexp-macro-assembler-mips.cc +110 -50
- data/vendor/v8/src/mips/regexp-macro-assembler-mips.h +6 -5
- data/vendor/v8/src/mips/simulator-mips.h +5 -5
- data/vendor/v8/src/mips/stub-cache-mips.cc +66 -20
- data/vendor/v8/src/mksnapshot.cc +5 -1
- data/vendor/v8/src/objects-debug.cc +103 -6
- data/vendor/v8/src/objects-inl.h +215 -116
- data/vendor/v8/src/objects-printer.cc +13 -8
- data/vendor/v8/src/objects.cc +608 -331
- data/vendor/v8/src/objects.h +129 -94
- data/vendor/v8/src/parser.cc +16 -4
- data/vendor/v8/src/platform-freebsd.cc +1 -0
- data/vendor/v8/src/platform-linux.cc +9 -30
- data/vendor/v8/src/platform-posix.cc +28 -7
- data/vendor/v8/src/platform-win32.cc +15 -3
- data/vendor/v8/src/platform.h +2 -1
- data/vendor/v8/src/profile-generator-inl.h +25 -2
- data/vendor/v8/src/profile-generator.cc +300 -822
- data/vendor/v8/src/profile-generator.h +97 -214
- data/vendor/v8/src/regexp-macro-assembler-irregexp.cc +2 -1
- data/vendor/v8/src/regexp-macro-assembler-irregexp.h +2 -2
- data/vendor/v8/src/regexp-macro-assembler-tracer.cc +6 -5
- data/vendor/v8/src/regexp-macro-assembler-tracer.h +1 -1
- data/vendor/v8/src/regexp-macro-assembler.cc +7 -3
- data/vendor/v8/src/regexp-macro-assembler.h +10 -2
- data/vendor/v8/src/regexp.js +6 -0
- data/vendor/v8/src/runtime.cc +265 -212
- data/vendor/v8/src/runtime.h +6 -5
- data/vendor/v8/src/scopes.cc +20 -0
- data/vendor/v8/src/scopes.h +6 -3
- data/vendor/v8/src/spaces.cc +0 -2
- data/vendor/v8/src/string-stream.cc +2 -2
- data/vendor/v8/src/v8-counters.h +0 -2
- data/vendor/v8/src/v8natives.js +2 -2
- data/vendor/v8/src/v8utils.h +6 -3
- data/vendor/v8/src/version.cc +1 -1
- data/vendor/v8/src/x64/assembler-x64.h +2 -1
- data/vendor/v8/src/x64/builtins-x64.cc +5 -4
- data/vendor/v8/src/x64/code-stubs-x64.cc +25 -16
- data/vendor/v8/src/x64/codegen-x64.cc +2 -2
- data/vendor/v8/src/x64/debug-x64.cc +14 -1
- data/vendor/v8/src/x64/disasm-x64.cc +1 -1
- data/vendor/v8/src/x64/full-codegen-x64.cc +10 -106
- data/vendor/v8/src/x64/ic-x64.cc +20 -16
- data/vendor/v8/src/x64/lithium-codegen-x64.cc +156 -79
- data/vendor/v8/src/x64/lithium-codegen-x64.h +2 -1
- data/vendor/v8/src/x64/lithium-x64.cc +18 -8
- data/vendor/v8/src/x64/lithium-x64.h +7 -2
- data/vendor/v8/src/x64/macro-assembler-x64.cc +50 -40
- data/vendor/v8/src/x64/macro-assembler-x64.h +5 -4
- data/vendor/v8/src/x64/regexp-macro-assembler-x64.cc +122 -51
- data/vendor/v8/src/x64/regexp-macro-assembler-x64.h +17 -8
- data/vendor/v8/src/x64/simulator-x64.h +4 -4
- data/vendor/v8/src/x64/stub-cache-x64.cc +55 -17
- data/vendor/v8/test/cctest/cctest.status +1 -0
- data/vendor/v8/test/cctest/test-api.cc +24 -0
- data/vendor/v8/test/cctest/test-func-name-inference.cc +38 -0
- data/vendor/v8/test/cctest/test-heap-profiler.cc +21 -77
- data/vendor/v8/test/cctest/test-heap.cc +164 -3
- data/vendor/v8/test/cctest/test-list.cc +12 -0
- data/vendor/v8/test/cctest/test-mark-compact.cc +5 -5
- data/vendor/v8/test/cctest/test-regexp.cc +14 -8
- data/vendor/v8/test/cctest/testcfg.py +2 -0
- data/vendor/v8/test/mjsunit/accessor-map-sharing.js +176 -0
- data/vendor/v8/test/mjsunit/array-construct-transition.js +3 -3
- data/vendor/v8/test/mjsunit/array-literal-transitions.js +10 -10
- data/vendor/v8/test/mjsunit/big-array-literal.js +3 -0
- data/vendor/v8/test/mjsunit/compiler/inline-construct.js +4 -2
- data/vendor/v8/test/mjsunit/debug-liveedit-stack-padding.js +88 -0
- data/vendor/v8/test/mjsunit/elements-kind.js +4 -4
- data/vendor/v8/test/mjsunit/elements-transition-hoisting.js +2 -2
- data/vendor/v8/test/mjsunit/elements-transition.js +5 -5
- data/vendor/v8/test/mjsunit/error-constructors.js +68 -33
- data/vendor/v8/test/mjsunit/harmony/proxies.js +14 -6
- data/vendor/v8/test/mjsunit/mjsunit.status +1 -0
- data/vendor/v8/test/mjsunit/packed-elements.js +112 -0
- data/vendor/v8/test/mjsunit/regexp-capture-3.js +6 -0
- data/vendor/v8/test/mjsunit/regexp-global.js +132 -0
- data/vendor/v8/test/mjsunit/regexp.js +11 -0
- data/vendor/v8/test/mjsunit/regress/regress-117409.js +52 -0
- data/vendor/v8/test/mjsunit/regress/regress-126412.js +33 -0
- data/vendor/v8/test/mjsunit/regress/regress-128018.js +35 -0
- data/vendor/v8/test/mjsunit/regress/regress-128146.js +33 -0
- data/vendor/v8/test/mjsunit/regress/regress-1639-2.js +4 -1
- data/vendor/v8/test/mjsunit/regress/regress-1639.js +14 -8
- data/vendor/v8/test/mjsunit/regress/regress-1849.js +3 -3
- data/vendor/v8/test/mjsunit/regress/regress-1878.js +2 -2
- data/vendor/v8/test/mjsunit/regress/regress-2071.js +79 -0
- data/vendor/v8/test/mjsunit/regress/regress-2153.js +32 -0
- data/vendor/v8/test/mjsunit/regress/regress-crbug-122271.js +4 -4
- data/vendor/v8/test/mjsunit/regress/regress-crbug-126414.js +32 -0
- data/vendor/v8/test/mjsunit/regress/regress-smi-only-concat.js +2 -2
- data/vendor/v8/test/mjsunit/regress/regress-transcendental.js +49 -0
- data/vendor/v8/test/mjsunit/stack-traces.js +14 -0
- data/vendor/v8/test/mjsunit/unbox-double-arrays.js +4 -3
- data/vendor/v8/test/test262/testcfg.py +6 -1
- data/vendor/v8/tools/check-static-initializers.sh +11 -3
- data/vendor/v8/tools/fuzz-harness.sh +92 -0
- data/vendor/v8/tools/grokdump.py +658 -67
- data/vendor/v8/tools/gyp/v8.gyp +21 -39
- data/vendor/v8/tools/js2c.py +3 -3
- data/vendor/v8/tools/jsmin.py +2 -2
- data/vendor/v8/tools/presubmit.py +2 -1
- data/vendor/v8/tools/test-wrapper-gypbuild.py +25 -11
- metadata +624 -612
@@ -1868,10 +1868,12 @@ void MacroAssembler::CompareRoot(Register obj,
|
|
1868
1868
|
void MacroAssembler::CheckFastElements(Register map,
|
1869
1869
|
Register scratch,
|
1870
1870
|
Label* fail) {
|
1871
|
-
STATIC_ASSERT(
|
1872
|
-
STATIC_ASSERT(
|
1871
|
+
STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
|
1872
|
+
STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
|
1873
|
+
STATIC_ASSERT(FAST_ELEMENTS == 2);
|
1874
|
+
STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3);
|
1873
1875
|
ldrb(scratch, FieldMemOperand(map, Map::kBitField2Offset));
|
1874
|
-
cmp(scratch, Operand(Map::
|
1876
|
+
cmp(scratch, Operand(Map::kMaximumBitField2FastHoleyElementValue));
|
1875
1877
|
b(hi, fail);
|
1876
1878
|
}
|
1877
1879
|
|
@@ -1879,22 +1881,25 @@ void MacroAssembler::CheckFastElements(Register map,
|
|
1879
1881
|
void MacroAssembler::CheckFastObjectElements(Register map,
|
1880
1882
|
Register scratch,
|
1881
1883
|
Label* fail) {
|
1882
|
-
STATIC_ASSERT(
|
1883
|
-
STATIC_ASSERT(
|
1884
|
+
STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
|
1885
|
+
STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
|
1886
|
+
STATIC_ASSERT(FAST_ELEMENTS == 2);
|
1887
|
+
STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3);
|
1884
1888
|
ldrb(scratch, FieldMemOperand(map, Map::kBitField2Offset));
|
1885
|
-
cmp(scratch, Operand(Map::
|
1889
|
+
cmp(scratch, Operand(Map::kMaximumBitField2FastHoleySmiElementValue));
|
1886
1890
|
b(ls, fail);
|
1887
|
-
cmp(scratch, Operand(Map::
|
1891
|
+
cmp(scratch, Operand(Map::kMaximumBitField2FastHoleyElementValue));
|
1888
1892
|
b(hi, fail);
|
1889
1893
|
}
|
1890
1894
|
|
1891
1895
|
|
1892
|
-
void MacroAssembler::
|
1893
|
-
|
1894
|
-
|
1895
|
-
STATIC_ASSERT(
|
1896
|
+
void MacroAssembler::CheckFastSmiElements(Register map,
|
1897
|
+
Register scratch,
|
1898
|
+
Label* fail) {
|
1899
|
+
STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
|
1900
|
+
STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
|
1896
1901
|
ldrb(scratch, FieldMemOperand(map, Map::kBitField2Offset));
|
1897
|
-
cmp(scratch, Operand(Map::
|
1902
|
+
cmp(scratch, Operand(Map::kMaximumBitField2FastHoleySmiElementValue));
|
1898
1903
|
b(hi, fail);
|
1899
1904
|
}
|
1900
1905
|
|
@@ -1997,22 +2002,17 @@ void MacroAssembler::CompareMap(Register obj,
|
|
1997
2002
|
ldr(scratch, FieldMemOperand(obj, HeapObject::kMapOffset));
|
1998
2003
|
cmp(scratch, Operand(map));
|
1999
2004
|
if (mode == ALLOW_ELEMENT_TRANSITION_MAPS) {
|
2000
|
-
|
2001
|
-
|
2002
|
-
|
2003
|
-
|
2004
|
-
|
2005
|
-
|
2006
|
-
|
2007
|
-
|
2008
|
-
|
2009
|
-
|
2010
|
-
|
2011
|
-
ASSERT(transitioned_double_map == NULL ||
|
2012
|
-
map->elements_kind() == FAST_SMI_ONLY_ELEMENTS);
|
2013
|
-
if (transitioned_double_map != NULL) {
|
2014
|
-
b(eq, early_success);
|
2015
|
-
cmp(scratch, Operand(Handle<Map>(transitioned_double_map)));
|
2005
|
+
ElementsKind kind = map->elements_kind();
|
2006
|
+
if (IsFastElementsKind(kind)) {
|
2007
|
+
bool packed = IsFastPackedElementsKind(kind);
|
2008
|
+
Map* current_map = *map;
|
2009
|
+
while (CanTransitionToMoreGeneralFastElementsKind(kind, packed)) {
|
2010
|
+
kind = GetNextMoreGeneralFastElementsKind(kind, packed);
|
2011
|
+
current_map = current_map->LookupElementsTransitionMap(kind, NULL);
|
2012
|
+
if (!current_map) break;
|
2013
|
+
b(eq, early_success);
|
2014
|
+
cmp(scratch, Operand(Handle<Map>(current_map)));
|
2015
|
+
}
|
2016
2016
|
}
|
2017
2017
|
}
|
2018
2018
|
}
|
@@ -2865,28 +2865,38 @@ void MacroAssembler::LoadTransitionedArrayMapConditional(
|
|
2865
2865
|
ldr(scratch, FieldMemOperand(scratch, GlobalObject::kGlobalContextOffset));
|
2866
2866
|
|
2867
2867
|
// Check that the function's map is the same as the expected cached map.
|
2868
|
-
|
2869
|
-
|
2870
|
-
|
2871
|
-
|
2868
|
+
ldr(scratch,
|
2869
|
+
MemOperand(scratch,
|
2870
|
+
Context::SlotOffset(Context::JS_ARRAY_MAPS_INDEX)));
|
2871
|
+
size_t offset = expected_kind * kPointerSize +
|
2872
|
+
FixedArrayBase::kHeaderSize;
|
2873
|
+
cmp(map_in_out, scratch);
|
2872
2874
|
b(ne, no_map_match);
|
2873
2875
|
|
2874
2876
|
// Use the transitioned cached map.
|
2875
|
-
|
2876
|
-
|
2877
|
-
ldr(map_in_out,
|
2877
|
+
offset = transitioned_kind * kPointerSize +
|
2878
|
+
FixedArrayBase::kHeaderSize;
|
2879
|
+
ldr(map_in_out, FieldMemOperand(scratch, offset));
|
2878
2880
|
}
|
2879
2881
|
|
2880
2882
|
|
2881
2883
|
void MacroAssembler::LoadInitialArrayMap(
|
2882
|
-
Register function_in, Register scratch,
|
2884
|
+
Register function_in, Register scratch,
|
2885
|
+
Register map_out, bool can_have_holes) {
|
2883
2886
|
ASSERT(!function_in.is(map_out));
|
2884
2887
|
Label done;
|
2885
2888
|
ldr(map_out, FieldMemOperand(function_in,
|
2886
2889
|
JSFunction::kPrototypeOrInitialMapOffset));
|
2887
2890
|
if (!FLAG_smi_only_arrays) {
|
2888
|
-
|
2889
|
-
|
2891
|
+
ElementsKind kind = can_have_holes ? FAST_HOLEY_ELEMENTS : FAST_ELEMENTS;
|
2892
|
+
LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
|
2893
|
+
kind,
|
2894
|
+
map_out,
|
2895
|
+
scratch,
|
2896
|
+
&done);
|
2897
|
+
} else if (can_have_holes) {
|
2898
|
+
LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
|
2899
|
+
FAST_HOLEY_SMI_ELEMENTS,
|
2890
2900
|
map_out,
|
2891
2901
|
scratch,
|
2892
2902
|
&done);
|
@@ -3738,7 +3748,7 @@ CodePatcher::CodePatcher(byte* address, int instructions)
|
|
3738
3748
|
: address_(address),
|
3739
3749
|
instructions_(instructions),
|
3740
3750
|
size_(instructions * Assembler::kInstrSize),
|
3741
|
-
masm_(
|
3751
|
+
masm_(NULL, address, size_ + Assembler::kGap) {
|
3742
3752
|
// Create a new macro assembler pointing to the address of the code to patch.
|
3743
3753
|
// The size is adjusted with kGap on order for the assembler to generate size
|
3744
3754
|
// bytes of instructions without failing with buffer size constraints.
|
@@ -512,7 +512,8 @@ class MacroAssembler: public Assembler {
|
|
512
512
|
// Load the initial map for new Arrays from a JSFunction.
|
513
513
|
void LoadInitialArrayMap(Register function_in,
|
514
514
|
Register scratch,
|
515
|
-
Register map_out
|
515
|
+
Register map_out,
|
516
|
+
bool can_have_holes);
|
516
517
|
|
517
518
|
void LoadGlobalFunction(int index, Register function);
|
518
519
|
|
@@ -802,9 +803,9 @@ class MacroAssembler: public Assembler {
|
|
802
803
|
|
803
804
|
// Check if a map for a JSObject indicates that the object has fast smi only
|
804
805
|
// elements. Jump to the specified label if it does not.
|
805
|
-
void
|
806
|
-
|
807
|
-
|
806
|
+
void CheckFastSmiElements(Register map,
|
807
|
+
Register scratch,
|
808
|
+
Label* fail);
|
808
809
|
|
809
810
|
// Check to see if maybe_number can be stored as a double in
|
810
811
|
// FastDoubleElements. If it can, store it at the index specified by key in
|
@@ -1,4 +1,4 @@
|
|
1
|
-
// Copyright
|
1
|
+
// Copyright 2012 the V8 project authors. All rights reserved.
|
2
2
|
// Redistribution and use in source and binary forms, with or without
|
3
3
|
// modification, are permitted provided that the following conditions are
|
4
4
|
// met:
|
@@ -43,45 +43,49 @@ namespace internal {
|
|
43
43
|
#ifndef V8_INTERPRETED_REGEXP
|
44
44
|
/*
|
45
45
|
* This assembler uses the following register assignment convention
|
46
|
+
* - r4 : Temporarily stores the index of capture start after a matching pass
|
47
|
+
* for a global regexp.
|
46
48
|
* - r5 : Pointer to current code object (Code*) including heap object tag.
|
47
49
|
* - r6 : Current position in input, as negative offset from end of string.
|
48
50
|
* Please notice that this is the byte offset, not the character offset!
|
49
51
|
* - r7 : Currently loaded character. Must be loaded using
|
50
52
|
* LoadCurrentCharacter before using any of the dispatch methods.
|
51
|
-
* - r8 :
|
53
|
+
* - r8 : Points to tip of backtrack stack
|
52
54
|
* - r9 : Unused, might be used by C code and expected unchanged.
|
53
55
|
* - r10 : End of input (points to byte after last character in input).
|
54
56
|
* - r11 : Frame pointer. Used to access arguments, local variables and
|
55
57
|
* RegExp registers.
|
56
58
|
* - r12 : IP register, used by assembler. Very volatile.
|
57
|
-
* - r13/sp :
|
59
|
+
* - r13/sp : Points to tip of C stack.
|
58
60
|
*
|
59
61
|
* The remaining registers are free for computations.
|
60
62
|
* Each call to a public method should retain this convention.
|
61
63
|
*
|
62
64
|
* The stack will have the following structure:
|
63
|
-
* - fp[
|
64
|
-
* - fp[
|
65
|
-
*
|
66
|
-
* - fp[
|
67
|
-
*
|
65
|
+
* - fp[56] Isolate* isolate (address of the current isolate)
|
66
|
+
* - fp[52] direct_call (if 1, direct call from JavaScript code,
|
67
|
+
* if 0, call through the runtime system).
|
68
|
+
* - fp[48] stack_area_base (high end of the memory area to use as
|
69
|
+
* backtracking stack).
|
70
|
+
* - fp[44] capture array size (may fit multiple sets of matches)
|
68
71
|
* - fp[40] int* capture_array (int[num_saved_registers_], for output).
|
69
72
|
* - fp[36] secondary link/return address used by native call.
|
70
73
|
* --- sp when called ---
|
71
|
-
* - fp[32] return address
|
72
|
-
* - fp[28] old frame pointer
|
74
|
+
* - fp[32] return address (lr).
|
75
|
+
* - fp[28] old frame pointer (r11).
|
73
76
|
* - fp[0..24] backup of registers r4..r10.
|
74
77
|
* --- frame pointer ----
|
75
|
-
* - fp[-4] end of input (
|
76
|
-
* - fp[-8] start of input (
|
78
|
+
* - fp[-4] end of input (address of end of string).
|
79
|
+
* - fp[-8] start of input (address of first character in string).
|
77
80
|
* - fp[-12] start index (character index of start).
|
78
81
|
* - fp[-16] void* input_string (location of a handle containing the string).
|
79
|
-
* - fp[-20]
|
82
|
+
* - fp[-20] success counter (only for global regexps to count matches).
|
83
|
+
* - fp[-24] Offset of location before start of input (effectively character
|
80
84
|
* position -1). Used to initialize capture registers to a
|
81
85
|
* non-position.
|
82
|
-
* - fp[-
|
86
|
+
* - fp[-28] At start (if 1, we are starting at the start of the
|
83
87
|
* string, otherwise 0)
|
84
|
-
* - fp[-
|
88
|
+
* - fp[-32] register 0 (Only positions must be stored in the first
|
85
89
|
* - register 1 num_saved_registers_ registers)
|
86
90
|
* - ...
|
87
91
|
* - register num_registers-1
|
@@ -197,9 +201,9 @@ void RegExpMacroAssemblerARM::CheckCharacterGT(uc16 limit, Label* on_greater) {
|
|
197
201
|
void RegExpMacroAssemblerARM::CheckAtStart(Label* on_at_start) {
|
198
202
|
Label not_at_start;
|
199
203
|
// Did we start the match at the start of the string at all?
|
200
|
-
__ ldr(r0, MemOperand(frame_pointer(),
|
204
|
+
__ ldr(r0, MemOperand(frame_pointer(), kStartIndex));
|
201
205
|
__ cmp(r0, Operand(0, RelocInfo::NONE));
|
202
|
-
BranchOrBacktrack(
|
206
|
+
BranchOrBacktrack(ne, ¬_at_start);
|
203
207
|
|
204
208
|
// If we did, are we still at the start of the input?
|
205
209
|
__ ldr(r1, MemOperand(frame_pointer(), kInputStart));
|
@@ -212,9 +216,9 @@ void RegExpMacroAssemblerARM::CheckAtStart(Label* on_at_start) {
|
|
212
216
|
|
213
217
|
void RegExpMacroAssemblerARM::CheckNotAtStart(Label* on_not_at_start) {
|
214
218
|
// Did we start the match at the start of the string at all?
|
215
|
-
__ ldr(r0, MemOperand(frame_pointer(),
|
219
|
+
__ ldr(r0, MemOperand(frame_pointer(), kStartIndex));
|
216
220
|
__ cmp(r0, Operand(0, RelocInfo::NONE));
|
217
|
-
BranchOrBacktrack(
|
221
|
+
BranchOrBacktrack(ne, on_not_at_start);
|
218
222
|
// If we did, are we still at the start of the input?
|
219
223
|
__ ldr(r1, MemOperand(frame_pointer(), kInputStart));
|
220
224
|
__ add(r0, end_of_input_address(), Operand(current_input_offset()));
|
@@ -655,6 +659,7 @@ void RegExpMacroAssemblerARM::Fail() {
|
|
655
659
|
|
656
660
|
|
657
661
|
Handle<HeapObject> RegExpMacroAssemblerARM::GetCode(Handle<String> source) {
|
662
|
+
Label return_r0;
|
658
663
|
// Finalize code - write the entry point code now we know how many
|
659
664
|
// registers we need.
|
660
665
|
|
@@ -678,8 +683,9 @@ Handle<HeapObject> RegExpMacroAssemblerARM::GetCode(Handle<String> source) {
|
|
678
683
|
// Set frame pointer in space for it if this is not a direct call
|
679
684
|
// from generated code.
|
680
685
|
__ add(frame_pointer(), sp, Operand(4 * kPointerSize));
|
686
|
+
__ mov(r0, Operand(0, RelocInfo::NONE));
|
687
|
+
__ push(r0); // Make room for success counter and initialize it to 0.
|
681
688
|
__ push(r0); // Make room for "position - 1" constant (value is irrelevant).
|
682
|
-
__ push(r0); // Make room for "at start" constant (value is irrelevant).
|
683
689
|
// Check if we have space on the stack for registers.
|
684
690
|
Label stack_limit_hit;
|
685
691
|
Label stack_ok;
|
@@ -698,13 +704,13 @@ Handle<HeapObject> RegExpMacroAssemblerARM::GetCode(Handle<String> source) {
|
|
698
704
|
// Exit with OutOfMemory exception. There is not enough space on the stack
|
699
705
|
// for our working registers.
|
700
706
|
__ mov(r0, Operand(EXCEPTION));
|
701
|
-
__ jmp(&
|
707
|
+
__ jmp(&return_r0);
|
702
708
|
|
703
709
|
__ bind(&stack_limit_hit);
|
704
710
|
CallCheckStackGuardState(r0);
|
705
711
|
__ cmp(r0, Operand(0, RelocInfo::NONE));
|
706
712
|
// If returned value is non-zero, we exit with the returned value as result.
|
707
|
-
__ b(ne, &
|
713
|
+
__ b(ne, &return_r0);
|
708
714
|
|
709
715
|
__ bind(&stack_ok);
|
710
716
|
|
@@ -725,41 +731,45 @@ Handle<HeapObject> RegExpMacroAssemblerARM::GetCode(Handle<String> source) {
|
|
725
731
|
// position registers.
|
726
732
|
__ str(r0, MemOperand(frame_pointer(), kInputStartMinusOne));
|
727
733
|
|
728
|
-
//
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
__
|
734
|
+
// Initialize code pointer register
|
735
|
+
__ mov(code_pointer(), Operand(masm_->CodeObject()));
|
736
|
+
|
737
|
+
Label load_char_start_regexp, start_regexp;
|
738
|
+
// Load newline if index is at start, previous character otherwise.
|
739
|
+
__ cmp(r1, Operand(0, RelocInfo::NONE));
|
740
|
+
__ b(ne, &load_char_start_regexp);
|
741
|
+
__ mov(current_character(), Operand('\n'), LeaveCC, eq);
|
742
|
+
__ jmp(&start_regexp);
|
743
|
+
|
744
|
+
// Global regexp restarts matching here.
|
745
|
+
__ bind(&load_char_start_regexp);
|
746
|
+
// Load previous char as initial value of current character register.
|
747
|
+
LoadCurrentCharacterUnchecked(-1, 1);
|
748
|
+
__ bind(&start_regexp);
|
734
749
|
|
750
|
+
// Initialize on-stack registers.
|
735
751
|
if (num_saved_registers_ > 0) { // Always is, if generated from a regexp.
|
736
752
|
// Fill saved registers with initial value = start offset - 1
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
|
753
|
+
if (num_saved_registers_ > 8) {
|
754
|
+
// Address of register 0.
|
755
|
+
__ add(r1, frame_pointer(), Operand(kRegisterZero));
|
756
|
+
__ mov(r2, Operand(num_saved_registers_));
|
757
|
+
Label init_loop;
|
758
|
+
__ bind(&init_loop);
|
759
|
+
__ str(r0, MemOperand(r1, kPointerSize, NegPostIndex));
|
760
|
+
__ sub(r2, r2, Operand(1), SetCC);
|
761
|
+
__ b(ne, &init_loop);
|
762
|
+
} else {
|
763
|
+
for (int i = 0; i < num_saved_registers_; i++) {
|
764
|
+
__ str(r0, register_location(i));
|
765
|
+
}
|
766
|
+
}
|
746
767
|
}
|
747
768
|
|
748
769
|
// Initialize backtrack stack pointer.
|
749
770
|
__ ldr(backtrack_stackpointer(), MemOperand(frame_pointer(), kStackHighEnd));
|
750
|
-
// Initialize code pointer register
|
751
|
-
__ mov(code_pointer(), Operand(masm_->CodeObject()));
|
752
|
-
// Load previous char as initial value of current character register.
|
753
|
-
Label at_start;
|
754
|
-
__ ldr(r0, MemOperand(frame_pointer(), kAtStart));
|
755
|
-
__ cmp(r0, Operand(0, RelocInfo::NONE));
|
756
|
-
__ b(ne, &at_start);
|
757
|
-
LoadCurrentCharacterUnchecked(-1, 1); // Load previous char.
|
758
|
-
__ jmp(&start_label_);
|
759
|
-
__ bind(&at_start);
|
760
|
-
__ mov(current_character(), Operand('\n'));
|
761
|
-
__ jmp(&start_label_);
|
762
771
|
|
772
|
+
__ jmp(&start_label_);
|
763
773
|
|
764
774
|
// Exit code:
|
765
775
|
if (success_label_.is_linked()) {
|
@@ -786,6 +796,10 @@ Handle<HeapObject> RegExpMacroAssemblerARM::GetCode(Handle<String> source) {
|
|
786
796
|
for (int i = 0; i < num_saved_registers_; i += 2) {
|
787
797
|
__ ldr(r2, register_location(i));
|
788
798
|
__ ldr(r3, register_location(i + 1));
|
799
|
+
if (global()) {
|
800
|
+
// Keep capture start in r4 for the zero-length check later.
|
801
|
+
__ mov(r4, r2);
|
802
|
+
}
|
789
803
|
if (mode_ == UC16) {
|
790
804
|
__ add(r2, r1, Operand(r2, ASR, 1));
|
791
805
|
__ add(r3, r1, Operand(r3, ASR, 1));
|
@@ -797,10 +811,54 @@ Handle<HeapObject> RegExpMacroAssemblerARM::GetCode(Handle<String> source) {
|
|
797
811
|
__ str(r3, MemOperand(r0, kPointerSize, PostIndex));
|
798
812
|
}
|
799
813
|
}
|
800
|
-
|
814
|
+
|
815
|
+
if (global()) {
|
816
|
+
// Restart matching if the regular expression is flagged as global.
|
817
|
+
__ ldr(r0, MemOperand(frame_pointer(), kSuccessfulCaptures));
|
818
|
+
__ ldr(r1, MemOperand(frame_pointer(), kNumOutputRegisters));
|
819
|
+
__ ldr(r2, MemOperand(frame_pointer(), kRegisterOutput));
|
820
|
+
// Increment success counter.
|
821
|
+
__ add(r0, r0, Operand(1));
|
822
|
+
__ str(r0, MemOperand(frame_pointer(), kSuccessfulCaptures));
|
823
|
+
// Capture results have been stored, so the number of remaining global
|
824
|
+
// output registers is reduced by the number of stored captures.
|
825
|
+
__ sub(r1, r1, Operand(num_saved_registers_));
|
826
|
+
// Check whether we have enough room for another set of capture results.
|
827
|
+
__ cmp(r1, Operand(num_saved_registers_));
|
828
|
+
__ b(lt, &return_r0);
|
829
|
+
|
830
|
+
__ str(r1, MemOperand(frame_pointer(), kNumOutputRegisters));
|
831
|
+
// Advance the location for output.
|
832
|
+
__ add(r2, r2, Operand(num_saved_registers_ * kPointerSize));
|
833
|
+
__ str(r2, MemOperand(frame_pointer(), kRegisterOutput));
|
834
|
+
|
835
|
+
// Prepare r0 to initialize registers with its value in the next run.
|
836
|
+
__ ldr(r0, MemOperand(frame_pointer(), kInputStartMinusOne));
|
837
|
+
// Special case for zero-length matches.
|
838
|
+
// r4: capture start index
|
839
|
+
__ cmp(current_input_offset(), r4);
|
840
|
+
// Not a zero-length match, restart.
|
841
|
+
__ b(ne, &load_char_start_regexp);
|
842
|
+
// Offset from the end is zero if we already reached the end.
|
843
|
+
__ cmp(current_input_offset(), Operand(0));
|
844
|
+
__ b(eq, &exit_label_);
|
845
|
+
// Advance current position after a zero-length match.
|
846
|
+
__ add(current_input_offset(),
|
847
|
+
current_input_offset(),
|
848
|
+
Operand((mode_ == UC16) ? 2 : 1));
|
849
|
+
__ b(&load_char_start_regexp);
|
850
|
+
} else {
|
851
|
+
__ mov(r0, Operand(SUCCESS));
|
852
|
+
}
|
801
853
|
}
|
854
|
+
|
802
855
|
// Exit and return r0
|
803
856
|
__ bind(&exit_label_);
|
857
|
+
if (global()) {
|
858
|
+
__ ldr(r0, MemOperand(frame_pointer(), kSuccessfulCaptures));
|
859
|
+
}
|
860
|
+
|
861
|
+
__ bind(&return_r0);
|
804
862
|
// Skip sp past regexp registers and local variables..
|
805
863
|
__ mov(sp, frame_pointer());
|
806
864
|
// Restore registers r4..r11 and return (restoring lr to pc).
|
@@ -822,7 +880,7 @@ Handle<HeapObject> RegExpMacroAssemblerARM::GetCode(Handle<String> source) {
|
|
822
880
|
__ cmp(r0, Operand(0, RelocInfo::NONE));
|
823
881
|
// If returning non-zero, we should end execution with the given
|
824
882
|
// result as return value.
|
825
|
-
__ b(ne, &
|
883
|
+
__ b(ne, &return_r0);
|
826
884
|
|
827
885
|
// String might have moved: Reload end of string from frame.
|
828
886
|
__ ldr(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd));
|
@@ -859,7 +917,7 @@ Handle<HeapObject> RegExpMacroAssemblerARM::GetCode(Handle<String> source) {
|
|
859
917
|
__ bind(&exit_with_exception);
|
860
918
|
// Exit with Result EXCEPTION(-1) to signal thrown exception.
|
861
919
|
__ mov(r0, Operand(EXCEPTION));
|
862
|
-
__ jmp(&
|
920
|
+
__ jmp(&return_r0);
|
863
921
|
}
|
864
922
|
|
865
923
|
CodeDesc code_desc;
|
@@ -1014,8 +1072,9 @@ void RegExpMacroAssemblerARM::SetRegister(int register_index, int to) {
|
|
1014
1072
|
}
|
1015
1073
|
|
1016
1074
|
|
1017
|
-
|
1075
|
+
bool RegExpMacroAssemblerARM::Succeed() {
|
1018
1076
|
__ jmp(&success_label_);
|
1077
|
+
return global();
|
1019
1078
|
}
|
1020
1079
|
|
1021
1080
|
|
@@ -1307,8 +1366,9 @@ void RegExpMacroAssemblerARM::LoadCurrentCharacterUnchecked(int cp_offset,
|
|
1307
1366
|
int characters) {
|
1308
1367
|
Register offset = current_input_offset();
|
1309
1368
|
if (cp_offset != 0) {
|
1310
|
-
|
1311
|
-
|
1369
|
+
// r4 is not being used to store the capture start index at this point.
|
1370
|
+
__ add(r4, current_input_offset(), Operand(cp_offset * char_size()));
|
1371
|
+
offset = r4;
|
1312
1372
|
}
|
1313
1373
|
// The ldr, str, ldrh, strh instructions can do unaligned accesses, if the CPU
|
1314
1374
|
// and the operating system running on the target allow it.
|