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

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

Issue 7618040: Version 3.5.5. (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
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
« no previous file with comments | « src/apinatives.js ('k') | src/arm/deoptimizer-arm.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 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 1595 matching lines...) Expand 10 before | Expand all | Expand 10 after
1606 // The stub expects its argument in the tos_ register and returns its result in 1606 // The stub expects its argument in the tos_ register and returns its result in
1607 // it, too: zero for false, and a non-zero value for true. 1607 // it, too: zero for false, and a non-zero value for true.
1608 void ToBooleanStub::Generate(MacroAssembler* masm) { 1608 void ToBooleanStub::Generate(MacroAssembler* masm) {
1609 // This stub uses VFP3 instructions. 1609 // This stub uses VFP3 instructions.
1610 CpuFeatures::Scope scope(VFP3); 1610 CpuFeatures::Scope scope(VFP3);
1611 1611
1612 Label patch; 1612 Label patch;
1613 const Register map = r9.is(tos_) ? r7 : r9; 1613 const Register map = r9.is(tos_) ? r7 : r9;
1614 1614
1615 // undefined -> false. 1615 // undefined -> false.
1616 CheckOddball(masm, UNDEFINED, Heap::kUndefinedValueRootIndex, false, &patch); 1616 CheckOddball(masm, UNDEFINED, Heap::kUndefinedValueRootIndex, false);
1617 1617
1618 // Boolean -> its value. 1618 // Boolean -> its value.
1619 CheckOddball(masm, BOOLEAN, Heap::kFalseValueRootIndex, false, &patch); 1619 CheckOddball(masm, BOOLEAN, Heap::kFalseValueRootIndex, false);
1620 CheckOddball(masm, BOOLEAN, Heap::kTrueValueRootIndex, true, &patch); 1620 CheckOddball(masm, BOOLEAN, Heap::kTrueValueRootIndex, true);
1621 1621
1622 // 'null' -> false. 1622 // 'null' -> false.
1623 CheckOddball(masm, NULL_TYPE, Heap::kNullValueRootIndex, false, &patch); 1623 CheckOddball(masm, NULL_TYPE, Heap::kNullValueRootIndex, false);
1624 1624
1625 if (types_.Contains(SMI)) { 1625 if (types_.Contains(SMI)) {
1626 // Smis: 0 -> false, all other -> true 1626 // Smis: 0 -> false, all other -> true
1627 __ tst(tos_, Operand(kSmiTagMask)); 1627 __ tst(tos_, Operand(kSmiTagMask));
1628 // tos_ contains the correct return value already 1628 // tos_ contains the correct return value already
1629 __ Ret(eq); 1629 __ Ret(eq);
1630 } else if (types_.NeedsMap()) { 1630 } else if (types_.NeedsMap()) {
1631 // If we need a map later and have a Smi -> patch. 1631 // If we need a map later and have a Smi -> patch.
1632 __ JumpIfSmi(tos_, &patch); 1632 __ JumpIfSmi(tos_, &patch);
1633 } 1633 }
1634 1634
1635 if (types_.NeedsMap()) { 1635 if (types_.NeedsMap()) {
1636 __ ldr(map, FieldMemOperand(tos_, HeapObject::kMapOffset)); 1636 __ ldr(map, FieldMemOperand(tos_, HeapObject::kMapOffset));
1637 1637
1638 // Everything with a map could be undetectable, so check this now. 1638 if (types_.CanBeUndetectable()) {
1639 __ ldrb(ip, FieldMemOperand(map, Map::kBitFieldOffset)); 1639 __ ldrb(ip, FieldMemOperand(map, Map::kBitFieldOffset));
1640 __ tst(ip, Operand(1 << Map::kIsUndetectable)); 1640 __ tst(ip, Operand(1 << Map::kIsUndetectable));
1641 // Undetectable -> false. 1641 // Undetectable -> false.
1642 __ mov(tos_, Operand(0, RelocInfo::NONE), LeaveCC, ne); 1642 __ mov(tos_, Operand(0, RelocInfo::NONE), LeaveCC, ne);
1643 __ Ret(ne); 1643 __ Ret(ne);
1644 }
1644 } 1645 }
1645 1646
1646 if (types_.Contains(SPEC_OBJECT)) { 1647 if (types_.Contains(SPEC_OBJECT)) {
1647 // Spec object -> true. 1648 // Spec object -> true.
1648 __ CompareInstanceType(map, ip, FIRST_SPEC_OBJECT_TYPE); 1649 __ CompareInstanceType(map, ip, FIRST_SPEC_OBJECT_TYPE);
1649 // tos_ contains the correct non-zero return value already. 1650 // tos_ contains the correct non-zero return value already.
1650 __ Ret(ge); 1651 __ Ret(ge);
1651 } else if (types_.Contains(INTERNAL_OBJECT)) {
1652 // We've seen a spec object for the first time -> patch.
1653 __ CompareInstanceType(map, ip, FIRST_SPEC_OBJECT_TYPE);
1654 __ b(ge, &patch);
1655 } 1652 }
1656 1653
1657 if (types_.Contains(STRING)) { 1654 if (types_.Contains(STRING)) {
1658 // String value -> false iff empty. 1655 // String value -> false iff empty.
1659 __ CompareInstanceType(map, ip, FIRST_NONSTRING_TYPE); 1656 __ CompareInstanceType(map, ip, FIRST_NONSTRING_TYPE);
1660 __ ldr(tos_, FieldMemOperand(tos_, String::kLengthOffset), lt); 1657 __ ldr(tos_, FieldMemOperand(tos_, String::kLengthOffset), lt);
1661 __ Ret(lt); // the string length is OK as the return value 1658 __ Ret(lt); // the string length is OK as the return value
1662 } else if (types_.Contains(INTERNAL_OBJECT)) {
1663 // We've seen a string for the first time -> patch
1664 __ CompareInstanceType(map, ip, FIRST_NONSTRING_TYPE);
1665 __ b(lt, &patch);
1666 } 1659 }
1667 1660
1668 if (types_.Contains(HEAP_NUMBER)) { 1661 if (types_.Contains(HEAP_NUMBER)) {
1669 // Heap number -> false iff +0, -0, or NaN. 1662 // Heap number -> false iff +0, -0, or NaN.
1670 Label not_heap_number; 1663 Label not_heap_number;
1671 __ CompareRoot(map, Heap::kHeapNumberMapRootIndex); 1664 __ CompareRoot(map, Heap::kHeapNumberMapRootIndex);
1672 __ b(ne, &not_heap_number); 1665 __ b(ne, &not_heap_number);
1673 __ vldr(d1, FieldMemOperand(tos_, HeapNumber::kValueOffset)); 1666 __ vldr(d1, FieldMemOperand(tos_, HeapNumber::kValueOffset));
1674 __ VFPCompareAndSetFlags(d1, 0.0); 1667 __ VFPCompareAndSetFlags(d1, 0.0);
1675 // "tos_" is a register, and contains a non zero value by default. 1668 // "tos_" is a register, and contains a non zero value by default.
1676 // Hence we only need to overwrite "tos_" with zero to return false for 1669 // Hence we only need to overwrite "tos_" with zero to return false for
1677 // FP_ZERO or FP_NAN cases. Otherwise, by default it returns true. 1670 // FP_ZERO or FP_NAN cases. Otherwise, by default it returns true.
1678 __ mov(tos_, Operand(0, RelocInfo::NONE), LeaveCC, eq); // for FP_ZERO 1671 __ mov(tos_, Operand(0, RelocInfo::NONE), LeaveCC, eq); // for FP_ZERO
1679 __ mov(tos_, Operand(0, RelocInfo::NONE), LeaveCC, vs); // for FP_NAN 1672 __ mov(tos_, Operand(0, RelocInfo::NONE), LeaveCC, vs); // for FP_NAN
1680 __ Ret(); 1673 __ Ret();
1681 __ bind(&not_heap_number); 1674 __ bind(&not_heap_number);
1682 } else if (types_.Contains(INTERNAL_OBJECT)) {
1683 // We've seen a heap number for the first time -> patch
1684 __ CompareRoot(map, Heap::kHeapNumberMapRootIndex);
1685 __ b(eq, &patch);
1686 } 1675 }
1687 1676
1688 if (types_.Contains(INTERNAL_OBJECT)) { 1677 __ bind(&patch);
1689 // Internal objects -> true. 1678 GenerateTypeTransition(masm);
1690 __ mov(tos_, Operand(1, RelocInfo::NONE));
1691 __ Ret();
1692 }
1693
1694 if (!types_.IsAll()) {
1695 __ bind(&patch);
1696 GenerateTypeTransition(masm);
1697 }
1698 } 1679 }
1699 1680
1700 1681
1701 void ToBooleanStub::CheckOddball(MacroAssembler* masm, 1682 void ToBooleanStub::CheckOddball(MacroAssembler* masm,
1702 Type type, 1683 Type type,
1703 Heap::RootListIndex value, 1684 Heap::RootListIndex value,
1704 bool result, 1685 bool result) {
1705 Label* patch) {
1706 if (types_.Contains(type)) { 1686 if (types_.Contains(type)) {
1707 // If we see an expected oddball, return its ToBoolean value tos_. 1687 // If we see an expected oddball, return its ToBoolean value tos_.
1708 __ LoadRoot(ip, value); 1688 __ LoadRoot(ip, value);
1709 __ cmp(tos_, ip); 1689 __ cmp(tos_, ip);
1710 // The value of a root is never NULL, so we can avoid loading a non-null 1690 // The value of a root is never NULL, so we can avoid loading a non-null
1711 // value into tos_ when we want to return 'true'. 1691 // value into tos_ when we want to return 'true'.
1712 if (!result) { 1692 if (!result) {
1713 __ mov(tos_, Operand(0, RelocInfo::NONE), LeaveCC, eq); 1693 __ mov(tos_, Operand(0, RelocInfo::NONE), LeaveCC, eq);
1714 } 1694 }
1715 __ Ret(eq); 1695 __ Ret(eq);
1716 } else if (types_.Contains(INTERNAL_OBJECT)) {
1717 // If we see an unexpected oddball and handle internal objects, we must
1718 // patch because the code for internal objects doesn't handle it explictly.
1719 __ LoadRoot(ip, value);
1720 __ cmp(tos_, ip);
1721 __ b(eq, patch);
1722 } 1696 }
1723 } 1697 }
1724 1698
1725 1699
1726 void ToBooleanStub::GenerateTypeTransition(MacroAssembler* masm) { 1700 void ToBooleanStub::GenerateTypeTransition(MacroAssembler* masm) {
1727 if (!tos_.is(r3)) { 1701 if (!tos_.is(r3)) {
1728 __ mov(r3, Operand(tos_)); 1702 __ mov(r3, Operand(tos_));
1729 } 1703 }
1730 __ mov(r2, Operand(Smi::FromInt(tos_.code()))); 1704 __ mov(r2, Operand(Smi::FromInt(tos_.code())));
1731 __ mov(r1, Operand(Smi::FromInt(types_.ToByte()))); 1705 __ mov(r1, Operand(Smi::FromInt(types_.ToByte())));
(...skipping 4606 matching lines...) Expand 10 before | Expand all | Expand 10 after
6338 __ ldr(pc, MemOperand(sp, 0)); 6312 __ ldr(pc, MemOperand(sp, 0));
6339 } 6313 }
6340 6314
6341 6315
6342 void DirectCEntryStub::GenerateCall(MacroAssembler* masm, 6316 void DirectCEntryStub::GenerateCall(MacroAssembler* masm,
6343 ExternalReference function) { 6317 ExternalReference function) {
6344 __ mov(lr, Operand(reinterpret_cast<intptr_t>(GetCode().location()), 6318 __ mov(lr, Operand(reinterpret_cast<intptr_t>(GetCode().location()),
6345 RelocInfo::CODE_TARGET)); 6319 RelocInfo::CODE_TARGET));
6346 __ mov(r2, Operand(function)); 6320 __ mov(r2, Operand(function));
6347 // Push return address (accessible to GC through exit frame pc). 6321 // Push return address (accessible to GC through exit frame pc).
6348 __ str(pc, MemOperand(sp, 0)); 6322 // Note that using pc with str is deprecated.
6323 __ add(ip, pc, Operand(4));
6324 __ str(ip, MemOperand(sp, 0));
6349 __ Jump(r2); // Call the api function. 6325 __ Jump(r2); // Call the api function.
6350 } 6326 }
6351 6327
6352 6328
6353 void DirectCEntryStub::GenerateCall(MacroAssembler* masm, 6329 void DirectCEntryStub::GenerateCall(MacroAssembler* masm,
6354 Register target) { 6330 Register target) {
6355 __ mov(lr, Operand(reinterpret_cast<intptr_t>(GetCode().location()), 6331 __ mov(lr, Operand(reinterpret_cast<intptr_t>(GetCode().location()),
6356 RelocInfo::CODE_TARGET)); 6332 RelocInfo::CODE_TARGET));
6357 // Push return address (accessible to GC through exit frame pc). 6333 // Push return address (accessible to GC through exit frame pc).
6358 __ str(pc, MemOperand(sp, 0)); 6334 // Note that using pc with str is deprecated.
6335 __ add(ip, pc, Operand(4));
6336 __ str(ip, MemOperand(sp, 0));
6359 __ Jump(target); // Call the C++ function. 6337 __ Jump(target); // Call the C++ function.
6360 } 6338 }
6361 6339
6362 6340
6363 MaybeObject* StringDictionaryLookupStub::GenerateNegativeLookup( 6341 MaybeObject* StringDictionaryLookupStub::GenerateNegativeLookup(
6364 MacroAssembler* masm, 6342 MacroAssembler* masm,
6365 Label* miss, 6343 Label* miss,
6366 Label* done, 6344 Label* done,
6367 Register receiver, 6345 Register receiver,
6368 Register properties, 6346 Register properties,
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
6591 __ mov(result, Operand(0)); 6569 __ mov(result, Operand(0));
6592 __ Ret(); 6570 __ Ret();
6593 } 6571 }
6594 6572
6595 6573
6596 #undef __ 6574 #undef __
6597 6575
6598 } } // namespace v8::internal 6576 } } // namespace v8::internal
6599 6577
6600 #endif // V8_TARGET_ARCH_ARM 6578 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/apinatives.js ('k') | src/arm/deoptimizer-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698