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

Side by Side Diff: src/arm/lithium-codegen-arm.cc

Issue 7497063: Simplify and optimize ToBoolean handling. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 9 years, 4 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
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 1565 matching lines...) Expand 10 before | Expand all | Expand 10 after
1576 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1576 Label* false_label = chunk_->GetAssemblyLabel(false_block);
1577 1577
1578 ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types(); 1578 ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types();
1579 // Avoid deopts in the case where we've never executed this path before. 1579 // Avoid deopts in the case where we've never executed this path before.
1580 if (expected.IsEmpty()) expected = ToBooleanStub::all_types(); 1580 if (expected.IsEmpty()) expected = ToBooleanStub::all_types();
1581 1581
1582 if (expected.Contains(ToBooleanStub::UNDEFINED)) { 1582 if (expected.Contains(ToBooleanStub::UNDEFINED)) {
1583 // undefined -> false. 1583 // undefined -> false.
1584 __ CompareRoot(reg, Heap::kUndefinedValueRootIndex); 1584 __ CompareRoot(reg, Heap::kUndefinedValueRootIndex);
1585 __ b(eq, false_label); 1585 __ b(eq, false_label);
1586 } else if (expected.Contains(ToBooleanStub::INTERNAL_OBJECT)) {
1587 // We've seen undefined for the first time -> deopt.
1588 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
1589 DeoptimizeIf(eq, instr->environment());
1590 } 1586 }
1591
1592 if (expected.Contains(ToBooleanStub::BOOLEAN)) { 1587 if (expected.Contains(ToBooleanStub::BOOLEAN)) {
1593 // Boolean -> its value. 1588 // Boolean -> its value.
1594 __ CompareRoot(reg, Heap::kTrueValueRootIndex); 1589 __ CompareRoot(reg, Heap::kTrueValueRootIndex);
1595 __ b(eq, true_label); 1590 __ b(eq, true_label);
1596 __ CompareRoot(reg, Heap::kFalseValueRootIndex); 1591 __ CompareRoot(reg, Heap::kFalseValueRootIndex);
1597 __ b(eq, false_label); 1592 __ b(eq, false_label);
1598 } else if (expected.Contains(ToBooleanStub::INTERNAL_OBJECT)) {
1599 // We've seen a boolean for the first time -> deopt.
1600 __ CompareRoot(reg, Heap::kTrueValueRootIndex);
1601 DeoptimizeIf(eq, instr->environment());
1602 __ CompareRoot(reg, Heap::kFalseValueRootIndex);
1603 DeoptimizeIf(eq, instr->environment());
1604 } 1593 }
1605
1606 #if 0
1607 if (expected.Contains(ToBooleanStub::BOOLEAN)) {
1608 // false -> false.
1609 __ CompareRoot(reg, Heap::kFalseValueRootIndex);
1610 __ b(eq, false_label);
1611 } else if (expected.Contains(ToBooleanStub::INTERNAL_OBJECT)) {
1612 // We've seen a boolean for the first time -> deopt.
1613 __ CompareRoot(reg, Heap::kFalseValueRootIndex);
1614 DeoptimizeIf(eq, instr->environment());
1615 }
1616 #endif
1617
1618 if (expected.Contains(ToBooleanStub::NULL_TYPE)) { 1594 if (expected.Contains(ToBooleanStub::NULL_TYPE)) {
1619 // 'null' -> false. 1595 // 'null' -> false.
1620 __ CompareRoot(reg, Heap::kNullValueRootIndex); 1596 __ CompareRoot(reg, Heap::kNullValueRootIndex);
1621 __ b(eq, false_label); 1597 __ b(eq, false_label);
1622 } else if (expected.Contains(ToBooleanStub::INTERNAL_OBJECT)) {
1623 // We've seen null for the first time -> deopt.
1624 __ CompareRoot(reg, Heap::kNullValueRootIndex);
1625 DeoptimizeIf(eq, instr->environment());
1626 } 1598 }
1627 1599
1628 if (expected.Contains(ToBooleanStub::SMI)) { 1600 if (expected.Contains(ToBooleanStub::SMI)) {
1629 // Smis: 0 -> false, all other -> true. 1601 // Smis: 0 -> false, all other -> true.
1630 __ cmp(reg, Operand(0)); 1602 __ cmp(reg, Operand(0));
1631 __ b(eq, false_label); 1603 __ b(eq, false_label);
1632 __ JumpIfSmi(reg, true_label); 1604 __ JumpIfSmi(reg, true_label);
1633 } else if (expected.NeedsMap()) { 1605 } else if (expected.NeedsMap()) {
1634 // If we need a map later and have a Smi -> deopt. 1606 // If we need a map later and have a Smi -> deopt.
1635 __ tst(reg, Operand(kSmiTagMask)); 1607 __ tst(reg, Operand(kSmiTagMask));
1636 DeoptimizeIf(eq, instr->environment()); 1608 DeoptimizeIf(eq, instr->environment());
1637 } 1609 }
1638 1610
1639 const Register map = scratch0(); 1611 const Register map = scratch0();
1640 if (expected.NeedsMap()) { 1612 if (expected.NeedsMap()) {
1641 __ ldr(map, FieldMemOperand(reg, HeapObject::kMapOffset)); 1613 __ ldr(map, FieldMemOperand(reg, HeapObject::kMapOffset));
1642 // Everything with a map could be undetectable, so check this now. 1614
1643 __ ldrb(ip, FieldMemOperand(map, Map::kBitFieldOffset)); 1615 if (expected.CanBeUndetectable()) {
1644 __ tst(ip, Operand(1 << Map::kIsUndetectable)); 1616 // Undetectable -> false.
1645 __ b(ne, false_label); 1617 __ ldrb(ip, FieldMemOperand(map, Map::kBitFieldOffset));
1618 __ tst(ip, Operand(1 << Map::kIsUndetectable));
1619 __ b(ne, false_label);
1620 }
1646 } 1621 }
1647 1622
1648 if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) { 1623 if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) {
1649 // spec object -> true. 1624 // spec object -> true.
1650 __ CompareInstanceType(map, ip, FIRST_SPEC_OBJECT_TYPE); 1625 __ CompareInstanceType(map, ip, FIRST_SPEC_OBJECT_TYPE);
1651 __ b(ge, true_label); 1626 __ b(ge, true_label);
1652 } else if (expected.Contains(ToBooleanStub::INTERNAL_OBJECT)) {
1653 // We've seen a spec object for the first time -> deopt.
1654 __ CompareInstanceType(map, ip, FIRST_SPEC_OBJECT_TYPE);
1655 DeoptimizeIf(ge, instr->environment());
1656 } 1627 }
1657 1628
1658 if (expected.Contains(ToBooleanStub::STRING)) { 1629 if (expected.Contains(ToBooleanStub::STRING)) {
1659 // String value -> false iff empty. 1630 // String value -> false iff empty.
1660 Label not_string; 1631 Label not_string;
1661 __ CompareInstanceType(map, ip, FIRST_NONSTRING_TYPE); 1632 __ CompareInstanceType(map, ip, FIRST_NONSTRING_TYPE);
1662 __ b(ge, &not_string); 1633 __ b(ge, &not_string);
1663 __ ldr(ip, FieldMemOperand(reg, String::kLengthOffset)); 1634 __ ldr(ip, FieldMemOperand(reg, String::kLengthOffset));
1664 __ cmp(ip, Operand(0)); 1635 __ cmp(ip, Operand(0));
1665 __ b(ne, true_label); 1636 __ b(ne, true_label);
1666 __ b(false_label); 1637 __ b(false_label);
1667 __ bind(&not_string); 1638 __ bind(&not_string);
1668 } else if (expected.Contains(ToBooleanStub::INTERNAL_OBJECT)) {
1669 // We've seen a string for the first time -> deopt
1670 __ CompareInstanceType(map, ip, FIRST_NONSTRING_TYPE);
1671 DeoptimizeIf(lt, instr->environment());
1672 } 1639 }
1673 1640
1674 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { 1641 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) {
1675 // heap number -> false iff +0, -0, or NaN. 1642 // heap number -> false iff +0, -0, or NaN.
1676 DoubleRegister dbl_scratch = double_scratch0(); 1643 DoubleRegister dbl_scratch = double_scratch0();
1677 Label not_heap_number; 1644 Label not_heap_number;
1678 __ CompareRoot(map, Heap::kHeapNumberMapRootIndex); 1645 __ CompareRoot(map, Heap::kHeapNumberMapRootIndex);
1679 __ b(ne, &not_heap_number); 1646 __ b(ne, &not_heap_number);
1680 __ vldr(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset)); 1647 __ vldr(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset));
1681 __ VFPCompareAndSetFlags(dbl_scratch, 0.0); 1648 __ VFPCompareAndSetFlags(dbl_scratch, 0.0);
1682 __ b(vs, false_label); // NaN -> false. 1649 __ b(vs, false_label); // NaN -> false.
1683 __ b(eq, false_label); // +0, -0 -> false. 1650 __ b(eq, false_label); // +0, -0 -> false.
1684 __ b(true_label); 1651 __ b(true_label);
1685 __ bind(&not_heap_number); 1652 __ bind(&not_heap_number);
1686 } else if (expected.Contains(ToBooleanStub::INTERNAL_OBJECT)) {
1687 // We've seen a heap number for the first time -> deopt.
1688 __ CompareRoot(map, Heap::kHeapNumberMapRootIndex);
1689 DeoptimizeIf(eq, instr->environment());
1690 } 1653 }
1691 1654
1692 if (expected.Contains(ToBooleanStub::INTERNAL_OBJECT)) { 1655 // We've seen something for the first time -> deopt.
1693 // internal objects -> true 1656 DeoptimizeIf(al, instr->environment());
1694 __ b(true_label);
1695 } else {
1696 // We've seen something for the first time -> deopt.
1697 DeoptimizeIf(al, instr->environment());
1698 }
1699 } 1657 }
1700 } 1658 }
1701 } 1659 }
1702 1660
1703 1661
1704 void LCodeGen::EmitGoto(int block) { 1662 void LCodeGen::EmitGoto(int block) {
1705 block = chunk_->LookupDestination(block); 1663 block = chunk_->LookupDestination(block);
1706 int next_block = GetNextEmittedBlock(current_block_); 1664 int next_block = GetNextEmittedBlock(current_block_);
1707 if (block != next_block) { 1665 if (block != next_block) {
1708 __ jmp(chunk_->GetAssemblyLabel(block)); 1666 __ jmp(chunk_->GetAssemblyLabel(block));
(...skipping 2862 matching lines...) Expand 10 before | Expand all | Expand 10 after
4571 ASSERT(osr_pc_offset_ == -1); 4529 ASSERT(osr_pc_offset_ == -1);
4572 osr_pc_offset_ = masm()->pc_offset(); 4530 osr_pc_offset_ = masm()->pc_offset();
4573 } 4531 }
4574 4532
4575 4533
4576 4534
4577 4535
4578 #undef __ 4536 #undef __
4579 4537
4580 } } // namespace v8::internal 4538 } } // namespace v8::internal
OLDNEW
« src/apinatives.js ('K') | « src/arm/lithium-arm.cc ('k') | src/code-stubs.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698