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
@@ -231,7 +231,8 @@ class LCodeGen BASE_EMBEDDED {
|
|
231
231
|
LOperand* elements_pointer,
|
232
232
|
LOperand* key,
|
233
233
|
ElementsKind elements_kind,
|
234
|
-
uint32_t offset
|
234
|
+
uint32_t offset,
|
235
|
+
uint32_t additional_index = 0);
|
235
236
|
|
236
237
|
// Specific math operations - used from DoUnaryMathOperation.
|
237
238
|
void EmitIntegerMathAbs(LUnaryMathOperation* instr);
|
@@ -2012,8 +2012,9 @@ LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) {
|
|
2012
2012
|
|
2013
2013
|
LInstruction* LChunkBuilder::DoTransitionElementsKind(
|
2014
2014
|
HTransitionElementsKind* instr) {
|
2015
|
-
|
2016
|
-
|
2015
|
+
ElementsKind from_kind = instr->original_map()->elements_kind();
|
2016
|
+
ElementsKind to_kind = instr->transitioned_map()->elements_kind();
|
2017
|
+
if (IsSimpleMapChangeTransition(from_kind, to_kind)) {
|
2017
2018
|
LOperand* object = UseRegister(instr->object());
|
2018
2019
|
LOperand* new_map_reg = TempRegister();
|
2019
2020
|
LOperand* temp_reg = TempRegister();
|
@@ -2035,10 +2036,19 @@ LInstruction* LChunkBuilder::DoTransitionElementsKind(
|
|
2035
2036
|
|
2036
2037
|
LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
|
2037
2038
|
bool needs_write_barrier = instr->NeedsWriteBarrier();
|
2038
|
-
|
2039
|
-
|
2040
|
-
|
2041
|
-
|
2039
|
+
bool needs_write_barrier_for_map = !instr->transition().is_null() &&
|
2040
|
+
instr->NeedsWriteBarrierForMap();
|
2041
|
+
|
2042
|
+
LOperand* obj;
|
2043
|
+
if (needs_write_barrier) {
|
2044
|
+
obj = instr->is_in_object()
|
2045
|
+
? UseRegister(instr->object())
|
2046
|
+
: UseTempRegister(instr->object());
|
2047
|
+
} else {
|
2048
|
+
obj = needs_write_barrier_for_map
|
2049
|
+
? UseRegister(instr->object())
|
2050
|
+
: UseRegisterAtStart(instr->object());
|
2051
|
+
}
|
2042
2052
|
|
2043
2053
|
LOperand* val = needs_write_barrier
|
2044
2054
|
? UseTempRegister(instr->value())
|
@@ -2046,8 +2056,8 @@ LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
|
|
2046
2056
|
|
2047
2057
|
// We only need a scratch register if we have a write barrier or we
|
2048
2058
|
// have a store into the properties array (not in-object-property).
|
2049
|
-
LOperand* temp = (!instr->is_in_object() || needs_write_barrier
|
2050
|
-
? TempRegister() : NULL;
|
2059
|
+
LOperand* temp = (!instr->is_in_object() || needs_write_barrier ||
|
2060
|
+
needs_write_barrier_for_map) ? TempRegister() : NULL;
|
2051
2061
|
|
2052
2062
|
return new(zone()) LStoreNamedField(obj, val, temp);
|
2053
2063
|
}
|
@@ -1199,6 +1199,7 @@ class LLoadKeyedFastElement: public LTemplateInstruction<1, 2, 0> {
|
|
1199
1199
|
|
1200
1200
|
LOperand* elements() { return inputs_[0]; }
|
1201
1201
|
LOperand* key() { return inputs_[1]; }
|
1202
|
+
uint32_t additional_index() const { return hydrogen()->index_offset(); }
|
1202
1203
|
};
|
1203
1204
|
|
1204
1205
|
|
@@ -1215,13 +1216,13 @@ class LLoadKeyedFastDoubleElement: public LTemplateInstruction<1, 2, 0> {
|
|
1215
1216
|
|
1216
1217
|
LOperand* elements() { return inputs_[0]; }
|
1217
1218
|
LOperand* key() { return inputs_[1]; }
|
1219
|
+
uint32_t additional_index() const { return hydrogen()->index_offset(); }
|
1218
1220
|
};
|
1219
1221
|
|
1220
1222
|
|
1221
1223
|
class LLoadKeyedSpecializedArrayElement: public LTemplateInstruction<1, 2, 0> {
|
1222
1224
|
public:
|
1223
|
-
LLoadKeyedSpecializedArrayElement(LOperand* external_pointer,
|
1224
|
-
LOperand* key) {
|
1225
|
+
LLoadKeyedSpecializedArrayElement(LOperand* external_pointer, LOperand* key) {
|
1225
1226
|
inputs_[0] = external_pointer;
|
1226
1227
|
inputs_[1] = key;
|
1227
1228
|
}
|
@@ -1235,6 +1236,7 @@ class LLoadKeyedSpecializedArrayElement: public LTemplateInstruction<1, 2, 0> {
|
|
1235
1236
|
ElementsKind elements_kind() const {
|
1236
1237
|
return hydrogen()->elements_kind();
|
1237
1238
|
}
|
1239
|
+
uint32_t additional_index() const { return hydrogen()->index_offset(); }
|
1238
1240
|
};
|
1239
1241
|
|
1240
1242
|
|
@@ -1692,6 +1694,7 @@ class LStoreKeyedFastElement: public LTemplateInstruction<0, 3, 0> {
|
|
1692
1694
|
LOperand* object() { return inputs_[0]; }
|
1693
1695
|
LOperand* key() { return inputs_[1]; }
|
1694
1696
|
LOperand* value() { return inputs_[2]; }
|
1697
|
+
uint32_t additional_index() const { return hydrogen()->index_offset(); }
|
1695
1698
|
};
|
1696
1699
|
|
1697
1700
|
|
@@ -1716,6 +1719,7 @@ class LStoreKeyedFastDoubleElement: public LTemplateInstruction<0, 3, 0> {
|
|
1716
1719
|
LOperand* value() { return inputs_[2]; }
|
1717
1720
|
|
1718
1721
|
bool NeedsCanonicalization() { return hydrogen()->NeedsCanonicalization(); }
|
1722
|
+
uint32_t additional_index() const { return hydrogen()->index_offset(); }
|
1719
1723
|
};
|
1720
1724
|
|
1721
1725
|
|
@@ -1739,6 +1743,7 @@ class LStoreKeyedSpecializedArrayElement: public LTemplateInstruction<0, 3, 0> {
|
|
1739
1743
|
ElementsKind elements_kind() const {
|
1740
1744
|
return hydrogen()->elements_kind();
|
1741
1745
|
}
|
1746
|
+
uint32_t additional_index() const { return hydrogen()->index_offset(); }
|
1742
1747
|
};
|
1743
1748
|
|
1744
1749
|
|
@@ -2658,10 +2658,12 @@ void MacroAssembler::CmpInstanceType(Register map, InstanceType type) {
|
|
2658
2658
|
void MacroAssembler::CheckFastElements(Register map,
|
2659
2659
|
Label* fail,
|
2660
2660
|
Label::Distance distance) {
|
2661
|
-
STATIC_ASSERT(
|
2662
|
-
STATIC_ASSERT(
|
2661
|
+
STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
|
2662
|
+
STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
|
2663
|
+
STATIC_ASSERT(FAST_ELEMENTS == 2);
|
2664
|
+
STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3);
|
2663
2665
|
cmpb(FieldOperand(map, Map::kBitField2Offset),
|
2664
|
-
Immediate(Map::
|
2666
|
+
Immediate(Map::kMaximumBitField2FastHoleyElementValue));
|
2665
2667
|
j(above, fail, distance);
|
2666
2668
|
}
|
2667
2669
|
|
@@ -2669,23 +2671,26 @@ void MacroAssembler::CheckFastElements(Register map,
|
|
2669
2671
|
void MacroAssembler::CheckFastObjectElements(Register map,
|
2670
2672
|
Label* fail,
|
2671
2673
|
Label::Distance distance) {
|
2672
|
-
STATIC_ASSERT(
|
2673
|
-
STATIC_ASSERT(
|
2674
|
+
STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
|
2675
|
+
STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
|
2676
|
+
STATIC_ASSERT(FAST_ELEMENTS == 2);
|
2677
|
+
STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3);
|
2674
2678
|
cmpb(FieldOperand(map, Map::kBitField2Offset),
|
2675
|
-
Immediate(Map::
|
2679
|
+
Immediate(Map::kMaximumBitField2FastHoleySmiElementValue));
|
2676
2680
|
j(below_equal, fail, distance);
|
2677
2681
|
cmpb(FieldOperand(map, Map::kBitField2Offset),
|
2678
|
-
Immediate(Map::
|
2682
|
+
Immediate(Map::kMaximumBitField2FastHoleyElementValue));
|
2679
2683
|
j(above, fail, distance);
|
2680
2684
|
}
|
2681
2685
|
|
2682
2686
|
|
2683
|
-
void MacroAssembler::
|
2684
|
-
|
2685
|
-
|
2686
|
-
STATIC_ASSERT(
|
2687
|
+
void MacroAssembler::CheckFastSmiElements(Register map,
|
2688
|
+
Label* fail,
|
2689
|
+
Label::Distance distance) {
|
2690
|
+
STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
|
2691
|
+
STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
|
2687
2692
|
cmpb(FieldOperand(map, Map::kBitField2Offset),
|
2688
|
-
Immediate(Map::
|
2693
|
+
Immediate(Map::kMaximumBitField2FastHoleySmiElementValue));
|
2689
2694
|
j(above, fail, distance);
|
2690
2695
|
}
|
2691
2696
|
|
@@ -2749,24 +2754,18 @@ void MacroAssembler::CompareMap(Register obj,
|
|
2749
2754
|
CompareMapMode mode) {
|
2750
2755
|
Cmp(FieldOperand(obj, HeapObject::kMapOffset), map);
|
2751
2756
|
if (mode == ALLOW_ELEMENT_TRANSITION_MAPS) {
|
2752
|
-
|
2753
|
-
|
2754
|
-
|
2755
|
-
|
2756
|
-
|
2757
|
-
|
2758
|
-
|
2759
|
-
|
2760
|
-
|
2761
|
-
|
2762
|
-
|
2763
|
-
|
2764
|
-
ASSERT(transitioned_double_map == NULL ||
|
2765
|
-
map->elements_kind() == FAST_SMI_ONLY_ELEMENTS);
|
2766
|
-
if (transitioned_double_map != NULL) {
|
2767
|
-
j(equal, early_success, Label::kNear);
|
2768
|
-
Cmp(FieldOperand(obj, HeapObject::kMapOffset),
|
2769
|
-
Handle<Map>(transitioned_double_map));
|
2757
|
+
ElementsKind kind = map->elements_kind();
|
2758
|
+
if (IsFastElementsKind(kind)) {
|
2759
|
+
bool packed = IsFastPackedElementsKind(kind);
|
2760
|
+
Map* current_map = *map;
|
2761
|
+
while (CanTransitionToMoreGeneralFastElementsKind(kind, packed)) {
|
2762
|
+
kind = GetNextMoreGeneralFastElementsKind(kind, packed);
|
2763
|
+
current_map = current_map->LookupElementsTransitionMap(kind, NULL);
|
2764
|
+
if (!current_map) break;
|
2765
|
+
j(equal, early_success, Label::kNear);
|
2766
|
+
Cmp(FieldOperand(obj, HeapObject::kMapOffset),
|
2767
|
+
Handle<Map>(current_map));
|
2768
|
+
}
|
2770
2769
|
}
|
2771
2770
|
}
|
2772
2771
|
}
|
@@ -4057,27 +4056,38 @@ void MacroAssembler::LoadTransitionedArrayMapConditional(
|
|
4057
4056
|
movq(scratch, FieldOperand(scratch, GlobalObject::kGlobalContextOffset));
|
4058
4057
|
|
4059
4058
|
// Check that the function's map is the same as the expected cached map.
|
4060
|
-
|
4061
|
-
|
4062
|
-
|
4059
|
+
movq(scratch, Operand(scratch,
|
4060
|
+
Context::SlotOffset(Context::JS_ARRAY_MAPS_INDEX)));
|
4061
|
+
|
4062
|
+
int offset = expected_kind * kPointerSize +
|
4063
|
+
FixedArrayBase::kHeaderSize;
|
4064
|
+
cmpq(map_in_out, FieldOperand(scratch, offset));
|
4063
4065
|
j(not_equal, no_map_match);
|
4064
4066
|
|
4065
4067
|
// Use the transitioned cached map.
|
4066
|
-
|
4067
|
-
|
4068
|
-
movq(map_in_out,
|
4068
|
+
offset = transitioned_kind * kPointerSize +
|
4069
|
+
FixedArrayBase::kHeaderSize;
|
4070
|
+
movq(map_in_out, FieldOperand(scratch, offset));
|
4069
4071
|
}
|
4070
4072
|
|
4071
4073
|
|
4072
4074
|
void MacroAssembler::LoadInitialArrayMap(
|
4073
|
-
Register function_in, Register scratch,
|
4075
|
+
Register function_in, Register scratch,
|
4076
|
+
Register map_out, bool can_have_holes) {
|
4074
4077
|
ASSERT(!function_in.is(map_out));
|
4075
4078
|
Label done;
|
4076
4079
|
movq(map_out, FieldOperand(function_in,
|
4077
4080
|
JSFunction::kPrototypeOrInitialMapOffset));
|
4078
4081
|
if (!FLAG_smi_only_arrays) {
|
4079
|
-
|
4080
|
-
|
4082
|
+
ElementsKind kind = can_have_holes ? FAST_HOLEY_ELEMENTS : FAST_ELEMENTS;
|
4083
|
+
LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
|
4084
|
+
kind,
|
4085
|
+
map_out,
|
4086
|
+
scratch,
|
4087
|
+
&done);
|
4088
|
+
} else if (can_have_holes) {
|
4089
|
+
LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
|
4090
|
+
FAST_HOLEY_SMI_ELEMENTS,
|
4081
4091
|
map_out,
|
4082
4092
|
scratch,
|
4083
4093
|
&done);
|
@@ -4188,7 +4198,7 @@ bool AreAliased(Register r1, Register r2, Register r3, Register r4) {
|
|
4188
4198
|
CodePatcher::CodePatcher(byte* address, int size)
|
4189
4199
|
: address_(address),
|
4190
4200
|
size_(size),
|
4191
|
-
masm_(
|
4201
|
+
masm_(NULL, address, size + Assembler::kGap) {
|
4192
4202
|
// Create a new macro assembler pointing to the address of the code to patch.
|
4193
4203
|
// The size is adjusted with kGap on order for the assembler to generate size
|
4194
4204
|
// bytes of instructions without failing with buffer size constraints.
|
@@ -877,9 +877,9 @@ class MacroAssembler: public Assembler {
|
|
877
877
|
|
878
878
|
// Check if a map for a JSObject indicates that the object has fast smi only
|
879
879
|
// elements. Jump to the specified label if it does not.
|
880
|
-
void
|
881
|
-
|
882
|
-
|
880
|
+
void CheckFastSmiElements(Register map,
|
881
|
+
Label* fail,
|
882
|
+
Label::Distance distance = Label::kFar);
|
883
883
|
|
884
884
|
// Check to see if maybe_number can be stored as a double in
|
885
885
|
// FastDoubleElements. If it can, store it at the index specified by index in
|
@@ -1141,7 +1141,8 @@ class MacroAssembler: public Assembler {
|
|
1141
1141
|
// Load the initial map for new Arrays from a JSFunction.
|
1142
1142
|
void LoadInitialArrayMap(Register function_in,
|
1143
1143
|
Register scratch,
|
1144
|
-
Register map_out
|
1144
|
+
Register map_out,
|
1145
|
+
bool can_have_holes);
|
1145
1146
|
|
1146
1147
|
// Load the global function with the given index.
|
1147
1148
|
void LoadGlobalFunction(int index, Register function);
|
@@ -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:
|
@@ -44,21 +44,23 @@ namespace internal {
|
|
44
44
|
|
45
45
|
/*
|
46
46
|
* This assembler uses the following register assignment convention
|
47
|
-
* - rdx :
|
48
|
-
* LoadCurrentCharacter before using any of the dispatch methods.
|
49
|
-
*
|
47
|
+
* - rdx : Currently loaded character(s) as ASCII or UC16. Must be loaded
|
48
|
+
* using LoadCurrentCharacter before using any of the dispatch methods.
|
49
|
+
* Temporarily stores the index of capture start after a matching pass
|
50
|
+
* for a global regexp.
|
51
|
+
* - rdi : Current position in input, as negative offset from end of string.
|
50
52
|
* Please notice that this is the byte offset, not the character
|
51
|
-
* offset!
|
53
|
+
* offset! Is always a 32-bit signed (negative) offset, but must be
|
52
54
|
* maintained sign-extended to 64 bits, since it is used as index.
|
53
|
-
* - rsi :
|
55
|
+
* - rsi : End of input (points to byte after last character in input),
|
54
56
|
* so that rsi+rdi points to the current character.
|
55
|
-
* - rbp :
|
57
|
+
* - rbp : Frame pointer. Used to access arguments, local variables and
|
56
58
|
* RegExp registers.
|
57
|
-
* - rsp :
|
58
|
-
* - rcx :
|
59
|
-
* only 32-bit values.
|
59
|
+
* - rsp : Points to tip of C stack.
|
60
|
+
* - rcx : Points to tip of backtrack stack. The backtrack stack contains
|
61
|
+
* only 32-bit values. Most are offsets from some base (e.g., character
|
60
62
|
* positions from end of string or code location from Code* pointer).
|
61
|
-
* - r8 :
|
63
|
+
* - r8 : Code object pointer. Used to convert between absolute and
|
62
64
|
* code-object-relative addresses.
|
63
65
|
*
|
64
66
|
* The registers rax, rbx, r9 and r11 are free to use for computations.
|
@@ -72,20 +74,22 @@ namespace internal {
|
|
72
74
|
*
|
73
75
|
* The stack will have the following content, in some order, indexable from the
|
74
76
|
* frame pointer (see, e.g., kStackHighEnd):
|
75
|
-
* - Isolate* isolate (
|
77
|
+
* - Isolate* isolate (address of the current isolate)
|
76
78
|
* - direct_call (if 1, direct call from JavaScript code, if 0 call
|
77
79
|
* through the runtime system)
|
78
|
-
* - stack_area_base (
|
80
|
+
* - stack_area_base (high end of the memory area to use as
|
79
81
|
* backtracking stack)
|
82
|
+
* - capture array size (may fit multiple sets of matches)
|
80
83
|
* - int* capture_array (int[num_saved_registers_], for output).
|
81
|
-
* - end of input (
|
82
|
-
* - start of input (
|
84
|
+
* - end of input (address of end of string)
|
85
|
+
* - start of input (address of first character in string)
|
83
86
|
* - start index (character index of start)
|
84
87
|
* - String* input_string (input string)
|
85
88
|
* - return address
|
86
89
|
* - backup of callee save registers (rbx, possibly rsi and rdi).
|
90
|
+
* - success counter (only useful for global regexp to count matches)
|
87
91
|
* - Offset of location before start of input (effectively character
|
88
|
-
* position -1).
|
92
|
+
* position -1). Used to initialize capture registers to a non-position.
|
89
93
|
* - At start of string (if 1, we are starting at the start of the
|
90
94
|
* string, otherwise 0)
|
91
95
|
* - register 0 rbp[-n] (Only positions must be stored in the first
|
@@ -94,7 +98,7 @@ namespace internal {
|
|
94
98
|
*
|
95
99
|
* The first num_saved_registers_ registers are initialized to point to
|
96
100
|
* "character -1" in the string (i.e., char_size() bytes before the first
|
97
|
-
* character of the string).
|
101
|
+
* character of the string). The remaining registers starts out uninitialized.
|
98
102
|
*
|
99
103
|
* The first seven values must be provided by the calling code by
|
100
104
|
* calling the code's entry address cast to a function pointer with the
|
@@ -744,13 +748,16 @@ bool RegExpMacroAssemblerX64::CheckSpecialCharacterClass(uc16 type,
|
|
744
748
|
|
745
749
|
|
746
750
|
void RegExpMacroAssemblerX64::Fail() {
|
747
|
-
|
748
|
-
|
751
|
+
STATIC_ASSERT(FAILURE == 0); // Return value for failure is zero.
|
752
|
+
if (!global()) {
|
753
|
+
__ Set(rax, FAILURE);
|
754
|
+
}
|
749
755
|
__ jmp(&exit_label_);
|
750
756
|
}
|
751
757
|
|
752
758
|
|
753
759
|
Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
|
760
|
+
Label return_rax;
|
754
761
|
// Finalize code - write the entry point code now we know how many
|
755
762
|
// registers we need.
|
756
763
|
// Entry code:
|
@@ -784,7 +791,7 @@ Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
|
|
784
791
|
ASSERT_EQ(kInputStart, -3 * kPointerSize);
|
785
792
|
ASSERT_EQ(kInputEnd, -4 * kPointerSize);
|
786
793
|
ASSERT_EQ(kRegisterOutput, -5 * kPointerSize);
|
787
|
-
ASSERT_EQ(
|
794
|
+
ASSERT_EQ(kNumOutputRegisters, -6 * kPointerSize);
|
788
795
|
__ push(rdi);
|
789
796
|
__ push(rsi);
|
790
797
|
__ push(rdx);
|
@@ -795,7 +802,8 @@ Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
|
|
795
802
|
__ push(rbx); // Callee-save
|
796
803
|
#endif
|
797
804
|
|
798
|
-
__ push(Immediate(0)); //
|
805
|
+
__ push(Immediate(0)); // Number of successful matches in a global regexp.
|
806
|
+
__ push(Immediate(0)); // Make room for "input start - 1" constant.
|
799
807
|
|
800
808
|
// Check if we have space on the stack for registers.
|
801
809
|
Label stack_limit_hit;
|
@@ -815,14 +823,14 @@ Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
|
|
815
823
|
// Exit with OutOfMemory exception. There is not enough space on the stack
|
816
824
|
// for our working registers.
|
817
825
|
__ Set(rax, EXCEPTION);
|
818
|
-
__ jmp(&
|
826
|
+
__ jmp(&return_rax);
|
819
827
|
|
820
828
|
__ bind(&stack_limit_hit);
|
821
829
|
__ Move(code_object_pointer(), masm_.CodeObject());
|
822
830
|
CallCheckStackGuardState(); // Preserves no registers beside rbp and rsp.
|
823
831
|
__ testq(rax, rax);
|
824
832
|
// If returned value is non-zero, we exit with the returned value as result.
|
825
|
-
__ j(not_zero, &
|
833
|
+
__ j(not_zero, &return_rax);
|
826
834
|
|
827
835
|
__ bind(&stack_ok);
|
828
836
|
|
@@ -847,19 +855,7 @@ Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
|
|
847
855
|
// position registers.
|
848
856
|
__ movq(Operand(rbp, kInputStartMinusOne), rax);
|
849
857
|
|
850
|
-
|
851
|
-
// Fill saved registers with initial value = start offset - 1
|
852
|
-
// Fill in stack push order, to avoid accessing across an unwritten
|
853
|
-
// page (a problem on Windows).
|
854
|
-
__ Set(rcx, kRegisterZero);
|
855
|
-
Label init_loop;
|
856
|
-
__ bind(&init_loop);
|
857
|
-
__ movq(Operand(rbp, rcx, times_1, 0), rax);
|
858
|
-
__ subq(rcx, Immediate(kPointerSize));
|
859
|
-
__ cmpq(rcx,
|
860
|
-
Immediate(kRegisterZero - num_saved_registers_ * kPointerSize));
|
861
|
-
__ j(greater, &init_loop);
|
862
|
-
}
|
858
|
+
#ifdef WIN32
|
863
859
|
// Ensure that we have written to each stack page, in order. Skipping a page
|
864
860
|
// on Windows can cause segmentation faults. Assuming page size is 4k.
|
865
861
|
const int kPageSize = 4096;
|
@@ -869,21 +865,49 @@ Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
|
|
869
865
|
i += kRegistersPerPage) {
|
870
866
|
__ movq(register_location(i), rax); // One write every page.
|
871
867
|
}
|
868
|
+
#endif // WIN32
|
872
869
|
|
873
|
-
// Initialize backtrack stack pointer.
|
874
|
-
__ movq(backtrack_stackpointer(), Operand(rbp, kStackHighEnd));
|
875
870
|
// Initialize code object pointer.
|
876
871
|
__ Move(code_object_pointer(), masm_.CodeObject());
|
877
|
-
|
878
|
-
Label
|
879
|
-
|
880
|
-
__
|
881
|
-
|
882
|
-
__ jmp(&start_label_);
|
883
|
-
__ bind(&at_start);
|
872
|
+
|
873
|
+
Label load_char_start_regexp, start_regexp;
|
874
|
+
// Load newline if index is at start, previous character otherwise.
|
875
|
+
__ cmpl(Operand(rbp, kStartIndex), Immediate(0));
|
876
|
+
__ j(not_equal, &load_char_start_regexp, Label::kNear);
|
884
877
|
__ Set(current_character(), '\n');
|
885
|
-
__ jmp(&
|
878
|
+
__ jmp(&start_regexp, Label::kNear);
|
879
|
+
|
880
|
+
// Global regexp restarts matching here.
|
881
|
+
__ bind(&load_char_start_regexp);
|
882
|
+
// Load previous char as initial value of current character register.
|
883
|
+
LoadCurrentCharacterUnchecked(-1, 1);
|
884
|
+
__ bind(&start_regexp);
|
885
|
+
|
886
|
+
// Initialize on-stack registers.
|
887
|
+
if (num_saved_registers_ > 0) {
|
888
|
+
// Fill saved registers with initial value = start offset - 1
|
889
|
+
// Fill in stack push order, to avoid accessing across an unwritten
|
890
|
+
// page (a problem on Windows).
|
891
|
+
if (num_saved_registers_ > 8) {
|
892
|
+
__ Set(rcx, kRegisterZero);
|
893
|
+
Label init_loop;
|
894
|
+
__ bind(&init_loop);
|
895
|
+
__ movq(Operand(rbp, rcx, times_1, 0), rax);
|
896
|
+
__ subq(rcx, Immediate(kPointerSize));
|
897
|
+
__ cmpq(rcx,
|
898
|
+
Immediate(kRegisterZero - num_saved_registers_ * kPointerSize));
|
899
|
+
__ j(greater, &init_loop);
|
900
|
+
} else { // Unroll the loop.
|
901
|
+
for (int i = 0; i < num_saved_registers_; i++) {
|
902
|
+
__ movq(register_location(i), rax);
|
903
|
+
}
|
904
|
+
}
|
905
|
+
}
|
906
|
+
|
907
|
+
// Initialize backtrack stack pointer.
|
908
|
+
__ movq(backtrack_stackpointer(), Operand(rbp, kStackHighEnd));
|
886
909
|
|
910
|
+
__ jmp(&start_label_);
|
887
911
|
|
888
912
|
// Exit code:
|
889
913
|
if (success_label_.is_linked()) {
|
@@ -902,6 +926,10 @@ Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
|
|
902
926
|
}
|
903
927
|
for (int i = 0; i < num_saved_registers_; i++) {
|
904
928
|
__ movq(rax, register_location(i));
|
929
|
+
if (i == 0 && global()) {
|
930
|
+
// Keep capture start in rdx for the zero-length check later.
|
931
|
+
__ movq(rdx, rax);
|
932
|
+
}
|
905
933
|
__ addq(rax, rcx); // Convert to index from start, not end.
|
906
934
|
if (mode_ == UC16) {
|
907
935
|
__ sar(rax, Immediate(1)); // Convert byte index to character index.
|
@@ -909,12 +937,54 @@ Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
|
|
909
937
|
__ movl(Operand(rbx, i * kIntSize), rax);
|
910
938
|
}
|
911
939
|
}
|
912
|
-
|
940
|
+
|
941
|
+
if (global()) {
|
942
|
+
// Restart matching if the regular expression is flagged as global.
|
943
|
+
// Increment success counter.
|
944
|
+
__ incq(Operand(rbp, kSuccessfulCaptures));
|
945
|
+
// Capture results have been stored, so the number of remaining global
|
946
|
+
// output registers is reduced by the number of stored captures.
|
947
|
+
__ movsxlq(rcx, Operand(rbp, kNumOutputRegisters));
|
948
|
+
__ subq(rcx, Immediate(num_saved_registers_));
|
949
|
+
// Check whether we have enough room for another set of capture results.
|
950
|
+
__ cmpq(rcx, Immediate(num_saved_registers_));
|
951
|
+
__ j(less, &exit_label_);
|
952
|
+
|
953
|
+
__ movq(Operand(rbp, kNumOutputRegisters), rcx);
|
954
|
+
// Advance the location for output.
|
955
|
+
__ addq(Operand(rbp, kRegisterOutput),
|
956
|
+
Immediate(num_saved_registers_ * kIntSize));
|
957
|
+
|
958
|
+
// Prepare rax to initialize registers with its value in the next run.
|
959
|
+
__ movq(rax, Operand(rbp, kInputStartMinusOne));
|
960
|
+
|
961
|
+
// Special case for zero-length matches.
|
962
|
+
// rdx: capture start index
|
963
|
+
__ cmpq(rdi, rdx);
|
964
|
+
// Not a zero-length match, restart.
|
965
|
+
__ j(not_equal, &load_char_start_regexp);
|
966
|
+
// rdi (offset from the end) is zero if we already reached the end.
|
967
|
+
__ testq(rdi, rdi);
|
968
|
+
__ j(zero, &exit_label_, Label::kNear);
|
969
|
+
// Advance current position after a zero-length match.
|
970
|
+
if (mode_ == UC16) {
|
971
|
+
__ addq(rdi, Immediate(2));
|
972
|
+
} else {
|
973
|
+
__ incq(rdi);
|
974
|
+
}
|
975
|
+
__ jmp(&load_char_start_regexp);
|
976
|
+
} else {
|
977
|
+
__ movq(rax, Immediate(SUCCESS));
|
978
|
+
}
|
913
979
|
}
|
914
980
|
|
915
|
-
// Exit and return rax
|
916
981
|
__ bind(&exit_label_);
|
982
|
+
if (global()) {
|
983
|
+
// Return the number of successful captures.
|
984
|
+
__ movq(rax, Operand(rbp, kSuccessfulCaptures));
|
985
|
+
}
|
917
986
|
|
987
|
+
__ bind(&return_rax);
|
918
988
|
#ifdef _WIN64
|
919
989
|
// Restore callee save registers.
|
920
990
|
__ lea(rsp, Operand(rbp, kLastCalleeSaveRegister));
|
@@ -951,7 +1021,7 @@ Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
|
|
951
1021
|
__ testq(rax, rax);
|
952
1022
|
// If returning non-zero, we should end execution with the given
|
953
1023
|
// result as return value.
|
954
|
-
__ j(not_zero, &
|
1024
|
+
__ j(not_zero, &return_rax);
|
955
1025
|
|
956
1026
|
// Restore registers.
|
957
1027
|
__ Move(code_object_pointer(), masm_.CodeObject());
|
@@ -1012,7 +1082,7 @@ Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
|
|
1012
1082
|
__ bind(&exit_with_exception);
|
1013
1083
|
// Exit with Result EXCEPTION(-1) to signal thrown exception.
|
1014
1084
|
__ Set(rax, EXCEPTION);
|
1015
|
-
__ jmp(&
|
1085
|
+
__ jmp(&return_rax);
|
1016
1086
|
}
|
1017
1087
|
|
1018
1088
|
FixupCodeRelativePositions();
|
@@ -1135,8 +1205,9 @@ void RegExpMacroAssemblerX64::SetRegister(int register_index, int to) {
|
|
1135
1205
|
}
|
1136
1206
|
|
1137
1207
|
|
1138
|
-
|
1208
|
+
bool RegExpMacroAssemblerX64::Succeed() {
|
1139
1209
|
__ jmp(&success_label_);
|
1210
|
+
return global();
|
1140
1211
|
}
|
1141
1212
|
|
1142
1213
|
|