Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1202)

Side by Side Diff: src/x64/code-stubs-x64.cc

Issue 153913002: A64: Synchronize with r16756. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/x64/builtins-x64.cc ('k') | src/x64/codegen-x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 991 matching lines...) Expand 10 before | Expand all | Expand 10 after
1002 Register heap_number_map = r8; 1002 Register heap_number_map = r8;
1003 Register scratch1 = r9; 1003 Register scratch1 = r9;
1004 Register scratch2 = r10; 1004 Register scratch2 = r10;
1005 // HeapNumbers containing 32bit integer values are also allowed. 1005 // HeapNumbers containing 32bit integer values are also allowed.
1006 __ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex); 1006 __ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex);
1007 __ cmpq(FieldOperand(input, HeapObject::kMapOffset), heap_number_map); 1007 __ cmpq(FieldOperand(input, HeapObject::kMapOffset), heap_number_map);
1008 __ j(not_equal, fail); 1008 __ j(not_equal, fail);
1009 __ movsd(xmm0, FieldOperand(input, HeapNumber::kValueOffset)); 1009 __ movsd(xmm0, FieldOperand(input, HeapNumber::kValueOffset));
1010 // Convert, convert back, and compare the two doubles' bits. 1010 // Convert, convert back, and compare the two doubles' bits.
1011 __ cvttsd2siq(scratch2, xmm0); 1011 __ cvttsd2siq(scratch2, xmm0);
1012 __ cvtlsi2sd(xmm1, scratch2); 1012 __ Cvtlsi2sd(xmm1, scratch2);
1013 __ movq(scratch1, xmm0); 1013 __ movq(scratch1, xmm0);
1014 __ movq(scratch2, xmm1); 1014 __ movq(scratch2, xmm1);
1015 __ cmpq(scratch1, scratch2); 1015 __ cmpq(scratch1, scratch2);
1016 __ j(not_equal, fail); 1016 __ j(not_equal, fail);
1017 __ bind(&ok); 1017 __ bind(&ok);
1018 } 1018 }
1019 1019
1020 1020
1021 void BinaryOpStub::GenerateNumberStub(MacroAssembler* masm) { 1021 void BinaryOpStub::GenerateNumberStub(MacroAssembler* masm) {
1022 Label gc_required, not_number; 1022 Label gc_required, not_number;
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
1138 Label input_not_smi, loaded; 1138 Label input_not_smi, loaded;
1139 1139
1140 // Test that rax is a number. 1140 // Test that rax is a number.
1141 StackArgumentsAccessor args(rsp, 1, ARGUMENTS_DONT_CONTAIN_RECEIVER); 1141 StackArgumentsAccessor args(rsp, 1, ARGUMENTS_DONT_CONTAIN_RECEIVER);
1142 __ movq(rax, args.GetArgumentOperand(0)); 1142 __ movq(rax, args.GetArgumentOperand(0));
1143 __ JumpIfNotSmi(rax, &input_not_smi, Label::kNear); 1143 __ JumpIfNotSmi(rax, &input_not_smi, Label::kNear);
1144 // Input is a smi. Untag and load it onto the FPU stack. 1144 // Input is a smi. Untag and load it onto the FPU stack.
1145 // Then load the bits of the double into rbx. 1145 // Then load the bits of the double into rbx.
1146 __ SmiToInteger32(rax, rax); 1146 __ SmiToInteger32(rax, rax);
1147 __ subq(rsp, Immediate(kDoubleSize)); 1147 __ subq(rsp, Immediate(kDoubleSize));
1148 __ cvtlsi2sd(xmm1, rax); 1148 __ Cvtlsi2sd(xmm1, rax);
1149 __ movsd(Operand(rsp, 0), xmm1); 1149 __ movsd(Operand(rsp, 0), xmm1);
1150 __ movq(rbx, xmm1); 1150 __ movq(rbx, xmm1);
1151 __ movq(rdx, xmm1); 1151 __ movq(rdx, xmm1);
1152 __ fld_d(Operand(rsp, 0)); 1152 __ fld_d(Operand(rsp, 0));
1153 __ addq(rsp, Immediate(kDoubleSize)); 1153 __ addq(rsp, Immediate(kDoubleSize));
1154 __ jmp(&loaded, Label::kNear); 1154 __ jmp(&loaded, Label::kNear);
1155 1155
1156 __ bind(&input_not_smi); 1156 __ bind(&input_not_smi);
1157 // Check if input is a HeapNumber. 1157 // Check if input is a HeapNumber.
1158 __ LoadRoot(rbx, Heap::kHeapNumberMapRootIndex); 1158 __ LoadRoot(rbx, Heap::kHeapNumberMapRootIndex);
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after
1470 // Get the untagged integer version of the rax heap number in rcx. 1470 // Get the untagged integer version of the rax heap number in rcx.
1471 __ TruncateHeapNumberToI(rcx, rax); 1471 __ TruncateHeapNumberToI(rcx, rax);
1472 1472
1473 __ bind(&done); 1473 __ bind(&done);
1474 __ movl(rax, r8); 1474 __ movl(rax, r8);
1475 } 1475 }
1476 1476
1477 1477
1478 void FloatingPointHelper::LoadSSE2SmiOperands(MacroAssembler* masm) { 1478 void FloatingPointHelper::LoadSSE2SmiOperands(MacroAssembler* masm) {
1479 __ SmiToInteger32(kScratchRegister, rdx); 1479 __ SmiToInteger32(kScratchRegister, rdx);
1480 __ cvtlsi2sd(xmm0, kScratchRegister); 1480 __ Cvtlsi2sd(xmm0, kScratchRegister);
1481 __ SmiToInteger32(kScratchRegister, rax); 1481 __ SmiToInteger32(kScratchRegister, rax);
1482 __ cvtlsi2sd(xmm1, kScratchRegister); 1482 __ Cvtlsi2sd(xmm1, kScratchRegister);
1483 } 1483 }
1484 1484
1485 1485
1486 void FloatingPointHelper::LoadSSE2UnknownOperands(MacroAssembler* masm, 1486 void FloatingPointHelper::LoadSSE2UnknownOperands(MacroAssembler* masm,
1487 Label* not_numbers) { 1487 Label* not_numbers) {
1488 Label load_smi_rdx, load_nonsmi_rax, load_smi_rax, load_float_rax, done; 1488 Label load_smi_rdx, load_nonsmi_rax, load_smi_rax, load_float_rax, done;
1489 // Load operand in rdx into xmm0, or branch to not_numbers. 1489 // Load operand in rdx into xmm0, or branch to not_numbers.
1490 __ LoadRoot(rcx, Heap::kHeapNumberMapRootIndex); 1490 __ LoadRoot(rcx, Heap::kHeapNumberMapRootIndex);
1491 __ JumpIfSmi(rdx, &load_smi_rdx); 1491 __ JumpIfSmi(rdx, &load_smi_rdx);
1492 __ cmpq(FieldOperand(rdx, HeapObject::kMapOffset), rcx); 1492 __ cmpq(FieldOperand(rdx, HeapObject::kMapOffset), rcx);
1493 __ j(not_equal, not_numbers); // Argument in rdx is not a number. 1493 __ j(not_equal, not_numbers); // Argument in rdx is not a number.
1494 __ movsd(xmm0, FieldOperand(rdx, HeapNumber::kValueOffset)); 1494 __ movsd(xmm0, FieldOperand(rdx, HeapNumber::kValueOffset));
1495 // Load operand in rax into xmm1, or branch to not_numbers. 1495 // Load operand in rax into xmm1, or branch to not_numbers.
1496 __ JumpIfSmi(rax, &load_smi_rax); 1496 __ JumpIfSmi(rax, &load_smi_rax);
1497 1497
1498 __ bind(&load_nonsmi_rax); 1498 __ bind(&load_nonsmi_rax);
1499 __ cmpq(FieldOperand(rax, HeapObject::kMapOffset), rcx); 1499 __ cmpq(FieldOperand(rax, HeapObject::kMapOffset), rcx);
1500 __ j(not_equal, not_numbers); 1500 __ j(not_equal, not_numbers);
1501 __ movsd(xmm1, FieldOperand(rax, HeapNumber::kValueOffset)); 1501 __ movsd(xmm1, FieldOperand(rax, HeapNumber::kValueOffset));
1502 __ jmp(&done); 1502 __ jmp(&done);
1503 1503
1504 __ bind(&load_smi_rdx); 1504 __ bind(&load_smi_rdx);
1505 __ SmiToInteger32(kScratchRegister, rdx); 1505 __ SmiToInteger32(kScratchRegister, rdx);
1506 __ cvtlsi2sd(xmm0, kScratchRegister); 1506 __ Cvtlsi2sd(xmm0, kScratchRegister);
1507 __ JumpIfNotSmi(rax, &load_nonsmi_rax); 1507 __ JumpIfNotSmi(rax, &load_nonsmi_rax);
1508 1508
1509 __ bind(&load_smi_rax); 1509 __ bind(&load_smi_rax);
1510 __ SmiToInteger32(kScratchRegister, rax); 1510 __ SmiToInteger32(kScratchRegister, rax);
1511 __ cvtlsi2sd(xmm1, kScratchRegister); 1511 __ Cvtlsi2sd(xmm1, kScratchRegister);
1512 __ bind(&done); 1512 __ bind(&done);
1513 } 1513 }
1514 1514
1515 1515
1516 void FloatingPointHelper::NumbersToSmis(MacroAssembler* masm, 1516 void FloatingPointHelper::NumbersToSmis(MacroAssembler* masm,
1517 Register first, 1517 Register first,
1518 Register second, 1518 Register second,
1519 Register scratch1, 1519 Register scratch1,
1520 Register scratch2, 1520 Register scratch2,
1521 Register scratch3, 1521 Register scratch3,
(...skipping 12 matching lines...) Expand all
1534 __ j(not_equal, 1534 __ j(not_equal,
1535 (convert_undefined == CONVERT_UNDEFINED_TO_ZERO) 1535 (convert_undefined == CONVERT_UNDEFINED_TO_ZERO)
1536 ? &maybe_undefined_first 1536 ? &maybe_undefined_first
1537 : on_not_smis); 1537 : on_not_smis);
1538 // Convert HeapNumber to smi if possible. 1538 // Convert HeapNumber to smi if possible.
1539 __ movsd(xmm0, FieldOperand(first, HeapNumber::kValueOffset)); 1539 __ movsd(xmm0, FieldOperand(first, HeapNumber::kValueOffset));
1540 __ movq(scratch2, xmm0); 1540 __ movq(scratch2, xmm0);
1541 __ cvttsd2siq(smi_result, xmm0); 1541 __ cvttsd2siq(smi_result, xmm0);
1542 // Check if conversion was successful by converting back and 1542 // Check if conversion was successful by converting back and
1543 // comparing to the original double's bits. 1543 // comparing to the original double's bits.
1544 __ cvtlsi2sd(xmm1, smi_result); 1544 __ Cvtlsi2sd(xmm1, smi_result);
1545 __ movq(kScratchRegister, xmm1); 1545 __ movq(kScratchRegister, xmm1);
1546 __ cmpq(scratch2, kScratchRegister); 1546 __ cmpq(scratch2, kScratchRegister);
1547 __ j(not_equal, on_not_smis); 1547 __ j(not_equal, on_not_smis);
1548 __ Integer32ToSmi(first, smi_result); 1548 __ Integer32ToSmi(first, smi_result);
1549 1549
1550 __ bind(&first_done); 1550 __ bind(&first_done);
1551 __ JumpIfSmi(second, (on_success != NULL) ? on_success : &done); 1551 __ JumpIfSmi(second, (on_success != NULL) ? on_success : &done);
1552 __ bind(&first_smi); 1552 __ bind(&first_smi);
1553 __ AssertNotSmi(second); 1553 __ AssertNotSmi(second);
1554 __ cmpq(FieldOperand(second, HeapObject::kMapOffset), heap_number_map); 1554 __ cmpq(FieldOperand(second, HeapObject::kMapOffset), heap_number_map);
1555 __ j(not_equal, 1555 __ j(not_equal,
1556 (convert_undefined == CONVERT_UNDEFINED_TO_ZERO) 1556 (convert_undefined == CONVERT_UNDEFINED_TO_ZERO)
1557 ? &maybe_undefined_second 1557 ? &maybe_undefined_second
1558 : on_not_smis); 1558 : on_not_smis);
1559 // Convert second to smi, if possible. 1559 // Convert second to smi, if possible.
1560 __ movsd(xmm0, FieldOperand(second, HeapNumber::kValueOffset)); 1560 __ movsd(xmm0, FieldOperand(second, HeapNumber::kValueOffset));
1561 __ movq(scratch2, xmm0); 1561 __ movq(scratch2, xmm0);
1562 __ cvttsd2siq(smi_result, xmm0); 1562 __ cvttsd2siq(smi_result, xmm0);
1563 __ cvtlsi2sd(xmm1, smi_result); 1563 __ Cvtlsi2sd(xmm1, smi_result);
1564 __ movq(kScratchRegister, xmm1); 1564 __ movq(kScratchRegister, xmm1);
1565 __ cmpq(scratch2, kScratchRegister); 1565 __ cmpq(scratch2, kScratchRegister);
1566 __ j(not_equal, on_not_smis); 1566 __ j(not_equal, on_not_smis);
1567 __ Integer32ToSmi(second, smi_result); 1567 __ Integer32ToSmi(second, smi_result);
1568 if (on_success != NULL) { 1568 if (on_success != NULL) {
1569 __ jmp(on_success); 1569 __ jmp(on_success);
1570 } else { 1570 } else {
1571 __ jmp(&done); 1571 __ jmp(&done);
1572 } 1572 }
1573 1573
(...skipping 22 matching lines...) Expand all
1596 const Register scratch = rcx; 1596 const Register scratch = rcx;
1597 const XMMRegister double_result = xmm3; 1597 const XMMRegister double_result = xmm3;
1598 const XMMRegister double_base = xmm2; 1598 const XMMRegister double_base = xmm2;
1599 const XMMRegister double_exponent = xmm1; 1599 const XMMRegister double_exponent = xmm1;
1600 const XMMRegister double_scratch = xmm4; 1600 const XMMRegister double_scratch = xmm4;
1601 1601
1602 Label call_runtime, done, exponent_not_smi, int_exponent; 1602 Label call_runtime, done, exponent_not_smi, int_exponent;
1603 1603
1604 // Save 1 in double_result - we need this several times later on. 1604 // Save 1 in double_result - we need this several times later on.
1605 __ movq(scratch, Immediate(1)); 1605 __ movq(scratch, Immediate(1));
1606 __ cvtlsi2sd(double_result, scratch); 1606 __ Cvtlsi2sd(double_result, scratch);
1607 1607
1608 if (exponent_type_ == ON_STACK) { 1608 if (exponent_type_ == ON_STACK) {
1609 Label base_is_smi, unpack_exponent; 1609 Label base_is_smi, unpack_exponent;
1610 // The exponent and base are supplied as arguments on the stack. 1610 // The exponent and base are supplied as arguments on the stack.
1611 // This can only happen if the stub is called from non-optimized code. 1611 // This can only happen if the stub is called from non-optimized code.
1612 // Load input parameters from stack. 1612 // Load input parameters from stack.
1613 StackArgumentsAccessor args(rsp, 2, ARGUMENTS_DONT_CONTAIN_RECEIVER); 1613 StackArgumentsAccessor args(rsp, 2, ARGUMENTS_DONT_CONTAIN_RECEIVER);
1614 __ movq(base, args.GetArgumentOperand(0)); 1614 __ movq(base, args.GetArgumentOperand(0));
1615 __ movq(exponent, args.GetArgumentOperand(1)); 1615 __ movq(exponent, args.GetArgumentOperand(1));
1616 __ JumpIfSmi(base, &base_is_smi, Label::kNear); 1616 __ JumpIfSmi(base, &base_is_smi, Label::kNear);
1617 __ CompareRoot(FieldOperand(base, HeapObject::kMapOffset), 1617 __ CompareRoot(FieldOperand(base, HeapObject::kMapOffset),
1618 Heap::kHeapNumberMapRootIndex); 1618 Heap::kHeapNumberMapRootIndex);
1619 __ j(not_equal, &call_runtime); 1619 __ j(not_equal, &call_runtime);
1620 1620
1621 __ movsd(double_base, FieldOperand(base, HeapNumber::kValueOffset)); 1621 __ movsd(double_base, FieldOperand(base, HeapNumber::kValueOffset));
1622 __ jmp(&unpack_exponent, Label::kNear); 1622 __ jmp(&unpack_exponent, Label::kNear);
1623 1623
1624 __ bind(&base_is_smi); 1624 __ bind(&base_is_smi);
1625 __ SmiToInteger32(base, base); 1625 __ SmiToInteger32(base, base);
1626 __ cvtlsi2sd(double_base, base); 1626 __ Cvtlsi2sd(double_base, base);
1627 __ bind(&unpack_exponent); 1627 __ bind(&unpack_exponent);
1628 1628
1629 __ JumpIfNotSmi(exponent, &exponent_not_smi, Label::kNear); 1629 __ JumpIfNotSmi(exponent, &exponent_not_smi, Label::kNear);
1630 __ SmiToInteger32(exponent, exponent); 1630 __ SmiToInteger32(exponent, exponent);
1631 __ jmp(&int_exponent); 1631 __ jmp(&int_exponent);
1632 1632
1633 __ bind(&exponent_not_smi); 1633 __ bind(&exponent_not_smi);
1634 __ CompareRoot(FieldOperand(exponent, HeapObject::kMapOffset), 1634 __ CompareRoot(FieldOperand(exponent, HeapObject::kMapOffset),
1635 Heap::kHeapNumberMapRootIndex); 1635 Heap::kHeapNumberMapRootIndex);
1636 __ j(not_equal, &call_runtime); 1636 __ j(not_equal, &call_runtime);
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
1805 __ divsd(double_scratch2, double_result); 1805 __ divsd(double_scratch2, double_result);
1806 __ movsd(double_result, double_scratch2); 1806 __ movsd(double_result, double_scratch2);
1807 // Test whether result is zero. Bail out to check for subnormal result. 1807 // Test whether result is zero. Bail out to check for subnormal result.
1808 // Due to subnormals, x^-y == (1/x)^y does not hold in all cases. 1808 // Due to subnormals, x^-y == (1/x)^y does not hold in all cases.
1809 __ xorps(double_scratch2, double_scratch2); 1809 __ xorps(double_scratch2, double_scratch2);
1810 __ ucomisd(double_scratch2, double_result); 1810 __ ucomisd(double_scratch2, double_result);
1811 // double_exponent aliased as double_scratch2 has already been overwritten 1811 // double_exponent aliased as double_scratch2 has already been overwritten
1812 // and may not have contained the exponent value in the first place when the 1812 // and may not have contained the exponent value in the first place when the
1813 // input was a smi. We reset it with exponent value before bailing out. 1813 // input was a smi. We reset it with exponent value before bailing out.
1814 __ j(not_equal, &done); 1814 __ j(not_equal, &done);
1815 __ cvtlsi2sd(double_exponent, exponent); 1815 __ Cvtlsi2sd(double_exponent, exponent);
1816 1816
1817 // Returning or bailing out. 1817 // Returning or bailing out.
1818 Counters* counters = masm->isolate()->counters(); 1818 Counters* counters = masm->isolate()->counters();
1819 if (exponent_type_ == ON_STACK) { 1819 if (exponent_type_ == ON_STACK) {
1820 // The arguments are still on the stack. 1820 // The arguments are still on the stack.
1821 __ bind(&call_runtime); 1821 __ bind(&call_runtime);
1822 __ TailCallRuntime(Runtime::kMath_pow_cfunction, 2, 1); 1822 __ TailCallRuntime(Runtime::kMath_pow_cfunction, 2, 1);
1823 1823
1824 // The stub is called from non-optimized code, which expects the result 1824 // The stub is called from non-optimized code, which expects the result
1825 // as heap number in rax. 1825 // as heap number in rax.
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1895 } else { 1895 } else {
1896 ASSERT(kind() == Code::LOAD_IC); 1896 ASSERT(kind() == Code::LOAD_IC);
1897 // ----------- S t a t e ------------- 1897 // ----------- S t a t e -------------
1898 // -- rax : receiver 1898 // -- rax : receiver
1899 // -- rcx : name 1899 // -- rcx : name
1900 // -- rsp[0] : return address 1900 // -- rsp[0] : return address
1901 // ----------------------------------- 1901 // -----------------------------------
1902 receiver = rax; 1902 receiver = rax;
1903 } 1903 }
1904 1904
1905 StubCompiler::GenerateLoadStringLength(masm, receiver, r8, r9, &miss, 1905 StubCompiler::GenerateLoadStringLength(masm, receiver, r8, r9, &miss);
1906 support_wrapper_);
1907 __ bind(&miss); 1906 __ bind(&miss);
1908 StubCompiler::TailCallBuiltin( 1907 StubCompiler::TailCallBuiltin(
1909 masm, BaseLoadStoreStubCompiler::MissBuiltin(kind())); 1908 masm, BaseLoadStoreStubCompiler::MissBuiltin(kind()));
1910 } 1909 }
1911 1910
1912 1911
1913 void StoreArrayLengthStub::Generate(MacroAssembler* masm) { 1912 void StoreArrayLengthStub::Generate(MacroAssembler* masm) {
1914 // ----------- S t a t e ------------- 1913 // ----------- S t a t e -------------
1915 // -- rax : value 1914 // -- rax : value
1916 // -- rcx : key 1915 // -- rcx : key
(...skipping 1695 matching lines...) Expand 10 before | Expand all | Expand 10 after
3612 // Check stack alignment. 3611 // Check stack alignment.
3613 if (FLAG_debug_code) { 3612 if (FLAG_debug_code) {
3614 __ CheckStackAlignment(); 3613 __ CheckStackAlignment();
3615 } 3614 }
3616 3615
3617 if (do_gc) { 3616 if (do_gc) {
3618 // Pass failure code returned from last attempt as first argument to 3617 // Pass failure code returned from last attempt as first argument to
3619 // PerformGC. No need to use PrepareCallCFunction/CallCFunction here as the 3618 // PerformGC. No need to use PrepareCallCFunction/CallCFunction here as the
3620 // stack is known to be aligned. This function takes one argument which is 3619 // stack is known to be aligned. This function takes one argument which is
3621 // passed in register. 3620 // passed in register.
3621 __ movq(arg_reg_2, ExternalReference::isolate_address(masm->isolate()));
3622 __ movq(arg_reg_1, rax); 3622 __ movq(arg_reg_1, rax);
3623 __ movq(kScratchRegister, 3623 __ movq(kScratchRegister,
3624 ExternalReference::perform_gc_function(masm->isolate())); 3624 ExternalReference::perform_gc_function(masm->isolate()));
3625 __ call(kScratchRegister); 3625 __ call(kScratchRegister);
3626 } 3626 }
3627 3627
3628 ExternalReference scope_depth = 3628 ExternalReference scope_depth =
3629 ExternalReference::heap_always_allocate_scope_depth(masm->isolate()); 3629 ExternalReference::heap_always_allocate_scope_depth(masm->isolate());
3630 if (always_allocate_scope) { 3630 if (always_allocate_scope) {
3631 Operand scope_depth_operand = masm->ExternalOperand(scope_depth); 3631 Operand scope_depth_operand = masm->ExternalOperand(scope_depth);
(...skipping 1005 matching lines...) Expand 10 before | Expand all | Expand 10 after
4637 Register scratch2, 4637 Register scratch2,
4638 Register scratch3, 4638 Register scratch3,
4639 Label* slow) { 4639 Label* slow) {
4640 // First check if the argument is already a string. 4640 // First check if the argument is already a string.
4641 Label not_string, done; 4641 Label not_string, done;
4642 __ JumpIfSmi(arg, &not_string); 4642 __ JumpIfSmi(arg, &not_string);
4643 __ CmpObjectType(arg, FIRST_NONSTRING_TYPE, scratch1); 4643 __ CmpObjectType(arg, FIRST_NONSTRING_TYPE, scratch1);
4644 __ j(below, &done); 4644 __ j(below, &done);
4645 4645
4646 // Check the number to string cache. 4646 // Check the number to string cache.
4647 Label not_cached;
4648 __ bind(&not_string); 4647 __ bind(&not_string);
4649 // Puts the cached result into scratch1. 4648 // Puts the cached result into scratch1.
4650 NumberToStringStub::GenerateLookupNumberStringCache(masm, 4649 NumberToStringStub::GenerateLookupNumberStringCache(masm,
4651 arg, 4650 arg,
4652 scratch1, 4651 scratch1,
4653 scratch2, 4652 scratch2,
4654 scratch3, 4653 scratch3,
4655 &not_cached); 4654 slow);
4656 __ movq(arg, scratch1); 4655 __ movq(arg, scratch1);
4657 __ movq(Operand(rsp, stack_offset), arg); 4656 __ movq(Operand(rsp, stack_offset), arg);
4658 __ jmp(&done);
4659
4660 // Check if the argument is a safe string wrapper.
4661 __ bind(&not_cached);
4662 __ JumpIfSmi(arg, slow);
4663 __ CmpObjectType(arg, JS_VALUE_TYPE, scratch1); // map -> scratch1.
4664 __ j(not_equal, slow);
4665 __ testb(FieldOperand(scratch1, Map::kBitField2Offset),
4666 Immediate(1 << Map::kStringWrapperSafeForDefaultValueOf));
4667 __ j(zero, slow);
4668 __ movq(arg, FieldOperand(arg, JSValue::kValueOffset));
4669 __ movq(Operand(rsp, stack_offset), arg);
4670
4671 __ bind(&done); 4657 __ bind(&done);
4672 } 4658 }
4673 4659
4674 4660
4675 void StringHelper::GenerateCopyCharacters(MacroAssembler* masm, 4661 void StringHelper::GenerateCopyCharacters(MacroAssembler* masm,
4676 Register dest, 4662 Register dest,
4677 Register src, 4663 Register src,
4678 Register count, 4664 Register count,
4679 bool ascii) { 4665 bool ascii) {
4680 Label loop; 4666 Label loop;
(...skipping 702 matching lines...) Expand 10 before | Expand all | Expand 10 after
5383 5369
5384 // Load left and right operand. 5370 // Load left and right operand.
5385 Label done, left, left_smi, right_smi; 5371 Label done, left, left_smi, right_smi;
5386 __ JumpIfSmi(rax, &right_smi, Label::kNear); 5372 __ JumpIfSmi(rax, &right_smi, Label::kNear);
5387 __ CompareMap(rax, masm->isolate()->factory()->heap_number_map(), NULL); 5373 __ CompareMap(rax, masm->isolate()->factory()->heap_number_map(), NULL);
5388 __ j(not_equal, &maybe_undefined1, Label::kNear); 5374 __ j(not_equal, &maybe_undefined1, Label::kNear);
5389 __ movsd(xmm1, FieldOperand(rax, HeapNumber::kValueOffset)); 5375 __ movsd(xmm1, FieldOperand(rax, HeapNumber::kValueOffset));
5390 __ jmp(&left, Label::kNear); 5376 __ jmp(&left, Label::kNear);
5391 __ bind(&right_smi); 5377 __ bind(&right_smi);
5392 __ SmiToInteger32(rcx, rax); // Can't clobber rax yet. 5378 __ SmiToInteger32(rcx, rax); // Can't clobber rax yet.
5393 __ cvtlsi2sd(xmm1, rcx); 5379 __ Cvtlsi2sd(xmm1, rcx);
5394 5380
5395 __ bind(&left); 5381 __ bind(&left);
5396 __ JumpIfSmi(rdx, &left_smi, Label::kNear); 5382 __ JumpIfSmi(rdx, &left_smi, Label::kNear);
5397 __ CompareMap(rdx, masm->isolate()->factory()->heap_number_map(), NULL); 5383 __ CompareMap(rdx, masm->isolate()->factory()->heap_number_map(), NULL);
5398 __ j(not_equal, &maybe_undefined2, Label::kNear); 5384 __ j(not_equal, &maybe_undefined2, Label::kNear);
5399 __ movsd(xmm0, FieldOperand(rdx, HeapNumber::kValueOffset)); 5385 __ movsd(xmm0, FieldOperand(rdx, HeapNumber::kValueOffset));
5400 __ jmp(&done); 5386 __ jmp(&done);
5401 __ bind(&left_smi); 5387 __ bind(&left_smi);
5402 __ SmiToInteger32(rcx, rdx); // Can't clobber rdx yet. 5388 __ SmiToInteger32(rcx, rdx); // Can't clobber rdx yet.
5403 __ cvtlsi2sd(xmm0, rcx); 5389 __ Cvtlsi2sd(xmm0, rcx);
5404 5390
5405 __ bind(&done); 5391 __ bind(&done);
5406 // Compare operands 5392 // Compare operands
5407 __ ucomisd(xmm0, xmm1); 5393 __ ucomisd(xmm0, xmm1);
5408 5394
5409 // Don't base result on EFLAGS when a NaN is involved. 5395 // Don't base result on EFLAGS when a NaN is involved.
5410 __ j(parity_even, &unordered, Label::kNear); 5396 __ j(parity_even, &unordered, Label::kNear);
5411 5397
5412 // Return a result of -1, 0, or 1, based on EFLAGS. 5398 // Return a result of -1, 0, or 1, based on EFLAGS.
5413 // Performing mov, because xor would destroy the flag register. 5399 // Performing mov, because xor would destroy the flag register.
(...skipping 905 matching lines...) Expand 10 before | Expand all | Expand 10 after
6319 // Restore volatile regs. 6305 // Restore volatile regs.
6320 masm->PopCallerSaved(kSaveFPRegs, arg_reg_1, arg_reg_2); 6306 masm->PopCallerSaved(kSaveFPRegs, arg_reg_1, arg_reg_2);
6321 __ pop(arg_reg_2); 6307 __ pop(arg_reg_2);
6322 __ pop(arg_reg_1); 6308 __ pop(arg_reg_1);
6323 6309
6324 __ Ret(); 6310 __ Ret();
6325 } 6311 }
6326 6312
6327 6313
6328 template<class T> 6314 template<class T>
6329 static void CreateArrayDispatch(MacroAssembler* masm) { 6315 static void CreateArrayDispatch(MacroAssembler* masm,
6330 int last_index = GetSequenceIndexFromFastElementsKind( 6316 AllocationSiteOverrideMode mode) {
6331 TERMINAL_FAST_ELEMENTS_KIND); 6317 if (mode == DISABLE_ALLOCATION_SITES) {
6332 for (int i = 0; i <= last_index; ++i) { 6318 T stub(GetInitialFastElementsKind(),
6333 Label next; 6319 CONTEXT_CHECK_REQUIRED,
6334 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i); 6320 mode);
6335 __ cmpl(rdx, Immediate(kind));
6336 __ j(not_equal, &next);
6337 T stub(kind);
6338 __ TailCallStub(&stub); 6321 __ TailCallStub(&stub);
6339 __ bind(&next); 6322 } else if (mode == DONT_OVERRIDE) {
6323 int last_index = GetSequenceIndexFromFastElementsKind(
6324 TERMINAL_FAST_ELEMENTS_KIND);
6325 for (int i = 0; i <= last_index; ++i) {
6326 Label next;
6327 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
6328 __ cmpl(rdx, Immediate(kind));
6329 __ j(not_equal, &next);
6330 T stub(kind);
6331 __ TailCallStub(&stub);
6332 __ bind(&next);
6333 }
6334
6335 // If we reached this point there is a problem.
6336 __ Abort(kUnexpectedElementsKindInArrayConstructor);
6337 } else {
6338 UNREACHABLE();
6340 } 6339 }
6341
6342 // If we reached this point there is a problem.
6343 __ Abort(kUnexpectedElementsKindInArrayConstructor);
6344 } 6340 }
6345 6341
6346 6342
6347 static void CreateArrayDispatchOneArgument(MacroAssembler* masm) { 6343 static void CreateArrayDispatchOneArgument(MacroAssembler* masm,
6348 // rbx - type info cell 6344 AllocationSiteOverrideMode mode) {
6349 // rdx - kind 6345 // rbx - type info cell (if mode != DISABLE_ALLOCATION_SITES)
6346 // rdx - kind (if mode != DISABLE_ALLOCATION_SITES)
6350 // rax - number of arguments 6347 // rax - number of arguments
6351 // rdi - constructor? 6348 // rdi - constructor?
6352 // rsp[0] - return address 6349 // rsp[0] - return address
6353 // rsp[8] - last argument 6350 // rsp[8] - last argument
6354 ASSERT(FAST_SMI_ELEMENTS == 0);
6355 ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
6356 ASSERT(FAST_ELEMENTS == 2);
6357 ASSERT(FAST_HOLEY_ELEMENTS == 3);
6358 ASSERT(FAST_DOUBLE_ELEMENTS == 4);
6359 ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == 5);
6360
6361 Handle<Object> undefined_sentinel( 6351 Handle<Object> undefined_sentinel(
6362 masm->isolate()->heap()->undefined_value(), 6352 masm->isolate()->heap()->undefined_value(),
6363 masm->isolate()); 6353 masm->isolate());
6364 6354
6365 // is the low bit set? If so, we are holey and that is good.
6366 __ testb(rdx, Immediate(1));
6367 Label normal_sequence; 6355 Label normal_sequence;
6368 __ j(not_zero, &normal_sequence); 6356 if (mode == DONT_OVERRIDE) {
6357 ASSERT(FAST_SMI_ELEMENTS == 0);
6358 ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
6359 ASSERT(FAST_ELEMENTS == 2);
6360 ASSERT(FAST_HOLEY_ELEMENTS == 3);
6361 ASSERT(FAST_DOUBLE_ELEMENTS == 4);
6362 ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == 5);
6363
6364 // is the low bit set? If so, we are holey and that is good.
6365 __ testb(rdx, Immediate(1));
6366 __ j(not_zero, &normal_sequence);
6367 }
6369 6368
6370 // look at the first argument 6369 // look at the first argument
6371 StackArgumentsAccessor args(rsp, 1, ARGUMENTS_DONT_CONTAIN_RECEIVER); 6370 StackArgumentsAccessor args(rsp, 1, ARGUMENTS_DONT_CONTAIN_RECEIVER);
6372 __ movq(rcx, args.GetArgumentOperand(0)); 6371 __ movq(rcx, args.GetArgumentOperand(0));
6373 __ testq(rcx, rcx); 6372 __ testq(rcx, rcx);
6374 __ j(zero, &normal_sequence); 6373 __ j(zero, &normal_sequence);
6375 6374
6376 // We are going to create a holey array, but our kind is non-holey. 6375 if (mode == DISABLE_ALLOCATION_SITES) {
6377 // Fix kind and retry (only if we have an allocation site in the cell). 6376 ElementsKind initial = GetInitialFastElementsKind();
6378 __ incl(rdx); 6377 ElementsKind holey_initial = GetHoleyElementsKind(initial);
6379 __ Cmp(rbx, undefined_sentinel);
6380 __ j(equal, &normal_sequence);
6381 __ movq(rcx, FieldOperand(rbx, Cell::kValueOffset));
6382 Handle<Map> allocation_site_map(
6383 masm->isolate()->heap()->allocation_site_map(),
6384 masm->isolate());
6385 __ Cmp(FieldOperand(rcx, 0), allocation_site_map);
6386 __ j(not_equal, &normal_sequence);
6387 6378
6388 // Save the resulting elements kind in type info 6379 ArraySingleArgumentConstructorStub stub_holey(holey_initial,
6389 __ Integer32ToSmi(rdx, rdx); 6380 CONTEXT_CHECK_REQUIRED,
6390 __ movq(FieldOperand(rcx, AllocationSite::kTransitionInfoOffset), rdx); 6381 DISABLE_ALLOCATION_SITES);
6391 __ SmiToInteger32(rdx, rdx); 6382 __ TailCallStub(&stub_holey);
6392 6383
6393 __ bind(&normal_sequence); 6384 __ bind(&normal_sequence);
6394 int last_index = GetSequenceIndexFromFastElementsKind( 6385 ArraySingleArgumentConstructorStub stub(initial,
6395 TERMINAL_FAST_ELEMENTS_KIND); 6386 CONTEXT_CHECK_REQUIRED,
6396 for (int i = 0; i <= last_index; ++i) { 6387 DISABLE_ALLOCATION_SITES);
6397 Label next;
6398 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
6399 __ cmpl(rdx, Immediate(kind));
6400 __ j(not_equal, &next);
6401 ArraySingleArgumentConstructorStub stub(kind);
6402 __ TailCallStub(&stub); 6388 __ TailCallStub(&stub);
6403 __ bind(&next); 6389 } else if (mode == DONT_OVERRIDE) {
6390 // We are going to create a holey array, but our kind is non-holey.
6391 // Fix kind and retry (only if we have an allocation site in the cell).
6392 __ incl(rdx);
6393 __ movq(rcx, FieldOperand(rbx, Cell::kValueOffset));
6394 if (FLAG_debug_code) {
6395 Handle<Map> allocation_site_map(
6396 masm->isolate()->heap()->allocation_site_map(),
6397 masm->isolate());
6398 __ Cmp(FieldOperand(rcx, 0), allocation_site_map);
6399 __ Assert(equal, kExpectedAllocationSiteInCell);
6400 }
6401
6402 // Save the resulting elements kind in type info
6403 __ Integer32ToSmi(rdx, rdx);
6404 __ movq(FieldOperand(rcx, AllocationSite::kTransitionInfoOffset), rdx);
6405 __ SmiToInteger32(rdx, rdx);
6406
6407 __ bind(&normal_sequence);
6408 int last_index = GetSequenceIndexFromFastElementsKind(
6409 TERMINAL_FAST_ELEMENTS_KIND);
6410 for (int i = 0; i <= last_index; ++i) {
6411 Label next;
6412 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
6413 __ cmpl(rdx, Immediate(kind));
6414 __ j(not_equal, &next);
6415 ArraySingleArgumentConstructorStub stub(kind);
6416 __ TailCallStub(&stub);
6417 __ bind(&next);
6418 }
6419
6420 // If we reached this point there is a problem.
6421 __ Abort(kUnexpectedElementsKindInArrayConstructor);
6422 } else {
6423 UNREACHABLE();
6404 } 6424 }
6405
6406 // If we reached this point there is a problem.
6407 __ Abort(kUnexpectedElementsKindInArrayConstructor);
6408 } 6425 }
6409 6426
6410 6427
6411 template<class T> 6428 template<class T>
6412 static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) { 6429 static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) {
6430 ElementsKind initial_kind = GetInitialFastElementsKind();
6431 ElementsKind initial_holey_kind = GetHoleyElementsKind(initial_kind);
6432
6413 int to_index = GetSequenceIndexFromFastElementsKind( 6433 int to_index = GetSequenceIndexFromFastElementsKind(
6414 TERMINAL_FAST_ELEMENTS_KIND); 6434 TERMINAL_FAST_ELEMENTS_KIND);
6415 for (int i = 0; i <= to_index; ++i) { 6435 for (int i = 0; i <= to_index; ++i) {
6416 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i); 6436 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
6417 T stub(kind); 6437 T stub(kind);
6418 stub.GetCode(isolate)->set_is_pregenerated(true); 6438 stub.GetCode(isolate)->set_is_pregenerated(true);
6419 if (AllocationSite::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE) { 6439 if (AllocationSite::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE ||
6440 (!FLAG_track_allocation_sites &&
6441 (kind == initial_kind || kind == initial_holey_kind))) {
6420 T stub1(kind, CONTEXT_CHECK_REQUIRED, DISABLE_ALLOCATION_SITES); 6442 T stub1(kind, CONTEXT_CHECK_REQUIRED, DISABLE_ALLOCATION_SITES);
6421 stub1.GetCode(isolate)->set_is_pregenerated(true); 6443 stub1.GetCode(isolate)->set_is_pregenerated(true);
6422 } 6444 }
6423 } 6445 }
6424 } 6446 }
6425 6447
6426 6448
6427 void ArrayConstructorStubBase::GenerateStubsAheadOfTime(Isolate* isolate) { 6449 void ArrayConstructorStubBase::GenerateStubsAheadOfTime(Isolate* isolate) {
6428 ArrayConstructorStubAheadOfTimeHelper<ArrayNoArgumentConstructorStub>( 6450 ArrayConstructorStubAheadOfTimeHelper<ArrayNoArgumentConstructorStub>(
6429 isolate); 6451 isolate);
(...skipping 12 matching lines...) Expand all
6442 InternalArrayNoArgumentConstructorStub stubh1(kinds[i]); 6464 InternalArrayNoArgumentConstructorStub stubh1(kinds[i]);
6443 stubh1.GetCode(isolate)->set_is_pregenerated(true); 6465 stubh1.GetCode(isolate)->set_is_pregenerated(true);
6444 InternalArraySingleArgumentConstructorStub stubh2(kinds[i]); 6466 InternalArraySingleArgumentConstructorStub stubh2(kinds[i]);
6445 stubh2.GetCode(isolate)->set_is_pregenerated(true); 6467 stubh2.GetCode(isolate)->set_is_pregenerated(true);
6446 InternalArrayNArgumentsConstructorStub stubh3(kinds[i]); 6468 InternalArrayNArgumentsConstructorStub stubh3(kinds[i]);
6447 stubh3.GetCode(isolate)->set_is_pregenerated(true); 6469 stubh3.GetCode(isolate)->set_is_pregenerated(true);
6448 } 6470 }
6449 } 6471 }
6450 6472
6451 6473
6474 void ArrayConstructorStub::GenerateDispatchToArrayStub(
6475 MacroAssembler* masm,
6476 AllocationSiteOverrideMode mode) {
6477 if (argument_count_ == ANY) {
6478 Label not_zero_case, not_one_case;
6479 __ testq(rax, rax);
6480 __ j(not_zero, &not_zero_case);
6481 CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm, mode);
6482
6483 __ bind(&not_zero_case);
6484 __ cmpl(rax, Immediate(1));
6485 __ j(greater, &not_one_case);
6486 CreateArrayDispatchOneArgument(masm, mode);
6487
6488 __ bind(&not_one_case);
6489 CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode);
6490 } else if (argument_count_ == NONE) {
6491 CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm, mode);
6492 } else if (argument_count_ == ONE) {
6493 CreateArrayDispatchOneArgument(masm, mode);
6494 } else if (argument_count_ == MORE_THAN_ONE) {
6495 CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode);
6496 } else {
6497 UNREACHABLE();
6498 }
6499 }
6500
6501
6452 void ArrayConstructorStub::Generate(MacroAssembler* masm) { 6502 void ArrayConstructorStub::Generate(MacroAssembler* masm) {
6453 // ----------- S t a t e ------------- 6503 // ----------- S t a t e -------------
6454 // -- rax : argc 6504 // -- rax : argc
6455 // -- rbx : type info cell 6505 // -- rbx : type info cell
6456 // -- rdi : constructor 6506 // -- rdi : constructor
6457 // -- rsp[0] : return address 6507 // -- rsp[0] : return address
6458 // -- rsp[8] : last argument 6508 // -- rsp[8] : last argument
6459 // ----------------------------------- 6509 // -----------------------------------
6460 Handle<Object> undefined_sentinel( 6510 Handle<Object> undefined_sentinel(
6461 masm->isolate()->heap()->undefined_value(), 6511 masm->isolate()->heap()->undefined_value(),
(...skipping 15 matching lines...) Expand all
6477 // We should either have undefined in rbx or a valid cell 6527 // We should either have undefined in rbx or a valid cell
6478 Label okay_here; 6528 Label okay_here;
6479 Handle<Map> cell_map = masm->isolate()->factory()->cell_map(); 6529 Handle<Map> cell_map = masm->isolate()->factory()->cell_map();
6480 __ Cmp(rbx, undefined_sentinel); 6530 __ Cmp(rbx, undefined_sentinel);
6481 __ j(equal, &okay_here); 6531 __ j(equal, &okay_here);
6482 __ Cmp(FieldOperand(rbx, 0), cell_map); 6532 __ Cmp(FieldOperand(rbx, 0), cell_map);
6483 __ Assert(equal, kExpectedPropertyCellInRegisterRbx); 6533 __ Assert(equal, kExpectedPropertyCellInRegisterRbx);
6484 __ bind(&okay_here); 6534 __ bind(&okay_here);
6485 } 6535 }
6486 6536
6487 Label no_info, switch_ready; 6537 Label no_info;
6488 // Get the elements kind and case on that. 6538 // If the type cell is undefined, or contains anything other than an
6539 // AllocationSite, call an array constructor that doesn't use AllocationSites.
6489 __ Cmp(rbx, undefined_sentinel); 6540 __ Cmp(rbx, undefined_sentinel);
6490 __ j(equal, &no_info); 6541 __ j(equal, &no_info);
6491 __ movq(rdx, FieldOperand(rbx, Cell::kValueOffset)); 6542 __ movq(rdx, FieldOperand(rbx, Cell::kValueOffset));
6492
6493 // The type cell may have undefined in its value.
6494 __ Cmp(rdx, undefined_sentinel);
6495 __ j(equal, &no_info);
6496
6497 // The type cell has either an AllocationSite or a JSFunction
6498 __ Cmp(FieldOperand(rdx, 0), 6543 __ Cmp(FieldOperand(rdx, 0),
6499 Handle<Map>(masm->isolate()->heap()->allocation_site_map())); 6544 Handle<Map>(masm->isolate()->heap()->allocation_site_map()));
6500 __ j(not_equal, &no_info); 6545 __ j(not_equal, &no_info);
6501 6546
6502 __ movq(rdx, FieldOperand(rdx, AllocationSite::kTransitionInfoOffset)); 6547 __ movq(rdx, FieldOperand(rdx, AllocationSite::kTransitionInfoOffset));
6503 __ SmiToInteger32(rdx, rdx); 6548 __ SmiToInteger32(rdx, rdx);
6504 __ jmp(&switch_ready); 6549 GenerateDispatchToArrayStub(masm, DONT_OVERRIDE);
6550
6505 __ bind(&no_info); 6551 __ bind(&no_info);
6506 __ movq(rdx, Immediate(GetInitialFastElementsKind())); 6552 GenerateDispatchToArrayStub(masm, DISABLE_ALLOCATION_SITES);
6507 __ bind(&switch_ready);
6508
6509 if (argument_count_ == ANY) {
6510 Label not_zero_case, not_one_case;
6511 __ testq(rax, rax);
6512 __ j(not_zero, &not_zero_case);
6513 CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm);
6514
6515 __ bind(&not_zero_case);
6516 __ cmpl(rax, Immediate(1));
6517 __ j(greater, &not_one_case);
6518 CreateArrayDispatchOneArgument(masm);
6519
6520 __ bind(&not_one_case);
6521 CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm);
6522 } else if (argument_count_ == NONE) {
6523 CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm);
6524 } else if (argument_count_ == ONE) {
6525 CreateArrayDispatchOneArgument(masm);
6526 } else if (argument_count_ == MORE_THAN_ONE) {
6527 CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm);
6528 } else {
6529 UNREACHABLE();
6530 }
6531 } 6553 }
6532 6554
6533 6555
6534 void InternalArrayConstructorStub::GenerateCase( 6556 void InternalArrayConstructorStub::GenerateCase(
6535 MacroAssembler* masm, ElementsKind kind) { 6557 MacroAssembler* masm, ElementsKind kind) {
6536 Label not_zero_case, not_one_case; 6558 Label not_zero_case, not_one_case;
6537 Label normal_sequence; 6559 Label normal_sequence;
6538 6560
6539 __ testq(rax, rax); 6561 __ testq(rax, rax);
6540 __ j(not_zero, &not_zero_case); 6562 __ j(not_zero, &not_zero_case);
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
6619 __ bind(&fast_elements_case); 6641 __ bind(&fast_elements_case);
6620 GenerateCase(masm, FAST_ELEMENTS); 6642 GenerateCase(masm, FAST_ELEMENTS);
6621 } 6643 }
6622 6644
6623 6645
6624 #undef __ 6646 #undef __
6625 6647
6626 } } // namespace v8::internal 6648 } } // namespace v8::internal
6627 6649
6628 #endif // V8_TARGET_ARCH_X64 6650 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/builtins-x64.cc ('k') | src/x64/codegen-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698