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
@@ -2023,8 +2023,9 @@ LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) {
|
|
2023
2023
|
|
2024
2024
|
LInstruction* LChunkBuilder::DoTransitionElementsKind(
|
2025
2025
|
HTransitionElementsKind* instr) {
|
2026
|
-
|
2027
|
-
|
2026
|
+
ElementsKind from_kind = instr->original_map()->elements_kind();
|
2027
|
+
ElementsKind to_kind = instr->transitioned_map()->elements_kind();
|
2028
|
+
if (IsSimpleMapChangeTransition(from_kind, to_kind)) {
|
2028
2029
|
LOperand* object = UseRegister(instr->object());
|
2029
2030
|
LOperand* new_map_reg = TempRegister();
|
2030
2031
|
LTransitionElementsKind* result =
|
@@ -2045,16 +2046,28 @@ LInstruction* LChunkBuilder::DoTransitionElementsKind(
|
|
2045
2046
|
|
2046
2047
|
LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
|
2047
2048
|
bool needs_write_barrier = instr->NeedsWriteBarrier();
|
2048
|
-
|
2049
|
-
|
2050
|
-
|
2051
|
-
|
2049
|
+
bool needs_write_barrier_for_map = !instr->transition().is_null() &&
|
2050
|
+
instr->NeedsWriteBarrierForMap();
|
2051
|
+
|
2052
|
+
LOperand* obj;
|
2053
|
+
if (needs_write_barrier) {
|
2054
|
+
obj = instr->is_in_object()
|
2055
|
+
? UseRegister(instr->object())
|
2056
|
+
: UseTempRegister(instr->object());
|
2057
|
+
} else {
|
2058
|
+
obj = needs_write_barrier_for_map
|
2059
|
+
? UseRegister(instr->object())
|
2060
|
+
: UseRegisterAtStart(instr->object());
|
2061
|
+
}
|
2052
2062
|
|
2053
2063
|
LOperand* val = needs_write_barrier
|
2054
2064
|
? UseTempRegister(instr->value())
|
2055
2065
|
: UseRegister(instr->value());
|
2056
2066
|
|
2057
|
-
|
2067
|
+
// We need a temporary register for write barrier of the map field.
|
2068
|
+
LOperand* temp = needs_write_barrier_for_map ? TempRegister() : NULL;
|
2069
|
+
|
2070
|
+
return new(zone()) LStoreNamedField(obj, val, temp);
|
2058
2071
|
}
|
2059
2072
|
|
2060
2073
|
|
@@ -1201,6 +1201,7 @@ class LLoadKeyedFastElement: public LTemplateInstruction<1, 2, 0> {
|
|
1201
1201
|
|
1202
1202
|
LOperand* elements() { return inputs_[0]; }
|
1203
1203
|
LOperand* key() { return inputs_[1]; }
|
1204
|
+
uint32_t additional_index() const { return hydrogen()->index_offset(); }
|
1204
1205
|
};
|
1205
1206
|
|
1206
1207
|
|
@@ -1217,13 +1218,14 @@ class LLoadKeyedFastDoubleElement: public LTemplateInstruction<1, 2, 0> {
|
|
1217
1218
|
|
1218
1219
|
LOperand* elements() { return inputs_[0]; }
|
1219
1220
|
LOperand* key() { return inputs_[1]; }
|
1221
|
+
uint32_t additional_index() const { return hydrogen()->index_offset(); }
|
1220
1222
|
};
|
1221
1223
|
|
1222
1224
|
|
1223
1225
|
class LLoadKeyedSpecializedArrayElement: public LTemplateInstruction<1, 2, 0> {
|
1224
1226
|
public:
|
1225
|
-
|
1226
|
-
|
1227
|
+
LLoadKeyedSpecializedArrayElement(LOperand* external_pointer,
|
1228
|
+
LOperand* key) {
|
1227
1229
|
inputs_[0] = external_pointer;
|
1228
1230
|
inputs_[1] = key;
|
1229
1231
|
}
|
@@ -1237,6 +1239,7 @@ class LLoadKeyedSpecializedArrayElement: public LTemplateInstruction<1, 2, 0> {
|
|
1237
1239
|
ElementsKind elements_kind() const {
|
1238
1240
|
return hydrogen()->elements_kind();
|
1239
1241
|
}
|
1242
|
+
uint32_t additional_index() const { return hydrogen()->index_offset(); }
|
1240
1243
|
};
|
1241
1244
|
|
1242
1245
|
|
@@ -1647,11 +1650,12 @@ class LSmiUntag: public LTemplateInstruction<1, 1, 0> {
|
|
1647
1650
|
};
|
1648
1651
|
|
1649
1652
|
|
1650
|
-
class LStoreNamedField: public LTemplateInstruction<0, 2,
|
1653
|
+
class LStoreNamedField: public LTemplateInstruction<0, 2, 1> {
|
1651
1654
|
public:
|
1652
|
-
LStoreNamedField(LOperand* obj, LOperand* val) {
|
1655
|
+
LStoreNamedField(LOperand* obj, LOperand* val, LOperand* temp) {
|
1653
1656
|
inputs_[0] = obj;
|
1654
1657
|
inputs_[1] = val;
|
1658
|
+
temps_[0] = temp;
|
1655
1659
|
}
|
1656
1660
|
|
1657
1661
|
DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store-named-field")
|
@@ -1705,6 +1709,7 @@ class LStoreKeyedFastElement: public LTemplateInstruction<0, 3, 0> {
|
|
1705
1709
|
LOperand* object() { return inputs_[0]; }
|
1706
1710
|
LOperand* key() { return inputs_[1]; }
|
1707
1711
|
LOperand* value() { return inputs_[2]; }
|
1712
|
+
uint32_t additional_index() const { return hydrogen()->index_offset(); }
|
1708
1713
|
};
|
1709
1714
|
|
1710
1715
|
|
@@ -1727,6 +1732,7 @@ class LStoreKeyedFastDoubleElement: public LTemplateInstruction<0, 3, 0> {
|
|
1727
1732
|
LOperand* elements() { return inputs_[0]; }
|
1728
1733
|
LOperand* key() { return inputs_[1]; }
|
1729
1734
|
LOperand* value() { return inputs_[2]; }
|
1735
|
+
uint32_t additional_index() const { return hydrogen()->index_offset(); }
|
1730
1736
|
|
1731
1737
|
bool NeedsCanonicalization() { return hydrogen()->NeedsCanonicalization(); }
|
1732
1738
|
};
|
@@ -1771,6 +1777,7 @@ class LStoreKeyedSpecializedArrayElement: public LTemplateInstruction<0, 3, 0> {
|
|
1771
1777
|
ElementsKind elements_kind() const {
|
1772
1778
|
return hydrogen()->elements_kind();
|
1773
1779
|
}
|
1780
|
+
uint32_t additional_index() const { return hydrogen()->index_offset(); }
|
1774
1781
|
};
|
1775
1782
|
|
1776
1783
|
|
@@ -3341,33 +3341,39 @@ void MacroAssembler::InitializeFieldsWithFiller(Register start_offset,
|
|
3341
3341
|
void MacroAssembler::CheckFastElements(Register map,
|
3342
3342
|
Register scratch,
|
3343
3343
|
Label* fail) {
|
3344
|
-
STATIC_ASSERT(
|
3345
|
-
STATIC_ASSERT(
|
3344
|
+
STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
|
3345
|
+
STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
|
3346
|
+
STATIC_ASSERT(FAST_ELEMENTS == 2);
|
3347
|
+
STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3);
|
3346
3348
|
lbu(scratch, FieldMemOperand(map, Map::kBitField2Offset));
|
3347
|
-
Branch(fail, hi, scratch,
|
3349
|
+
Branch(fail, hi, scratch,
|
3350
|
+
Operand(Map::kMaximumBitField2FastHoleyElementValue));
|
3348
3351
|
}
|
3349
3352
|
|
3350
3353
|
|
3351
3354
|
void MacroAssembler::CheckFastObjectElements(Register map,
|
3352
3355
|
Register scratch,
|
3353
3356
|
Label* fail) {
|
3354
|
-
STATIC_ASSERT(
|
3355
|
-
STATIC_ASSERT(
|
3357
|
+
STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
|
3358
|
+
STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
|
3359
|
+
STATIC_ASSERT(FAST_ELEMENTS == 2);
|
3360
|
+
STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3);
|
3356
3361
|
lbu(scratch, FieldMemOperand(map, Map::kBitField2Offset));
|
3357
3362
|
Branch(fail, ls, scratch,
|
3358
|
-
Operand(Map::
|
3363
|
+
Operand(Map::kMaximumBitField2FastHoleySmiElementValue));
|
3359
3364
|
Branch(fail, hi, scratch,
|
3360
|
-
Operand(Map::
|
3365
|
+
Operand(Map::kMaximumBitField2FastHoleyElementValue));
|
3361
3366
|
}
|
3362
3367
|
|
3363
3368
|
|
3364
|
-
void MacroAssembler::
|
3365
|
-
|
3366
|
-
|
3367
|
-
STATIC_ASSERT(
|
3369
|
+
void MacroAssembler::CheckFastSmiElements(Register map,
|
3370
|
+
Register scratch,
|
3371
|
+
Label* fail) {
|
3372
|
+
STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
|
3373
|
+
STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
|
3368
3374
|
lbu(scratch, FieldMemOperand(map, Map::kBitField2Offset));
|
3369
3375
|
Branch(fail, hi, scratch,
|
3370
|
-
Operand(Map::
|
3376
|
+
Operand(Map::kMaximumBitField2FastHoleySmiElementValue));
|
3371
3377
|
}
|
3372
3378
|
|
3373
3379
|
|
@@ -3469,22 +3475,17 @@ void MacroAssembler::CompareMapAndBranch(Register obj,
|
|
3469
3475
|
lw(scratch, FieldMemOperand(obj, HeapObject::kMapOffset));
|
3470
3476
|
Operand right = Operand(map);
|
3471
3477
|
if (mode == ALLOW_ELEMENT_TRANSITION_MAPS) {
|
3472
|
-
|
3473
|
-
|
3474
|
-
|
3475
|
-
|
3476
|
-
|
3477
|
-
|
3478
|
-
|
3479
|
-
|
3480
|
-
|
3481
|
-
|
3482
|
-
|
3483
|
-
ASSERT(transitioned_double_map == NULL ||
|
3484
|
-
map->elements_kind() == FAST_SMI_ONLY_ELEMENTS);
|
3485
|
-
if (transitioned_double_map != NULL) {
|
3486
|
-
Branch(early_success, eq, scratch, right);
|
3487
|
-
right = Operand(Handle<Map>(transitioned_double_map));
|
3478
|
+
ElementsKind kind = map->elements_kind();
|
3479
|
+
if (IsFastElementsKind(kind)) {
|
3480
|
+
bool packed = IsFastPackedElementsKind(kind);
|
3481
|
+
Map* current_map = *map;
|
3482
|
+
while (CanTransitionToMoreGeneralFastElementsKind(kind, packed)) {
|
3483
|
+
kind = GetNextMoreGeneralFastElementsKind(kind, packed);
|
3484
|
+
current_map = current_map->LookupElementsTransitionMap(kind, NULL);
|
3485
|
+
if (!current_map) break;
|
3486
|
+
Branch(early_success, eq, scratch, right);
|
3487
|
+
right = Operand(Handle<Map>(current_map));
|
3488
|
+
}
|
3488
3489
|
}
|
3489
3490
|
}
|
3490
3491
|
|
@@ -4443,27 +4444,37 @@ void MacroAssembler::LoadTransitionedArrayMapConditional(
|
|
4443
4444
|
lw(scratch, FieldMemOperand(scratch, GlobalObject::kGlobalContextOffset));
|
4444
4445
|
|
4445
4446
|
// Check that the function's map is the same as the expected cached map.
|
4446
|
-
|
4447
|
-
|
4448
|
-
|
4449
|
-
|
4447
|
+
lw(scratch,
|
4448
|
+
MemOperand(scratch,
|
4449
|
+
Context::SlotOffset(Context::JS_ARRAY_MAPS_INDEX)));
|
4450
|
+
size_t offset = expected_kind * kPointerSize +
|
4451
|
+
FixedArrayBase::kHeaderSize;
|
4452
|
+
Branch(no_map_match, ne, map_in_out, Operand(scratch));
|
4450
4453
|
|
4451
4454
|
// Use the transitioned cached map.
|
4452
|
-
|
4453
|
-
|
4454
|
-
lw(map_in_out,
|
4455
|
+
offset = transitioned_kind * kPointerSize +
|
4456
|
+
FixedArrayBase::kHeaderSize;
|
4457
|
+
lw(map_in_out, FieldMemOperand(scratch, offset));
|
4455
4458
|
}
|
4456
4459
|
|
4457
4460
|
|
4458
4461
|
void MacroAssembler::LoadInitialArrayMap(
|
4459
|
-
Register function_in, Register scratch,
|
4462
|
+
Register function_in, Register scratch,
|
4463
|
+
Register map_out, bool can_have_holes) {
|
4460
4464
|
ASSERT(!function_in.is(map_out));
|
4461
4465
|
Label done;
|
4462
4466
|
lw(map_out, FieldMemOperand(function_in,
|
4463
4467
|
JSFunction::kPrototypeOrInitialMapOffset));
|
4464
4468
|
if (!FLAG_smi_only_arrays) {
|
4465
|
-
|
4466
|
-
|
4469
|
+
ElementsKind kind = can_have_holes ? FAST_HOLEY_ELEMENTS : FAST_ELEMENTS;
|
4470
|
+
LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
|
4471
|
+
kind,
|
4472
|
+
map_out,
|
4473
|
+
scratch,
|
4474
|
+
&done);
|
4475
|
+
} else if (can_have_holes) {
|
4476
|
+
LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
|
4477
|
+
FAST_HOLEY_SMI_ELEMENTS,
|
4467
4478
|
map_out,
|
4468
4479
|
scratch,
|
4469
4480
|
&done);
|
@@ -5378,7 +5389,7 @@ CodePatcher::CodePatcher(byte* address, int instructions)
|
|
5378
5389
|
: address_(address),
|
5379
5390
|
instructions_(instructions),
|
5380
5391
|
size_(instructions * Assembler::kInstrSize),
|
5381
|
-
masm_(
|
5392
|
+
masm_(NULL, address, size_ + Assembler::kGap) {
|
5382
5393
|
// Create a new macro assembler pointing to the address of the code to patch.
|
5383
5394
|
// The size is adjusted with kGap on order for the assembler to generate size
|
5384
5395
|
// bytes of instructions without failing with buffer size constraints.
|
@@ -819,7 +819,8 @@ class MacroAssembler: public Assembler {
|
|
819
819
|
// Load the initial map for new Arrays from a JSFunction.
|
820
820
|
void LoadInitialArrayMap(Register function_in,
|
821
821
|
Register scratch,
|
822
|
-
Register map_out
|
822
|
+
Register map_out,
|
823
|
+
bool can_have_holes);
|
823
824
|
|
824
825
|
void LoadGlobalFunction(int index, Register function);
|
825
826
|
|
@@ -961,9 +962,9 @@ class MacroAssembler: public Assembler {
|
|
961
962
|
|
962
963
|
// Check if a map for a JSObject indicates that the object has fast smi only
|
963
964
|
// elements. Jump to the specified label if it does not.
|
964
|
-
void
|
965
|
-
|
966
|
-
|
965
|
+
void CheckFastSmiElements(Register map,
|
966
|
+
Register scratch,
|
967
|
+
Label* fail);
|
967
968
|
|
968
969
|
// Check to see if maybe_number can be stored as a double in
|
969
970
|
// FastDoubleElements. If it can, store it at the index specified by key in
|
@@ -43,44 +43,49 @@ namespace internal {
|
|
43
43
|
#ifndef V8_INTERPRETED_REGEXP
|
44
44
|
/*
|
45
45
|
* This assembler uses the following register assignment convention
|
46
|
+
* - t7 : Temporarily stores the index of capture start after a matching pass
|
47
|
+
* for a global regexp.
|
46
48
|
* - t1 : Pointer to current code object (Code*) including heap object tag.
|
47
49
|
* - t2 : 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
|
* - t3 : Currently loaded character. Must be loaded using
|
50
52
|
* LoadCurrentCharacter before using any of the dispatch methods.
|
51
|
-
* - t4 :
|
53
|
+
* - t4 : Points to tip of backtrack stack
|
52
54
|
* - t5 : Unused.
|
53
55
|
* - t6 : End of input (points to byte after last character in input).
|
54
56
|
* - fp : Frame pointer. Used to access arguments, local variables and
|
55
57
|
* RegExp registers.
|
56
|
-
* - sp :
|
58
|
+
* - sp : Points to tip of C stack.
|
57
59
|
*
|
58
60
|
* The remaining registers are free for computations.
|
59
61
|
* Each call to a public method should retain this convention.
|
60
62
|
*
|
61
63
|
* The stack will have the following structure:
|
62
64
|
*
|
63
|
-
* - fp[
|
65
|
+
* - fp[64] Isolate* isolate (address of the current isolate)
|
66
|
+
* - fp[60] direct_call (if 1, direct call from JavaScript code,
|
64
67
|
* if 0, call through the runtime system).
|
65
|
-
* - fp[
|
68
|
+
* - fp[56] stack_area_base (High end of the memory area to use as
|
66
69
|
* backtracking stack).
|
70
|
+
* - fp[52] capture array size (may fit multiple sets of matches)
|
67
71
|
* - fp[48] int* capture_array (int[num_saved_registers_], for output).
|
68
72
|
* - fp[44] secondary link/return address used by native call.
|
69
73
|
* --- sp when called ---
|
70
|
-
* - fp[40] return address
|
71
|
-
* - fp[36] old frame pointer
|
74
|
+
* - fp[40] return address (lr).
|
75
|
+
* - fp[36] old frame pointer (r11).
|
72
76
|
* - fp[0..32] backup of registers s0..s7.
|
73
77
|
* --- frame pointer ----
|
74
|
-
* - fp[-4] end of input (
|
75
|
-
* - 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).
|
76
80
|
* - fp[-12] start index (character index of start).
|
77
81
|
* - fp[-16] void* input_string (location of a handle containing the string).
|
78
|
-
* - 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
|
79
84
|
* position -1). Used to initialize capture registers to a
|
80
85
|
* non-position.
|
81
|
-
* - fp[-
|
86
|
+
* - fp[-28] At start (if 1, we are starting at the start of the
|
82
87
|
* string, otherwise 0)
|
83
|
-
* - fp[-
|
88
|
+
* - fp[-32] register 0 (Only positions must be stored in the first
|
84
89
|
* - register 1 num_saved_registers_ registers)
|
85
90
|
* - ...
|
86
91
|
* - register num_registers-1
|
@@ -201,8 +206,8 @@ void RegExpMacroAssemblerMIPS::CheckCharacterGT(uc16 limit, Label* on_greater) {
|
|
201
206
|
void RegExpMacroAssemblerMIPS::CheckAtStart(Label* on_at_start) {
|
202
207
|
Label not_at_start;
|
203
208
|
// Did we start the match at the start of the string at all?
|
204
|
-
__ lw(a0, MemOperand(frame_pointer(),
|
205
|
-
BranchOrBacktrack(¬_at_start,
|
209
|
+
__ lw(a0, MemOperand(frame_pointer(), kStartIndex));
|
210
|
+
BranchOrBacktrack(¬_at_start, ne, a0, Operand(zero_reg));
|
206
211
|
|
207
212
|
// If we did, are we still at the start of the input?
|
208
213
|
__ lw(a1, MemOperand(frame_pointer(), kInputStart));
|
@@ -214,8 +219,8 @@ void RegExpMacroAssemblerMIPS::CheckAtStart(Label* on_at_start) {
|
|
214
219
|
|
215
220
|
void RegExpMacroAssemblerMIPS::CheckNotAtStart(Label* on_not_at_start) {
|
216
221
|
// Did we start the match at the start of the string at all?
|
217
|
-
__ lw(a0, MemOperand(frame_pointer(),
|
218
|
-
BranchOrBacktrack(on_not_at_start,
|
222
|
+
__ lw(a0, MemOperand(frame_pointer(), kStartIndex));
|
223
|
+
BranchOrBacktrack(on_not_at_start, ne, a0, Operand(zero_reg));
|
219
224
|
// If we did, are we still at the start of the input?
|
220
225
|
__ lw(a1, MemOperand(frame_pointer(), kInputStart));
|
221
226
|
__ Addu(a0, end_of_input_address(), Operand(current_input_offset()));
|
@@ -640,6 +645,7 @@ void RegExpMacroAssemblerMIPS::Fail() {
|
|
640
645
|
|
641
646
|
|
642
647
|
Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
|
648
|
+
Label return_v0;
|
643
649
|
if (masm_->has_exception()) {
|
644
650
|
// If the code gets corrupted due to long regular expressions and lack of
|
645
651
|
// space on trampolines, an internal exception flag is set. If this case
|
@@ -669,8 +675,9 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
|
|
669
675
|
// Set frame pointer in space for it if this is not a direct call
|
670
676
|
// from generated code.
|
671
677
|
__ Addu(frame_pointer(), sp, Operand(4 * kPointerSize));
|
678
|
+
__ mov(a0, zero_reg);
|
679
|
+
__ push(a0); // Make room for success counter and initialize it to 0.
|
672
680
|
__ push(a0); // Make room for "position - 1" constant (value irrelevant).
|
673
|
-
__ push(a0); // Make room for "at start" constant (value irrelevant).
|
674
681
|
|
675
682
|
// Check if we have space on the stack for registers.
|
676
683
|
Label stack_limit_hit;
|
@@ -689,12 +696,12 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
|
|
689
696
|
// Exit with OutOfMemory exception. There is not enough space on the stack
|
690
697
|
// for our working registers.
|
691
698
|
__ li(v0, Operand(EXCEPTION));
|
692
|
-
__ jmp(&
|
699
|
+
__ jmp(&return_v0);
|
693
700
|
|
694
701
|
__ bind(&stack_limit_hit);
|
695
702
|
CallCheckStackGuardState(a0);
|
696
703
|
// If returned value is non-zero, we exit with the returned value as result.
|
697
|
-
__ Branch(&
|
704
|
+
__ Branch(&return_v0, ne, v0, Operand(zero_reg));
|
698
705
|
|
699
706
|
__ bind(&stack_ok);
|
700
707
|
// Allocate space on stack for registers.
|
@@ -715,39 +722,44 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
|
|
715
722
|
// position registers.
|
716
723
|
__ sw(a0, MemOperand(frame_pointer(), kInputStartMinusOne));
|
717
724
|
|
718
|
-
//
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
__
|
725
|
+
// Initialize code pointer register
|
726
|
+
__ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE);
|
727
|
+
|
728
|
+
Label load_char_start_regexp, start_regexp;
|
729
|
+
// Load newline if index is at start, previous character otherwise.
|
730
|
+
__ Branch(&load_char_start_regexp, ne, a1, Operand(zero_reg));
|
731
|
+
__ li(current_character(), Operand('\n'));
|
732
|
+
__ jmp(&start_regexp);
|
733
|
+
|
734
|
+
// Global regexp restarts matching here.
|
735
|
+
__ bind(&load_char_start_regexp);
|
736
|
+
// Load previous char as initial value of current character register.
|
737
|
+
LoadCurrentCharacterUnchecked(-1, 1);
|
738
|
+
__ bind(&start_regexp);
|
724
739
|
|
740
|
+
// Initialize on-stack registers.
|
725
741
|
if (num_saved_registers_ > 0) { // Always is, if generated from a regexp.
|
726
742
|
// Fill saved registers with initial value = start offset - 1.
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
743
|
+
if (num_saved_registers_ > 8) {
|
744
|
+
// Address of register 0.
|
745
|
+
__ Addu(a1, frame_pointer(), Operand(kRegisterZero));
|
746
|
+
__ li(a2, Operand(num_saved_registers_));
|
747
|
+
Label init_loop;
|
748
|
+
__ bind(&init_loop);
|
749
|
+
__ sw(a0, MemOperand(a1));
|
750
|
+
__ Addu(a1, a1, Operand(-kPointerSize));
|
751
|
+
__ Subu(a2, a2, Operand(1));
|
752
|
+
__ Branch(&init_loop, ne, a2, Operand(zero_reg));
|
753
|
+
} else {
|
754
|
+
for (int i = 0; i < num_saved_registers_; i++) {
|
755
|
+
__ sw(a0, register_location(i));
|
756
|
+
}
|
757
|
+
}
|
737
758
|
}
|
738
759
|
|
739
760
|
// Initialize backtrack stack pointer.
|
740
761
|
__ lw(backtrack_stackpointer(), MemOperand(frame_pointer(), kStackHighEnd));
|
741
|
-
|
742
|
-
__ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE);
|
743
|
-
// Load previous char as initial value of current character register.
|
744
|
-
Label at_start;
|
745
|
-
__ lw(a0, MemOperand(frame_pointer(), kAtStart));
|
746
|
-
__ Branch(&at_start, ne, a0, Operand(zero_reg));
|
747
|
-
LoadCurrentCharacterUnchecked(-1, 1); // Load previous char.
|
748
|
-
__ jmp(&start_label_);
|
749
|
-
__ bind(&at_start);
|
750
|
-
__ li(current_character(), Operand('\n'));
|
762
|
+
|
751
763
|
__ jmp(&start_label_);
|
752
764
|
|
753
765
|
|
@@ -776,6 +788,10 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
|
|
776
788
|
for (int i = 0; i < num_saved_registers_; i += 2) {
|
777
789
|
__ lw(a2, register_location(i));
|
778
790
|
__ lw(a3, register_location(i + 1));
|
791
|
+
if (global()) {
|
792
|
+
// Keep capture start in a4 for the zero-length check later.
|
793
|
+
__ mov(t7, a2);
|
794
|
+
}
|
779
795
|
if (mode_ == UC16) {
|
780
796
|
__ sra(a2, a2, 1);
|
781
797
|
__ Addu(a2, a2, a1);
|
@@ -791,10 +807,52 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
|
|
791
807
|
__ Addu(a0, a0, kPointerSize);
|
792
808
|
}
|
793
809
|
}
|
794
|
-
|
810
|
+
|
811
|
+
if (global()) {
|
812
|
+
// Restart matching if the regular expression is flagged as global.
|
813
|
+
__ lw(a0, MemOperand(frame_pointer(), kSuccessfulCaptures));
|
814
|
+
__ lw(a1, MemOperand(frame_pointer(), kNumOutputRegisters));
|
815
|
+
__ lw(a2, MemOperand(frame_pointer(), kRegisterOutput));
|
816
|
+
// Increment success counter.
|
817
|
+
__ Addu(a0, a0, 1);
|
818
|
+
__ sw(a0, MemOperand(frame_pointer(), kSuccessfulCaptures));
|
819
|
+
// Capture results have been stored, so the number of remaining global
|
820
|
+
// output registers is reduced by the number of stored captures.
|
821
|
+
__ Subu(a1, a1, num_saved_registers_);
|
822
|
+
// Check whether we have enough room for another set of capture results.
|
823
|
+
__ mov(v0, a0);
|
824
|
+
__ Branch(&return_v0, lt, a1, Operand(num_saved_registers_));
|
825
|
+
|
826
|
+
__ sw(a1, MemOperand(frame_pointer(), kNumOutputRegisters));
|
827
|
+
// Advance the location for output.
|
828
|
+
__ Addu(a2, a2, num_saved_registers_ * kPointerSize);
|
829
|
+
__ sw(a2, MemOperand(frame_pointer(), kRegisterOutput));
|
830
|
+
|
831
|
+
// Prepare a0 to initialize registers with its value in the next run.
|
832
|
+
__ lw(a0, MemOperand(frame_pointer(), kInputStartMinusOne));
|
833
|
+
// Special case for zero-length matches.
|
834
|
+
// t7: capture start index
|
835
|
+
// Not a zero-length match, restart.
|
836
|
+
__ Branch(
|
837
|
+
&load_char_start_regexp, ne, current_input_offset(), Operand(t7));
|
838
|
+
// Offset from the end is zero if we already reached the end.
|
839
|
+
__ Branch(&exit_label_, eq, current_input_offset(), Operand(zero_reg));
|
840
|
+
// Advance current position after a zero-length match.
|
841
|
+
__ Addu(current_input_offset(),
|
842
|
+
current_input_offset(),
|
843
|
+
Operand((mode_ == UC16) ? 2 : 1));
|
844
|
+
__ Branch(&load_char_start_regexp);
|
845
|
+
} else {
|
846
|
+
__ li(v0, Operand(SUCCESS));
|
847
|
+
}
|
795
848
|
}
|
796
849
|
// Exit and return v0.
|
797
850
|
__ bind(&exit_label_);
|
851
|
+
if (global()) {
|
852
|
+
__ lw(v0, MemOperand(frame_pointer(), kSuccessfulCaptures));
|
853
|
+
}
|
854
|
+
|
855
|
+
__ bind(&return_v0);
|
798
856
|
// Skip sp past regexp registers and local variables..
|
799
857
|
__ mov(sp, frame_pointer());
|
800
858
|
// Restore registers s0..s7 and return (restoring ra to pc).
|
@@ -820,7 +878,7 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
|
|
820
878
|
__ MultiPop(regexp_registers_to_retain);
|
821
879
|
// If returning non-zero, we should end execution with the given
|
822
880
|
// result as return value.
|
823
|
-
__ Branch(&
|
881
|
+
__ Branch(&return_v0, ne, v0, Operand(zero_reg));
|
824
882
|
|
825
883
|
// String might have moved: Reload end of string from frame.
|
826
884
|
__ lw(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd));
|
@@ -864,7 +922,7 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
|
|
864
922
|
__ bind(&exit_with_exception);
|
865
923
|
// Exit with Result EXCEPTION(-1) to signal thrown exception.
|
866
924
|
__ li(v0, Operand(EXCEPTION));
|
867
|
-
__ jmp(&
|
925
|
+
__ jmp(&return_v0);
|
868
926
|
}
|
869
927
|
}
|
870
928
|
|
@@ -1012,8 +1070,9 @@ void RegExpMacroAssemblerMIPS::SetRegister(int register_index, int to) {
|
|
1012
1070
|
}
|
1013
1071
|
|
1014
1072
|
|
1015
|
-
|
1073
|
+
bool RegExpMacroAssemblerMIPS::Succeed() {
|
1016
1074
|
__ jmp(&success_label_);
|
1075
|
+
return global();
|
1017
1076
|
}
|
1018
1077
|
|
1019
1078
|
|
@@ -1280,8 +1339,9 @@ void RegExpMacroAssemblerMIPS::LoadCurrentCharacterUnchecked(int cp_offset,
|
|
1280
1339
|
int characters) {
|
1281
1340
|
Register offset = current_input_offset();
|
1282
1341
|
if (cp_offset != 0) {
|
1283
|
-
|
1284
|
-
|
1342
|
+
// t7 is not being used to store the capture start index at this point.
|
1343
|
+
__ Addu(t7, current_input_offset(), Operand(cp_offset * char_size()));
|
1344
|
+
offset = t7;
|
1285
1345
|
}
|
1286
1346
|
// We assume that we cannot do unaligned loads on MIPS, so this function
|
1287
1347
|
// must only be used to load a single character at a time.
|