Skip to content

Commit fa0ce10

Browse files
Version 3.31.0 (based on 50a829b)
Classes: Partial fix for constructor not calling super (issues 3661, 3672). Performance and stability improvements on all platforms. git-svn-id: https://v8.googlecode.com/svn/trunk@25239 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
1 parent c0d6ccd commit fa0ce10

File tree

91 files changed

+3952
-689
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

91 files changed

+3952
-689
lines changed

Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ endif
6464
ifeq ($(verifyheap), on)
6565
GYPFLAGS += -Dv8_enable_verify_heap=1
6666
endif
67+
# tracemaps=on
68+
ifeq ($(tracemaps), on)
69+
GYPFLAGS += -Dv8_trace_maps=1
70+
endif
6771
# backtrace=off
6872
ifeq ($(backtrace), off)
6973
GYPFLAGS += -Dv8_enable_backtrace=0

build/features.gypi

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@
3939

4040
'v8_enable_verify_heap%': 0,
4141

42+
'v8_trace_maps%': 0,
43+
4244
'v8_use_snapshot%': 'true',
4345

4446
'v8_enable_verify_predictable%': 0,
@@ -77,6 +79,9 @@
7779
['v8_enable_verify_heap==1', {
7880
'defines': ['VERIFY_HEAP',],
7981
}],
82+
['v8_trace_maps==1', {
83+
'defines': ['TRACE_MAPS',],
84+
}],
8085
['v8_enable_verify_predictable==1', {
8186
'defines': ['VERIFY_PREDICTABLE',],
8287
}],

build/toolchain.gypi

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -852,7 +852,8 @@
852852
'V8_ENABLE_CHECKS',
853853
'OBJECT_PRINT',
854854
'VERIFY_HEAP',
855-
'DEBUG'
855+
'DEBUG',
856+
'TRACE_MAPS'
856857
],
857858
'conditions': [
858859
['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="netbsd" or \

include/v8.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6110,7 +6110,7 @@ class Internals {
61106110
static const int kNullValueRootIndex = 7;
61116111
static const int kTrueValueRootIndex = 8;
61126112
static const int kFalseValueRootIndex = 9;
6113-
static const int kEmptyStringRootIndex = 154;
6113+
static const int kEmptyStringRootIndex = 155;
61146114

61156115
// The external allocation limit should be below 256 MB on all architectures
61166116
// to avoid that resource-constrained embedders run low on memory.

src/api.cc

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3636,7 +3636,9 @@ static inline bool ObjectSetAccessor(Object* obj,
36363636
i::JSObject::SetAccessor(Utils::OpenHandle(obj), info),
36373637
false);
36383638
if (result->IsUndefined()) return false;
3639-
if (fast) i::JSObject::MigrateSlowToFast(Utils::OpenHandle(obj), 0);
3639+
if (fast) {
3640+
i::JSObject::MigrateSlowToFast(Utils::OpenHandle(obj), 0, "APISetAccessor");
3641+
}
36403642
return true;
36413643
}
36423644

@@ -3822,7 +3824,8 @@ void v8::Object::TurnOnAccessCheck() {
38223824
// as optimized code does not always handle access checks.
38233825
i::Deoptimizer::DeoptimizeGlobalObject(*obj);
38243826

3825-
i::Handle<i::Map> new_map = i::Map::Copy(i::Handle<i::Map>(obj->map()));
3827+
i::Handle<i::Map> new_map =
3828+
i::Map::Copy(i::Handle<i::Map>(obj->map()), "APITurnOnAccessCheck");
38263829
new_map->set_is_access_check_needed(true);
38273830
i::JSObject::MigrateToMap(obj, new_map);
38283831
}

src/arm/assembler-arm.cc

Lines changed: 96 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1798,71 +1798,119 @@ void Assembler::pkhtb(Register dst,
17981798
}
17991799

18001800

1801-
void Assembler::uxtb(Register dst,
1802-
const Operand& src,
1803-
Condition cond) {
1801+
void Assembler::sxtb(Register dst, Register src, int rotate, Condition cond) {
1802+
// Instruction details available in ARM DDI 0406C.b, A8.8.233.
1803+
// cond(31-28) | 01101010(27-20) | 1111(19-16) |
1804+
// Rd(15-12) | rotate(11-10) | 00(9-8)| 0111(7-4) | Rm(3-0)
1805+
DCHECK(!dst.is(pc));
1806+
DCHECK(!src.is(pc));
1807+
DCHECK(rotate == 0 || rotate == 8 || rotate == 16 || rotate == 24);
1808+
emit(cond | 0x6A * B20 | 0xF * B16 | dst.code() * B12 |
1809+
((rotate >> 1) & 0xC) * B8 | 7 * B4 | src.code());
1810+
}
1811+
1812+
1813+
void Assembler::sxtab(Register dst, Register src1, Register src2, int rotate,
1814+
Condition cond) {
1815+
// Instruction details available in ARM DDI 0406C.b, A8.8.233.
1816+
// cond(31-28) | 01101010(27-20) | Rn(19-16) |
1817+
// Rd(15-12) | rotate(11-10) | 00(9-8)| 0111(7-4) | Rm(3-0)
1818+
DCHECK(!dst.is(pc));
1819+
DCHECK(!src1.is(pc));
1820+
DCHECK(!src2.is(pc));
1821+
DCHECK(rotate == 0 || rotate == 8 || rotate == 16 || rotate == 24);
1822+
emit(cond | 0x6A * B20 | src1.code() * B16 | dst.code() * B12 |
1823+
((rotate >> 1) & 0xC) * B8 | 7 * B4 | src2.code());
1824+
}
1825+
1826+
1827+
void Assembler::sxth(Register dst, Register src, int rotate, Condition cond) {
1828+
// Instruction details available in ARM DDI 0406C.b, A8.8.235.
1829+
// cond(31-28) | 01101011(27-20) | 1111(19-16) |
1830+
// Rd(15-12) | rotate(11-10) | 00(9-8)| 0111(7-4) | Rm(3-0)
1831+
DCHECK(!dst.is(pc));
1832+
DCHECK(!src.is(pc));
1833+
DCHECK(rotate == 0 || rotate == 8 || rotate == 16 || rotate == 24);
1834+
emit(cond | 0x6B * B20 | 0xF * B16 | dst.code() * B12 |
1835+
((rotate >> 1) & 0xC) * B8 | 7 * B4 | src.code());
1836+
}
1837+
1838+
1839+
void Assembler::sxtah(Register dst, Register src1, Register src2, int rotate,
1840+
Condition cond) {
1841+
// Instruction details available in ARM DDI 0406C.b, A8.8.235.
1842+
// cond(31-28) | 01101011(27-20) | Rn(19-16) |
1843+
// Rd(15-12) | rotate(11-10) | 00(9-8)| 0111(7-4) | Rm(3-0)
1844+
DCHECK(!dst.is(pc));
1845+
DCHECK(!src1.is(pc));
1846+
DCHECK(!src2.is(pc));
1847+
DCHECK(rotate == 0 || rotate == 8 || rotate == 16 || rotate == 24);
1848+
emit(cond | 0x6B * B20 | src1.code() * B16 | dst.code() * B12 |
1849+
((rotate >> 1) & 0xC) * B8 | 7 * B4 | src2.code());
1850+
}
1851+
1852+
1853+
void Assembler::uxtb(Register dst, Register src, int rotate, Condition cond) {
18041854
// Instruction details available in ARM DDI 0406C.b, A8.8.274.
18051855
// cond(31-28) | 01101110(27-20) | 1111(19-16) |
18061856
// Rd(15-12) | rotate(11-10) | 00(9-8)| 0111(7-4) | Rm(3-0)
18071857
DCHECK(!dst.is(pc));
1808-
DCHECK(!src.rm().is(pc));
1809-
DCHECK(!src.rm().is(no_reg));
1810-
DCHECK(src.rs().is(no_reg));
1811-
DCHECK((src.shift_imm_ == 0) ||
1812-
(src.shift_imm_ == 8) ||
1813-
(src.shift_imm_ == 16) ||
1814-
(src.shift_imm_ == 24));
1815-
// Operand maps ROR #0 to LSL #0.
1816-
DCHECK((src.shift_op() == ROR) ||
1817-
((src.shift_op() == LSL) && (src.shift_imm_ == 0)));
1818-
emit(cond | 0x6E*B20 | 0xF*B16 | dst.code()*B12 |
1819-
((src.shift_imm_ >> 1)&0xC)*B8 | 7*B4 | src.rm().code());
1820-
}
1821-
1822-
1823-
void Assembler::uxtab(Register dst,
1824-
Register src1,
1825-
const Operand& src2,
1858+
DCHECK(!src.is(pc));
1859+
DCHECK(rotate == 0 || rotate == 8 || rotate == 16 || rotate == 24);
1860+
emit(cond | 0x6E * B20 | 0xF * B16 | dst.code() * B12 |
1861+
((rotate >> 1) & 0xC) * B8 | 7 * B4 | src.code());
1862+
}
1863+
1864+
1865+
void Assembler::uxtab(Register dst, Register src1, Register src2, int rotate,
18261866
Condition cond) {
18271867
// Instruction details available in ARM DDI 0406C.b, A8.8.271.
18281868
// cond(31-28) | 01101110(27-20) | Rn(19-16) |
18291869
// Rd(15-12) | rotate(11-10) | 00(9-8)| 0111(7-4) | Rm(3-0)
18301870
DCHECK(!dst.is(pc));
18311871
DCHECK(!src1.is(pc));
1832-
DCHECK(!src2.rm().is(pc));
1833-
DCHECK(!src2.rm().is(no_reg));
1834-
DCHECK(src2.rs().is(no_reg));
1835-
DCHECK((src2.shift_imm_ == 0) ||
1836-
(src2.shift_imm_ == 8) ||
1837-
(src2.shift_imm_ == 16) ||
1838-
(src2.shift_imm_ == 24));
1839-
// Operand maps ROR #0 to LSL #0.
1840-
DCHECK((src2.shift_op() == ROR) ||
1841-
((src2.shift_op() == LSL) && (src2.shift_imm_ == 0)));
1842-
emit(cond | 0x6E*B20 | src1.code()*B16 | dst.code()*B12 |
1843-
((src2.shift_imm_ >> 1) &0xC)*B8 | 7*B4 | src2.rm().code());
1872+
DCHECK(!src2.is(pc));
1873+
DCHECK(rotate == 0 || rotate == 8 || rotate == 16 || rotate == 24);
1874+
emit(cond | 0x6E * B20 | src1.code() * B16 | dst.code() * B12 |
1875+
((rotate >> 1) & 0xC) * B8 | 7 * B4 | src2.code());
18441876
}
18451877

18461878

1847-
void Assembler::uxtb16(Register dst,
1848-
const Operand& src,
1849-
Condition cond) {
1879+
void Assembler::uxtb16(Register dst, Register src, int rotate, Condition cond) {
18501880
// Instruction details available in ARM DDI 0406C.b, A8.8.275.
18511881
// cond(31-28) | 01101100(27-20) | 1111(19-16) |
18521882
// Rd(15-12) | rotate(11-10) | 00(9-8)| 0111(7-4) | Rm(3-0)
18531883
DCHECK(!dst.is(pc));
1854-
DCHECK(!src.rm().is(pc));
1855-
DCHECK(!src.rm().is(no_reg));
1856-
DCHECK(src.rs().is(no_reg));
1857-
DCHECK((src.shift_imm_ == 0) ||
1858-
(src.shift_imm_ == 8) ||
1859-
(src.shift_imm_ == 16) ||
1860-
(src.shift_imm_ == 24));
1861-
// Operand maps ROR #0 to LSL #0.
1862-
DCHECK((src.shift_op() == ROR) ||
1863-
((src.shift_op() == LSL) && (src.shift_imm_ == 0)));
1864-
emit(cond | 0x6C*B20 | 0xF*B16 | dst.code()*B12 |
1865-
((src.shift_imm_ >> 1)&0xC)*B8 | 7*B4 | src.rm().code());
1884+
DCHECK(!src.is(pc));
1885+
DCHECK(rotate == 0 || rotate == 8 || rotate == 16 || rotate == 24);
1886+
emit(cond | 0x6C * B20 | 0xF * B16 | dst.code() * B12 |
1887+
((rotate >> 1) & 0xC) * B8 | 7 * B4 | src.code());
1888+
}
1889+
1890+
1891+
void Assembler::uxth(Register dst, Register src, int rotate, Condition cond) {
1892+
// Instruction details available in ARM DDI 0406C.b, A8.8.276.
1893+
// cond(31-28) | 01101111(27-20) | 1111(19-16) |
1894+
// Rd(15-12) | rotate(11-10) | 00(9-8)| 0111(7-4) | Rm(3-0)
1895+
DCHECK(!dst.is(pc));
1896+
DCHECK(!src.is(pc));
1897+
DCHECK(rotate == 0 || rotate == 8 || rotate == 16 || rotate == 24);
1898+
emit(cond | 0x6F * B20 | 0xF * B16 | dst.code() * B12 |
1899+
((rotate >> 1) & 0xC) * B8 | 7 * B4 | src.code());
1900+
}
1901+
1902+
1903+
void Assembler::uxtah(Register dst, Register src1, Register src2, int rotate,
1904+
Condition cond) {
1905+
// Instruction details available in ARM DDI 0406C.b, A8.8.273.
1906+
// cond(31-28) | 01101111(27-20) | Rn(19-16) |
1907+
// Rd(15-12) | rotate(11-10) | 00(9-8)| 0111(7-4) | Rm(3-0)
1908+
DCHECK(!dst.is(pc));
1909+
DCHECK(!src1.is(pc));
1910+
DCHECK(!src2.is(pc));
1911+
DCHECK(rotate == 0 || rotate == 8 || rotate == 16 || rotate == 24);
1912+
emit(cond | 0x6F * B20 | src1.code() * B16 | dst.code() * B12 |
1913+
((rotate >> 1) & 0xC) * B8 | 7 * B4 | src2.code());
18661914
}
18671915

18681916

src/arm/assembler-arm.h

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1034,12 +1034,20 @@ class Assembler : public AssemblerBase {
10341034
void pkhtb(Register dst, Register src1, const Operand& src2,
10351035
Condition cond = al);
10361036

1037-
void uxtb(Register dst, const Operand& src, Condition cond = al);
1038-
1039-
void uxtab(Register dst, Register src1, const Operand& src2,
1037+
void sxtb(Register dst, Register src, int rotate = 0, Condition cond = al);
1038+
void sxtab(Register dst, Register src1, Register src2, int rotate = 0,
1039+
Condition cond = al);
1040+
void sxth(Register dst, Register src, int rotate = 0, Condition cond = al);
1041+
void sxtah(Register dst, Register src1, Register src2, int rotate = 0,
10401042
Condition cond = al);
10411043

1042-
void uxtb16(Register dst, const Operand& src, Condition cond = al);
1044+
void uxtb(Register dst, Register src, int rotate = 0, Condition cond = al);
1045+
void uxtab(Register dst, Register src1, Register src2, int rotate = 0,
1046+
Condition cond = al);
1047+
void uxtb16(Register dst, Register src, int rotate = 0, Condition cond = al);
1048+
void uxth(Register dst, Register src, int rotate = 0, Condition cond = al);
1049+
void uxtah(Register dst, Register src1, Register src2, int rotate = 0,
1050+
Condition cond = al);
10431051

10441052
// Status register access instructions
10451053

src/arm/code-stubs-arm.cc

Lines changed: 61 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2686,6 +2686,10 @@ void CallIC_ArrayStub::Generate(MacroAssembler* masm) {
26862686
void CallICStub::Generate(MacroAssembler* masm) {
26872687
// r1 - function
26882688
// r3 - slot id (Smi)
2689+
const int with_types_offset =
2690+
FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex);
2691+
const int generic_offset =
2692+
FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex);
26892693
Label extra_checks_or_miss, slow_start;
26902694
Label slow, non_function, wrap, cont;
26912695
Label have_js_function;
@@ -2724,37 +2728,70 @@ void CallICStub::Generate(MacroAssembler* masm) {
27242728
}
27252729

27262730
__ bind(&extra_checks_or_miss);
2727-
Label miss;
2731+
Label uninitialized, miss;
27282732

27292733
__ CompareRoot(r4, Heap::kmegamorphic_symbolRootIndex);
27302734
__ b(eq, &slow_start);
2735+
2736+
// The following cases attempt to handle MISS cases without going to the
2737+
// runtime.
2738+
if (FLAG_trace_ic) {
2739+
__ jmp(&miss);
2740+
}
2741+
27312742
__ CompareRoot(r4, Heap::kuninitialized_symbolRootIndex);
2743+
__ b(eq, &uninitialized);
2744+
2745+
// We are going megamorphic. If the feedback is a JSFunction, it is fine
2746+
// to handle it here. More complex cases are dealt with in the runtime.
2747+
__ AssertNotSmi(r4);
2748+
__ CompareObjectType(r4, r5, r5, JS_FUNCTION_TYPE);
2749+
__ b(ne, &miss);
2750+
__ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3));
2751+
__ LoadRoot(ip, Heap::kmegamorphic_symbolRootIndex);
2752+
__ str(ip, FieldMemOperand(r4, FixedArray::kHeaderSize));
2753+
// We have to update statistics for runtime profiling.
2754+
__ ldr(r4, FieldMemOperand(r2, with_types_offset));
2755+
__ sub(r4, r4, Operand(Smi::FromInt(1)));
2756+
__ str(r4, FieldMemOperand(r2, with_types_offset));
2757+
__ ldr(r4, FieldMemOperand(r2, generic_offset));
2758+
__ add(r4, r4, Operand(Smi::FromInt(1)));
2759+
__ str(r4, FieldMemOperand(r2, generic_offset));
2760+
__ jmp(&slow_start);
2761+
2762+
__ bind(&uninitialized);
2763+
2764+
// We are going monomorphic, provided we actually have a JSFunction.
2765+
__ JumpIfSmi(r1, &miss);
2766+
2767+
// Goto miss case if we do not have a function.
2768+
__ CompareObjectType(r1, r4, r4, JS_FUNCTION_TYPE);
2769+
__ b(ne, &miss);
2770+
2771+
// Make sure the function is not the Array() function, which requires special
2772+
// behavior on MISS.
2773+
__ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, r4);
2774+
__ cmp(r1, r4);
27322775
__ b(eq, &miss);
27332776

2734-
if (!FLAG_trace_ic) {
2735-
// We are going megamorphic. If the feedback is a JSFunction, it is fine
2736-
// to handle it here. More complex cases are dealt with in the runtime.
2737-
__ AssertNotSmi(r4);
2738-
__ CompareObjectType(r4, r5, r5, JS_FUNCTION_TYPE);
2739-
__ b(ne, &miss);
2740-
__ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3));
2741-
__ LoadRoot(ip, Heap::kmegamorphic_symbolRootIndex);
2742-
__ str(ip, FieldMemOperand(r4, FixedArray::kHeaderSize));
2743-
// We have to update statistics for runtime profiling.
2744-
const int with_types_offset =
2745-
FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex);
2746-
__ ldr(r4, FieldMemOperand(r2, with_types_offset));
2747-
__ sub(r4, r4, Operand(Smi::FromInt(1)));
2748-
__ str(r4, FieldMemOperand(r2, with_types_offset));
2749-
const int generic_offset =
2750-
FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex);
2751-
__ ldr(r4, FieldMemOperand(r2, generic_offset));
2752-
__ add(r4, r4, Operand(Smi::FromInt(1)));
2753-
__ str(r4, FieldMemOperand(r2, generic_offset));
2754-
__ jmp(&slow_start);
2755-
}
2777+
// Update stats.
2778+
__ ldr(r4, FieldMemOperand(r2, with_types_offset));
2779+
__ add(r4, r4, Operand(Smi::FromInt(1)));
2780+
__ str(r4, FieldMemOperand(r2, with_types_offset));
2781+
2782+
// Store the function.
2783+
__ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3));
2784+
__ add(r4, r4, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
2785+
__ str(r1, MemOperand(r4, 0));
2786+
2787+
// Update the write barrier.
2788+
__ mov(r5, r1);
2789+
__ RecordWrite(r2, r4, r5, kLRHasNotBeenSaved, kDontSaveFPRegs,
2790+
EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
2791+
__ jmp(&have_js_function);
27562792

2757-
// We are here because tracing is on or we are going monomorphic.
2793+
// We are here because tracing is on or we encountered a MISS case we can't
2794+
// handle here.
27582795
__ bind(&miss);
27592796
GenerateMiss(masm);
27602797

src/arm/codegen-arm.cc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -288,8 +288,8 @@ MemCopyUint16Uint8Function CreateMemCopyUint16Uint8Function(
288288

289289
__ bind(&loop);
290290
__ ldr(temp1, MemOperand(src, 4, PostIndex));
291-
__ uxtb16(temp3, Operand(temp1, ROR, 0));
292-
__ uxtb16(temp4, Operand(temp1, ROR, 8));
291+
__ uxtb16(temp3, temp1);
292+
__ uxtb16(temp4, temp1, 8);
293293
__ pkhbt(temp1, temp3, Operand(temp4, LSL, 16));
294294
__ str(temp1, MemOperand(dest));
295295
__ pkhtb(temp1, temp4, Operand(temp3, ASR, 16));
@@ -301,9 +301,9 @@ MemCopyUint16Uint8Function CreateMemCopyUint16Uint8Function(
301301
__ mov(chars, Operand(chars, LSL, 31), SetCC); // bit0 => ne, bit1 => cs
302302
__ b(&not_two, cc);
303303
__ ldrh(temp1, MemOperand(src, 2, PostIndex));
304-
__ uxtb(temp3, Operand(temp1, ROR, 8));
304+
__ uxtb(temp3, temp1, 8);
305305
__ mov(temp3, Operand(temp3, LSL, 16));
306-
__ uxtab(temp3, temp3, Operand(temp1, ROR, 0));
306+
__ uxtab(temp3, temp3, temp1);
307307
__ str(temp3, MemOperand(dest, 4, PostIndex));
308308
__ bind(&not_two);
309309
__ ldrb(temp1, MemOperand(src), ne);

0 commit comments

Comments
 (0)