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
@@ -242,7 +242,8 @@ class LCodeGen BASE_EMBEDDED {
|
|
242
242
|
Operand BuildFastArrayOperand(LOperand* elements_pointer,
|
243
243
|
LOperand* key,
|
244
244
|
ElementsKind elements_kind,
|
245
|
-
uint32_t offset
|
245
|
+
uint32_t offset,
|
246
|
+
uint32_t additional_index = 0);
|
246
247
|
|
247
248
|
// Specific math operations - used from DoUnaryMathOperation.
|
248
249
|
void EmitIntegerMathAbs(LUnaryMathOperation* instr);
|
@@ -1990,8 +1990,7 @@ LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement(
|
|
1990
1990
|
LOperand* external_pointer = UseRegister(instr->external_pointer());
|
1991
1991
|
LOperand* key = UseRegisterOrConstant(instr->key());
|
1992
1992
|
LLoadKeyedSpecializedArrayElement* result =
|
1993
|
-
new(zone()) LLoadKeyedSpecializedArrayElement(external_pointer,
|
1994
|
-
key);
|
1993
|
+
new(zone()) LLoadKeyedSpecializedArrayElement(external_pointer, key);
|
1995
1994
|
LInstruction* load_instr = DefineAsRegister(result);
|
1996
1995
|
// An unsigned int array load might overflow and cause a deopt, make sure it
|
1997
1996
|
// has an environment.
|
@@ -2093,8 +2092,9 @@ LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) {
|
|
2093
2092
|
|
2094
2093
|
LInstruction* LChunkBuilder::DoTransitionElementsKind(
|
2095
2094
|
HTransitionElementsKind* instr) {
|
2096
|
-
|
2097
|
-
|
2095
|
+
ElementsKind from_kind = instr->original_map()->elements_kind();
|
2096
|
+
ElementsKind to_kind = instr->transitioned_map()->elements_kind();
|
2097
|
+
if (IsSimpleMapChangeTransition(from_kind, to_kind)) {
|
2098
2098
|
LOperand* object = UseRegister(instr->object());
|
2099
2099
|
LOperand* new_map_reg = TempRegister();
|
2100
2100
|
LOperand* temp_reg = TempRegister();
|
@@ -2116,6 +2116,8 @@ LInstruction* LChunkBuilder::DoTransitionElementsKind(
|
|
2116
2116
|
|
2117
2117
|
LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
|
2118
2118
|
bool needs_write_barrier = instr->NeedsWriteBarrier();
|
2119
|
+
bool needs_write_barrier_for_map = !instr->transition().is_null() &&
|
2120
|
+
instr->NeedsWriteBarrierForMap();
|
2119
2121
|
|
2120
2122
|
LOperand* obj;
|
2121
2123
|
if (needs_write_barrier) {
|
@@ -2123,7 +2125,9 @@ LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
|
|
2123
2125
|
? UseRegister(instr->object())
|
2124
2126
|
: UseTempRegister(instr->object());
|
2125
2127
|
} else {
|
2126
|
-
obj =
|
2128
|
+
obj = needs_write_barrier_for_map
|
2129
|
+
? UseRegister(instr->object())
|
2130
|
+
: UseRegisterAtStart(instr->object());
|
2127
2131
|
}
|
2128
2132
|
|
2129
2133
|
LOperand* val = needs_write_barrier
|
@@ -2132,11 +2136,13 @@ LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
|
|
2132
2136
|
|
2133
2137
|
// We only need a scratch register if we have a write barrier or we
|
2134
2138
|
// have a store into the properties array (not in-object-property).
|
2135
|
-
LOperand* temp = (!instr->is_in_object() || needs_write_barrier
|
2136
|
-
? TempRegister()
|
2137
|
-
|
2139
|
+
LOperand* temp = (!instr->is_in_object() || needs_write_barrier ||
|
2140
|
+
needs_write_barrier_for_map) ? TempRegister() : NULL;
|
2141
|
+
|
2142
|
+
// We need a temporary register for write barrier of the map field.
|
2143
|
+
LOperand* temp_map = needs_write_barrier_for_map ? TempRegister() : NULL;
|
2138
2144
|
|
2139
|
-
return new(zone()) LStoreNamedField(obj, val, temp);
|
2145
|
+
return new(zone()) LStoreNamedField(obj, val, temp, temp_map);
|
2140
2146
|
}
|
2141
2147
|
|
2142
2148
|
|
@@ -1238,13 +1238,13 @@ class LLoadKeyedFastElement: public LTemplateInstruction<1, 2, 0> {
|
|
1238
1238
|
|
1239
1239
|
LOperand* elements() { return inputs_[0]; }
|
1240
1240
|
LOperand* key() { return inputs_[1]; }
|
1241
|
+
uint32_t additional_index() const { return hydrogen()->index_offset(); }
|
1241
1242
|
};
|
1242
1243
|
|
1243
1244
|
|
1244
1245
|
class LLoadKeyedFastDoubleElement: public LTemplateInstruction<1, 2, 0> {
|
1245
1246
|
public:
|
1246
|
-
LLoadKeyedFastDoubleElement(LOperand* elements,
|
1247
|
-
LOperand* key) {
|
1247
|
+
LLoadKeyedFastDoubleElement(LOperand* elements, LOperand* key) {
|
1248
1248
|
inputs_[0] = elements;
|
1249
1249
|
inputs_[1] = key;
|
1250
1250
|
}
|
@@ -1255,13 +1255,13 @@ class LLoadKeyedFastDoubleElement: public LTemplateInstruction<1, 2, 0> {
|
|
1255
1255
|
|
1256
1256
|
LOperand* elements() { return inputs_[0]; }
|
1257
1257
|
LOperand* key() { return inputs_[1]; }
|
1258
|
+
uint32_t additional_index() const { return hydrogen()->index_offset(); }
|
1258
1259
|
};
|
1259
1260
|
|
1260
1261
|
|
1261
1262
|
class LLoadKeyedSpecializedArrayElement: public LTemplateInstruction<1, 2, 0> {
|
1262
1263
|
public:
|
1263
|
-
LLoadKeyedSpecializedArrayElement(LOperand* external_pointer,
|
1264
|
-
LOperand* key) {
|
1264
|
+
LLoadKeyedSpecializedArrayElement(LOperand* external_pointer, LOperand* key) {
|
1265
1265
|
inputs_[0] = external_pointer;
|
1266
1266
|
inputs_[1] = key;
|
1267
1267
|
}
|
@@ -1275,6 +1275,7 @@ class LLoadKeyedSpecializedArrayElement: public LTemplateInstruction<1, 2, 0> {
|
|
1275
1275
|
ElementsKind elements_kind() const {
|
1276
1276
|
return hydrogen()->elements_kind();
|
1277
1277
|
}
|
1278
|
+
uint32_t additional_index() const { return hydrogen()->index_offset(); }
|
1278
1279
|
};
|
1279
1280
|
|
1280
1281
|
|
@@ -1714,12 +1715,16 @@ class LSmiUntag: public LTemplateInstruction<1, 1, 0> {
|
|
1714
1715
|
};
|
1715
1716
|
|
1716
1717
|
|
1717
|
-
class LStoreNamedField: public LTemplateInstruction<0, 2,
|
1718
|
+
class LStoreNamedField: public LTemplateInstruction<0, 2, 2> {
|
1718
1719
|
public:
|
1719
|
-
LStoreNamedField(LOperand* obj,
|
1720
|
+
LStoreNamedField(LOperand* obj,
|
1721
|
+
LOperand* val,
|
1722
|
+
LOperand* temp,
|
1723
|
+
LOperand* temp_map) {
|
1720
1724
|
inputs_[0] = obj;
|
1721
1725
|
inputs_[1] = val;
|
1722
1726
|
temps_[0] = temp;
|
1727
|
+
temps_[1] = temp_map;
|
1723
1728
|
}
|
1724
1729
|
|
1725
1730
|
DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store-named-field")
|
@@ -1775,6 +1780,7 @@ class LStoreKeyedFastElement: public LTemplateInstruction<0, 3, 0> {
|
|
1775
1780
|
LOperand* object() { return inputs_[0]; }
|
1776
1781
|
LOperand* key() { return inputs_[1]; }
|
1777
1782
|
LOperand* value() { return inputs_[2]; }
|
1783
|
+
uint32_t additional_index() const { return hydrogen()->index_offset(); }
|
1778
1784
|
};
|
1779
1785
|
|
1780
1786
|
|
@@ -1797,6 +1803,7 @@ class LStoreKeyedFastDoubleElement: public LTemplateInstruction<0, 3, 0> {
|
|
1797
1803
|
LOperand* elements() { return inputs_[0]; }
|
1798
1804
|
LOperand* key() { return inputs_[1]; }
|
1799
1805
|
LOperand* value() { return inputs_[2]; }
|
1806
|
+
uint32_t additional_index() const { return hydrogen()->index_offset(); }
|
1800
1807
|
|
1801
1808
|
bool NeedsCanonicalization() { return hydrogen()->NeedsCanonicalization(); }
|
1802
1809
|
};
|
@@ -1822,6 +1829,7 @@ class LStoreKeyedSpecializedArrayElement: public LTemplateInstruction<0, 3, 0> {
|
|
1822
1829
|
ElementsKind elements_kind() const {
|
1823
1830
|
return hydrogen()->elements_kind();
|
1824
1831
|
}
|
1832
|
+
uint32_t additional_index() const { return hydrogen()->index_offset(); }
|
1825
1833
|
};
|
1826
1834
|
|
1827
1835
|
|
@@ -382,10 +382,12 @@ void MacroAssembler::CmpInstanceType(Register map, InstanceType type) {
|
|
382
382
|
void MacroAssembler::CheckFastElements(Register map,
|
383
383
|
Label* fail,
|
384
384
|
Label::Distance distance) {
|
385
|
-
STATIC_ASSERT(
|
386
|
-
STATIC_ASSERT(
|
385
|
+
STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
|
386
|
+
STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
|
387
|
+
STATIC_ASSERT(FAST_ELEMENTS == 2);
|
388
|
+
STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3);
|
387
389
|
cmpb(FieldOperand(map, Map::kBitField2Offset),
|
388
|
-
Map::
|
390
|
+
Map::kMaximumBitField2FastHoleyElementValue);
|
389
391
|
j(above, fail, distance);
|
390
392
|
}
|
391
393
|
|
@@ -393,23 +395,26 @@ void MacroAssembler::CheckFastElements(Register map,
|
|
393
395
|
void MacroAssembler::CheckFastObjectElements(Register map,
|
394
396
|
Label* fail,
|
395
397
|
Label::Distance distance) {
|
396
|
-
STATIC_ASSERT(
|
397
|
-
STATIC_ASSERT(
|
398
|
+
STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
|
399
|
+
STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
|
400
|
+
STATIC_ASSERT(FAST_ELEMENTS == 2);
|
401
|
+
STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3);
|
398
402
|
cmpb(FieldOperand(map, Map::kBitField2Offset),
|
399
|
-
Map::
|
403
|
+
Map::kMaximumBitField2FastHoleySmiElementValue);
|
400
404
|
j(below_equal, fail, distance);
|
401
405
|
cmpb(FieldOperand(map, Map::kBitField2Offset),
|
402
|
-
Map::
|
406
|
+
Map::kMaximumBitField2FastHoleyElementValue);
|
403
407
|
j(above, fail, distance);
|
404
408
|
}
|
405
409
|
|
406
410
|
|
407
|
-
void MacroAssembler::
|
408
|
-
|
409
|
-
|
410
|
-
STATIC_ASSERT(
|
411
|
+
void MacroAssembler::CheckFastSmiElements(Register map,
|
412
|
+
Label* fail,
|
413
|
+
Label::Distance distance) {
|
414
|
+
STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
|
415
|
+
STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
|
411
416
|
cmpb(FieldOperand(map, Map::kBitField2Offset),
|
412
|
-
Map::
|
417
|
+
Map::kMaximumBitField2FastHoleySmiElementValue);
|
413
418
|
j(above, fail, distance);
|
414
419
|
}
|
415
420
|
|
@@ -493,24 +498,18 @@ void MacroAssembler::CompareMap(Register obj,
|
|
493
498
|
CompareMapMode mode) {
|
494
499
|
cmp(FieldOperand(obj, HeapObject::kMapOffset), map);
|
495
500
|
if (mode == ALLOW_ELEMENT_TRANSITION_MAPS) {
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
ASSERT(transitioned_double_map == NULL ||
|
509
|
-
map->elements_kind() == FAST_SMI_ONLY_ELEMENTS);
|
510
|
-
if (transitioned_double_map != NULL) {
|
511
|
-
j(equal, early_success, Label::kNear);
|
512
|
-
cmp(FieldOperand(obj, HeapObject::kMapOffset),
|
513
|
-
Handle<Map>(transitioned_double_map));
|
501
|
+
ElementsKind kind = map->elements_kind();
|
502
|
+
if (IsFastElementsKind(kind)) {
|
503
|
+
bool packed = IsFastPackedElementsKind(kind);
|
504
|
+
Map* current_map = *map;
|
505
|
+
while (CanTransitionToMoreGeneralFastElementsKind(kind, packed)) {
|
506
|
+
kind = GetNextMoreGeneralFastElementsKind(kind, packed);
|
507
|
+
current_map = current_map->LookupElementsTransitionMap(kind, NULL);
|
508
|
+
if (!current_map) break;
|
509
|
+
j(equal, early_success, Label::kNear);
|
510
|
+
cmp(FieldOperand(obj, HeapObject::kMapOffset),
|
511
|
+
Handle<Map>(current_map));
|
512
|
+
}
|
514
513
|
}
|
515
514
|
}
|
516
515
|
}
|
@@ -2161,27 +2160,38 @@ void MacroAssembler::LoadTransitionedArrayMapConditional(
|
|
2161
2160
|
mov(scratch, FieldOperand(scratch, GlobalObject::kGlobalContextOffset));
|
2162
2161
|
|
2163
2162
|
// Check that the function's map is the same as the expected cached map.
|
2164
|
-
|
2165
|
-
|
2166
|
-
|
2163
|
+
mov(scratch, Operand(scratch,
|
2164
|
+
Context::SlotOffset(Context::JS_ARRAY_MAPS_INDEX)));
|
2165
|
+
|
2166
|
+
size_t offset = expected_kind * kPointerSize +
|
2167
|
+
FixedArrayBase::kHeaderSize;
|
2168
|
+
cmp(map_in_out, FieldOperand(scratch, offset));
|
2167
2169
|
j(not_equal, no_map_match);
|
2168
2170
|
|
2169
2171
|
// Use the transitioned cached map.
|
2170
|
-
|
2171
|
-
|
2172
|
-
mov(map_in_out,
|
2172
|
+
offset = transitioned_kind * kPointerSize +
|
2173
|
+
FixedArrayBase::kHeaderSize;
|
2174
|
+
mov(map_in_out, FieldOperand(scratch, offset));
|
2173
2175
|
}
|
2174
2176
|
|
2175
2177
|
|
2176
2178
|
void MacroAssembler::LoadInitialArrayMap(
|
2177
|
-
Register function_in, Register scratch,
|
2179
|
+
Register function_in, Register scratch,
|
2180
|
+
Register map_out, bool can_have_holes) {
|
2178
2181
|
ASSERT(!function_in.is(map_out));
|
2179
2182
|
Label done;
|
2180
2183
|
mov(map_out, FieldOperand(function_in,
|
2181
2184
|
JSFunction::kPrototypeOrInitialMapOffset));
|
2182
2185
|
if (!FLAG_smi_only_arrays) {
|
2183
|
-
|
2184
|
-
|
2186
|
+
ElementsKind kind = can_have_holes ? FAST_HOLEY_ELEMENTS : FAST_ELEMENTS;
|
2187
|
+
LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
|
2188
|
+
kind,
|
2189
|
+
map_out,
|
2190
|
+
scratch,
|
2191
|
+
&done);
|
2192
|
+
} else if (can_have_holes) {
|
2193
|
+
LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
|
2194
|
+
FAST_HOLEY_SMI_ELEMENTS,
|
2185
2195
|
map_out,
|
2186
2196
|
scratch,
|
2187
2197
|
&done);
|
@@ -2566,7 +2576,7 @@ bool AreAliased(Register r1, Register r2, Register r3, Register r4) {
|
|
2566
2576
|
CodePatcher::CodePatcher(byte* address, int size)
|
2567
2577
|
: address_(address),
|
2568
2578
|
size_(size),
|
2569
|
-
masm_(
|
2579
|
+
masm_(NULL, address, size + Assembler::kGap) {
|
2570
2580
|
// Create a new macro assembler pointing to the address of the code to patch.
|
2571
2581
|
// The size is adjusted with kGap on order for the assembler to generate size
|
2572
2582
|
// bytes of instructions without failing with buffer size constraints.
|
@@ -235,7 +235,8 @@ class MacroAssembler: public Assembler {
|
|
235
235
|
// Load the initial map for new Arrays from a JSFunction.
|
236
236
|
void LoadInitialArrayMap(Register function_in,
|
237
237
|
Register scratch,
|
238
|
-
Register map_out
|
238
|
+
Register map_out,
|
239
|
+
bool can_have_holes);
|
239
240
|
|
240
241
|
// Load the global function with the given index.
|
241
242
|
void LoadGlobalFunction(int index, Register function);
|
@@ -357,9 +358,9 @@ class MacroAssembler: public Assembler {
|
|
357
358
|
|
358
359
|
// Check if a map for a JSObject indicates that the object has fast smi only
|
359
360
|
// elements. Jump to the specified label if it does not.
|
360
|
-
void
|
361
|
-
|
362
|
-
|
361
|
+
void CheckFastSmiElements(Register map,
|
362
|
+
Label* fail,
|
363
|
+
Label::Distance distance = Label::kFar);
|
363
364
|
|
364
365
|
// Check to see if maybe_number can be stored as a double in
|
365
366
|
// 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:
|
@@ -42,28 +42,30 @@ namespace internal {
|
|
42
42
|
#ifndef V8_INTERPRETED_REGEXP
|
43
43
|
/*
|
44
44
|
* This assembler uses the following register assignment convention
|
45
|
-
* - edx :
|
46
|
-
* before using any of the dispatch methods.
|
47
|
-
*
|
45
|
+
* - edx : Current character. Must be loaded using LoadCurrentCharacter
|
46
|
+
* before using any of the dispatch methods. Temporarily stores the
|
47
|
+
* index of capture start after a matching pass for a global regexp.
|
48
|
+
* - edi : Current position in input, as negative offset from end of string.
|
48
49
|
* Please notice that this is the byte offset, not the character offset!
|
49
50
|
* - esi : end of input (points to byte after last character in input).
|
50
|
-
* - ebp :
|
51
|
+
* - ebp : Frame pointer. Used to access arguments, local variables and
|
51
52
|
* RegExp registers.
|
52
|
-
* - esp :
|
53
|
-
* - ecx :
|
53
|
+
* - esp : Points to tip of C stack.
|
54
|
+
* - ecx : Points to tip of backtrack stack
|
54
55
|
*
|
55
56
|
* The registers eax and ebx are free to use for computations.
|
56
57
|
*
|
57
58
|
* Each call to a public method should retain this convention.
|
58
59
|
* The stack will have the following structure:
|
59
|
-
* - Isolate* isolate (
|
60
|
+
* - Isolate* isolate (address of the current isolate)
|
60
61
|
* - direct_call (if 1, direct call from JavaScript code, if 0
|
61
62
|
* call through the runtime system)
|
62
|
-
* - stack_area_base (
|
63
|
+
* - stack_area_base (high end of the memory area to use as
|
63
64
|
* backtracking stack)
|
65
|
+
* - capture array size (may fit multiple sets of matches)
|
64
66
|
* - int* capture_array (int[num_saved_registers_], for output).
|
65
|
-
* - end of input (
|
66
|
-
* - start of input (
|
67
|
+
* - end of input (address of end of string)
|
68
|
+
* - start of input (address of first character in string)
|
67
69
|
* - start index (character index of start)
|
68
70
|
* - String* input_string (location of a handle containing the string)
|
69
71
|
* --- frame alignment (if applicable) ---
|
@@ -72,9 +74,10 @@ namespace internal {
|
|
72
74
|
* - backup of caller esi
|
73
75
|
* - backup of caller edi
|
74
76
|
* - backup of caller ebx
|
77
|
+
* - success counter (only for global regexps to count matches).
|
75
78
|
* - Offset of location before start of input (effectively character
|
76
79
|
* position -1). Used to initialize capture registers to a non-position.
|
77
|
-
* - register 0 ebp[-4] (
|
80
|
+
* - register 0 ebp[-4] (only positions must be stored in the first
|
78
81
|
* - register 1 ebp[-8] num_saved_registers_ registers)
|
79
82
|
* - ...
|
80
83
|
*
|
@@ -706,13 +709,16 @@ bool RegExpMacroAssemblerIA32::CheckSpecialCharacterClass(uc16 type,
|
|
706
709
|
|
707
710
|
|
708
711
|
void RegExpMacroAssemblerIA32::Fail() {
|
709
|
-
|
710
|
-
|
712
|
+
STATIC_ASSERT(FAILURE == 0); // Return value for failure is zero.
|
713
|
+
if (!global()) {
|
714
|
+
__ Set(eax, Immediate(FAILURE));
|
715
|
+
}
|
711
716
|
__ jmp(&exit_label_);
|
712
717
|
}
|
713
718
|
|
714
719
|
|
715
720
|
Handle<HeapObject> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
|
721
|
+
Label return_eax;
|
716
722
|
// Finalize code - write the entry point code now we know how many
|
717
723
|
// registers we need.
|
718
724
|
|
@@ -731,6 +737,7 @@ Handle<HeapObject> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
|
|
731
737
|
__ push(esi);
|
732
738
|
__ push(edi);
|
733
739
|
__ push(ebx); // Callee-save on MacOS.
|
740
|
+
__ push(Immediate(0)); // Number of successful matches in a global regexp.
|
734
741
|
__ push(Immediate(0)); // Make room for "input start - 1" constant.
|
735
742
|
|
736
743
|
// Check if we have space on the stack for registers.
|
@@ -750,13 +757,13 @@ Handle<HeapObject> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
|
|
750
757
|
// Exit with OutOfMemory exception. There is not enough space on the stack
|
751
758
|
// for our working registers.
|
752
759
|
__ mov(eax, EXCEPTION);
|
753
|
-
__ jmp(&
|
760
|
+
__ jmp(&return_eax);
|
754
761
|
|
755
762
|
__ bind(&stack_limit_hit);
|
756
763
|
CallCheckStackGuardState(ebx);
|
757
764
|
__ or_(eax, eax);
|
758
765
|
// If returned value is non-zero, we exit with the returned value as result.
|
759
|
-
__ j(not_zero, &
|
766
|
+
__ j(not_zero, &return_eax);
|
760
767
|
|
761
768
|
__ bind(&stack_ok);
|
762
769
|
// Load start index for later use.
|
@@ -783,19 +790,8 @@ Handle<HeapObject> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
|
|
783
790
|
// position registers.
|
784
791
|
__ mov(Operand(ebp, kInputStartMinusOne), eax);
|
785
792
|
|
786
|
-
|
787
|
-
|
788
|
-
// Fill in stack push order, to avoid accessing across an unwritten
|
789
|
-
// page (a problem on Windows).
|
790
|
-
__ mov(ecx, kRegisterZero);
|
791
|
-
Label init_loop;
|
792
|
-
__ bind(&init_loop);
|
793
|
-
__ mov(Operand(ebp, ecx, times_1, +0), eax);
|
794
|
-
__ sub(ecx, Immediate(kPointerSize));
|
795
|
-
__ cmp(ecx, kRegisterZero - num_saved_registers_ * kPointerSize);
|
796
|
-
__ j(greater, &init_loop);
|
797
|
-
}
|
798
|
-
// Ensure that we have written to each stack page, in order. Skipping a page
|
793
|
+
#ifdef WIN32
|
794
|
+
// Ensure that we write to each stack page, in order. Skipping a page
|
799
795
|
// on Windows can cause segmentation faults. Assuming page size is 4k.
|
800
796
|
const int kPageSize = 4096;
|
801
797
|
const int kRegistersPerPage = kPageSize / kPointerSize;
|
@@ -804,20 +800,45 @@ Handle<HeapObject> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
|
|
804
800
|
i += kRegistersPerPage) {
|
805
801
|
__ mov(register_location(i), eax); // One write every page.
|
806
802
|
}
|
803
|
+
#endif // WIN32
|
804
|
+
|
805
|
+
Label load_char_start_regexp, start_regexp;
|
806
|
+
// Load newline if index is at start, previous character otherwise.
|
807
|
+
__ cmp(Operand(ebp, kStartIndex), Immediate(0));
|
808
|
+
__ j(not_equal, &load_char_start_regexp, Label::kNear);
|
809
|
+
__ mov(current_character(), '\n');
|
810
|
+
__ jmp(&start_regexp, Label::kNear);
|
807
811
|
|
812
|
+
// Global regexp restarts matching here.
|
813
|
+
__ bind(&load_char_start_regexp);
|
814
|
+
// Load previous char as initial value of current character register.
|
815
|
+
LoadCurrentCharacterUnchecked(-1, 1);
|
816
|
+
__ bind(&start_regexp);
|
817
|
+
|
818
|
+
// Initialize on-stack registers.
|
819
|
+
if (num_saved_registers_ > 0) { // Always is, if generated from a regexp.
|
820
|
+
// Fill saved registers with initial value = start offset - 1
|
821
|
+
// Fill in stack push order, to avoid accessing across an unwritten
|
822
|
+
// page (a problem on Windows).
|
823
|
+
if (num_saved_registers_ > 8) {
|
824
|
+
__ mov(ecx, kRegisterZero);
|
825
|
+
Label init_loop;
|
826
|
+
__ bind(&init_loop);
|
827
|
+
__ mov(Operand(ebp, ecx, times_1, 0), eax);
|
828
|
+
__ sub(ecx, Immediate(kPointerSize));
|
829
|
+
__ cmp(ecx, kRegisterZero - num_saved_registers_ * kPointerSize);
|
830
|
+
__ j(greater, &init_loop);
|
831
|
+
} else { // Unroll the loop.
|
832
|
+
for (int i = 0; i < num_saved_registers_; i++) {
|
833
|
+
__ mov(register_location(i), eax);
|
834
|
+
}
|
835
|
+
}
|
836
|
+
}
|
808
837
|
|
809
838
|
// Initialize backtrack stack pointer.
|
810
839
|
__ mov(backtrack_stackpointer(), Operand(ebp, kStackHighEnd));
|
811
|
-
// Load previous char as initial value of current-character.
|
812
|
-
Label at_start;
|
813
|
-
__ cmp(Operand(ebp, kStartIndex), Immediate(0));
|
814
|
-
__ j(equal, &at_start);
|
815
|
-
LoadCurrentCharacterUnchecked(-1, 1); // Load previous char.
|
816
|
-
__ jmp(&start_label_);
|
817
|
-
__ bind(&at_start);
|
818
|
-
__ mov(current_character(), '\n');
|
819
|
-
__ jmp(&start_label_);
|
820
840
|
|
841
|
+
__ jmp(&start_label_);
|
821
842
|
|
822
843
|
// Exit code:
|
823
844
|
if (success_label_.is_linked()) {
|
@@ -836,6 +857,10 @@ Handle<HeapObject> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
|
|
836
857
|
}
|
837
858
|
for (int i = 0; i < num_saved_registers_; i++) {
|
838
859
|
__ mov(eax, register_location(i));
|
860
|
+
if (i == 0 && global()) {
|
861
|
+
// Keep capture start in edx for the zero-length check later.
|
862
|
+
__ mov(edx, eax);
|
863
|
+
}
|
839
864
|
// Convert to index from start of string, not end.
|
840
865
|
__ add(eax, ecx);
|
841
866
|
if (mode_ == UC16) {
|
@@ -844,10 +869,54 @@ Handle<HeapObject> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
|
|
844
869
|
__ mov(Operand(ebx, i * kPointerSize), eax);
|
845
870
|
}
|
846
871
|
}
|
847
|
-
|
872
|
+
|
873
|
+
if (global()) {
|
874
|
+
// Restart matching if the regular expression is flagged as global.
|
875
|
+
// Increment success counter.
|
876
|
+
__ inc(Operand(ebp, kSuccessfulCaptures));
|
877
|
+
// Capture results have been stored, so the number of remaining global
|
878
|
+
// output registers is reduced by the number of stored captures.
|
879
|
+
__ mov(ecx, Operand(ebp, kNumOutputRegisters));
|
880
|
+
__ sub(ecx, Immediate(num_saved_registers_));
|
881
|
+
// Check whether we have enough room for another set of capture results.
|
882
|
+
__ cmp(ecx, Immediate(num_saved_registers_));
|
883
|
+
__ j(less, &exit_label_);
|
884
|
+
|
885
|
+
__ mov(Operand(ebp, kNumOutputRegisters), ecx);
|
886
|
+
// Advance the location for output.
|
887
|
+
__ add(Operand(ebp, kRegisterOutput),
|
888
|
+
Immediate(num_saved_registers_ * kPointerSize));
|
889
|
+
|
890
|
+
// Prepare eax to initialize registers with its value in the next run.
|
891
|
+
__ mov(eax, Operand(ebp, kInputStartMinusOne));
|
892
|
+
|
893
|
+
// Special case for zero-length matches.
|
894
|
+
// edx: capture start index
|
895
|
+
__ cmp(edi, edx);
|
896
|
+
// Not a zero-length match, restart.
|
897
|
+
__ j(not_equal, &load_char_start_regexp);
|
898
|
+
// edi (offset from the end) is zero if we already reached the end.
|
899
|
+
__ test(edi, edi);
|
900
|
+
__ j(zero, &exit_label_, Label::kNear);
|
901
|
+
// Advance current position after a zero-length match.
|
902
|
+
if (mode_ == UC16) {
|
903
|
+
__ add(edi, Immediate(2));
|
904
|
+
} else {
|
905
|
+
__ inc(edi);
|
906
|
+
}
|
907
|
+
__ jmp(&load_char_start_regexp);
|
908
|
+
} else {
|
909
|
+
__ mov(eax, Immediate(SUCCESS));
|
910
|
+
}
|
848
911
|
}
|
849
|
-
|
912
|
+
|
850
913
|
__ bind(&exit_label_);
|
914
|
+
if (global()) {
|
915
|
+
// Return the number of successful captures.
|
916
|
+
__ mov(eax, Operand(ebp, kSuccessfulCaptures));
|
917
|
+
}
|
918
|
+
|
919
|
+
__ bind(&return_eax);
|
851
920
|
// Skip esp past regexp registers.
|
852
921
|
__ lea(esp, Operand(ebp, kBackup_ebx));
|
853
922
|
// Restore callee-save registers.
|
@@ -877,7 +946,7 @@ Handle<HeapObject> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
|
|
877
946
|
__ or_(eax, eax);
|
878
947
|
// If returning non-zero, we should end execution with the given
|
879
948
|
// result as return value.
|
880
|
-
__ j(not_zero, &
|
949
|
+
__ j(not_zero, &return_eax);
|
881
950
|
|
882
951
|
__ pop(edi);
|
883
952
|
__ pop(backtrack_stackpointer());
|
@@ -924,7 +993,7 @@ Handle<HeapObject> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
|
|
924
993
|
__ bind(&exit_with_exception);
|
925
994
|
// Exit with Result EXCEPTION(-1) to signal thrown exception.
|
926
995
|
__ mov(eax, EXCEPTION);
|
927
|
-
__ jmp(&
|
996
|
+
__ jmp(&return_eax);
|
928
997
|
}
|
929
998
|
|
930
999
|
CodeDesc code_desc;
|
@@ -1043,8 +1112,9 @@ void RegExpMacroAssemblerIA32::SetRegister(int register_index, int to) {
|
|
1043
1112
|
}
|
1044
1113
|
|
1045
1114
|
|
1046
|
-
|
1115
|
+
bool RegExpMacroAssemblerIA32::Succeed() {
|
1047
1116
|
__ jmp(&success_label_);
|
1117
|
+
return global();
|
1048
1118
|
}
|
1049
1119
|
|
1050
1120
|
|