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

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

Issue 3166033: Improve the code generated by the full codegen by keeping... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 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 | « no previous file | src/full-codegen.h » ('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 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 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 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
262 break; 262 break;
263 case kStack: 263 case kStack:
264 __ push(reg); 264 __ push(reg);
265 break; 265 break;
266 } 266 }
267 break; 267 break;
268 268
269 case Expression::kTest: 269 case Expression::kTest:
270 // For simplicity we always test the accumulator register. 270 // For simplicity we always test the accumulator register.
271 if (!reg.is(result_register())) __ mov(result_register(), reg); 271 if (!reg.is(result_register())) __ mov(result_register(), reg);
272 DoTest(true_label_, false_label_, NULL); 272 DoTest(true_label_, false_label_, fall_through_);
273 break; 273 break;
274 } 274 }
275 } 275 }
276 276
277 277
278 void FullCodeGenerator::Apply(Expression::Context context, Slot* slot) { 278 void FullCodeGenerator::Apply(Expression::Context context, Slot* slot) {
279 switch (context) { 279 switch (context) {
280 case Expression::kUninitialized: 280 case Expression::kUninitialized:
281 UNREACHABLE(); 281 UNREACHABLE();
282 case Expression::kEffect: 282 case Expression::kEffect:
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
325 case kAccumulator: 325 case kAccumulator:
326 __ pop(result_register()); 326 __ pop(result_register());
327 break; 327 break;
328 case kStack: 328 case kStack:
329 break; 329 break;
330 } 330 }
331 break; 331 break;
332 332
333 case Expression::kTest: 333 case Expression::kTest:
334 __ pop(result_register()); 334 __ pop(result_register());
335 DoTest(true_label_, false_label_, NULL); 335 DoTest(true_label_, false_label_, fall_through_);
336 break; 336 break;
337 } 337 }
338 } 338 }
339 339
340 340
341 void FullCodeGenerator::DropAndApply(int count, 341 void FullCodeGenerator::DropAndApply(int count,
342 Expression::Context context, 342 Expression::Context context,
343 Register reg) { 343 Register reg) {
344 ASSERT(count > 0); 344 ASSERT(count > 0);
345 ASSERT(!reg.is(sp)); 345 ASSERT(!reg.is(sp));
(...skipping 14 matching lines...) Expand all
360 case kStack: 360 case kStack:
361 if (count > 1) __ Drop(count - 1); 361 if (count > 1) __ Drop(count - 1);
362 __ str(reg, MemOperand(sp)); 362 __ str(reg, MemOperand(sp));
363 break; 363 break;
364 } 364 }
365 break; 365 break;
366 366
367 case Expression::kTest: 367 case Expression::kTest:
368 __ Drop(count); 368 __ Drop(count);
369 if (!reg.is(result_register())) __ mov(result_register(), reg); 369 if (!reg.is(result_register())) __ mov(result_register(), reg);
370 DoTest(true_label_, false_label_, NULL); 370 DoTest(true_label_, false_label_, fall_through_);
371 break;
372 }
373 }
374
375 void FullCodeGenerator::PrepareTest(Label* materialize_true,
376 Label* materialize_false,
377 Label** if_true,
378 Label** if_false) {
379 switch (context_) {
380 case Expression::kUninitialized:
381 UNREACHABLE();
382 break;
383 case Expression::kEffect:
384 // In an effect context, the true and the false case branch to the
385 // same label.
386 *if_true = *if_false = materialize_true;
387 break;
388 case Expression::kValue:
389 *if_true = materialize_true;
390 *if_false = materialize_false;
391 break;
392 case Expression::kTest:
393 *if_true = true_label_;
394 *if_false = false_label_;
395 break; 371 break;
396 } 372 }
397 } 373 }
398 374
399 375
400 void FullCodeGenerator::Apply(Expression::Context context, 376 void FullCodeGenerator::Apply(Expression::Context context,
401 Label* materialize_true, 377 Label* materialize_true,
402 Label* materialize_false) { 378 Label* materialize_false) {
403 switch (context) { 379 switch (context) {
404 case Expression::kUninitialized: 380 case Expression::kUninitialized:
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
455 __ LoadRoot(result_register(), value_root_index); 431 __ LoadRoot(result_register(), value_root_index);
456 break; 432 break;
457 case kStack: 433 case kStack:
458 __ LoadRoot(ip, value_root_index); 434 __ LoadRoot(ip, value_root_index);
459 __ push(ip); 435 __ push(ip);
460 break; 436 break;
461 } 437 }
462 break; 438 break;
463 } 439 }
464 case Expression::kTest: 440 case Expression::kTest:
465 __ b(flag ? true_label_ : false_label_); 441 if (flag) {
442 if (true_label_ != fall_through_) __ b(true_label_);
443 } else {
444 if (false_label_ != fall_through_) __ b(false_label_);
445 }
466 break; 446 break;
467 } 447 }
468 } 448 }
469 449
470 450
471 void FullCodeGenerator::DoTest(Label* if_true, 451 void FullCodeGenerator::DoTest(Label* if_true,
472 Label* if_false, 452 Label* if_false,
473 Label* fall_through) { 453 Label* fall_through) {
474 // Call the runtime to find the boolean value of the source and then 454 // Call the runtime to find the boolean value of the source and then
475 // translate it into control flow to the pair of labels. 455 // translate it into control flow to the pair of labels.
(...skipping 1252 matching lines...) Expand 10 before | Expand all | Expand 10 after
1728 1708
1729 1709
1730 void FullCodeGenerator::EmitIsSmi(ZoneList<Expression*>* args) { 1710 void FullCodeGenerator::EmitIsSmi(ZoneList<Expression*>* args) {
1731 ASSERT(args->length() == 1); 1711 ASSERT(args->length() == 1);
1732 1712
1733 VisitForValue(args->at(0), kAccumulator); 1713 VisitForValue(args->at(0), kAccumulator);
1734 1714
1735 Label materialize_true, materialize_false; 1715 Label materialize_true, materialize_false;
1736 Label* if_true = NULL; 1716 Label* if_true = NULL;
1737 Label* if_false = NULL; 1717 Label* if_false = NULL;
1738 PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false); 1718 Label* fall_through = NULL;
1719 PrepareTest(&materialize_true, &materialize_false,
1720 &if_true, &if_false, &fall_through);
1739 1721
1740 __ BranchOnSmi(r0, if_true); 1722 __ BranchOnSmi(r0, if_true);
1741 __ b(if_false); 1723 __ b(if_false);
1742 1724
1743 Apply(context_, if_true, if_false); 1725 Apply(context_, if_true, if_false);
1744 } 1726 }
1745 1727
1746 1728
1747 void FullCodeGenerator::EmitIsNonNegativeSmi(ZoneList<Expression*>* args) { 1729 void FullCodeGenerator::EmitIsNonNegativeSmi(ZoneList<Expression*>* args) {
1748 ASSERT(args->length() == 1); 1730 ASSERT(args->length() == 1);
1749 1731
1750 VisitForValue(args->at(0), kAccumulator); 1732 VisitForValue(args->at(0), kAccumulator);
1751 1733
1752 Label materialize_true, materialize_false; 1734 Label materialize_true, materialize_false;
1753 Label* if_true = NULL; 1735 Label* if_true = NULL;
1754 Label* if_false = NULL; 1736 Label* if_false = NULL;
1755 PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false); 1737 Label* fall_through = NULL;
1738 PrepareTest(&materialize_true, &materialize_false,
1739 &if_true, &if_false, &fall_through);
1756 1740
1757 __ tst(r0, Operand(kSmiTagMask | 0x80000000)); 1741 __ tst(r0, Operand(kSmiTagMask | 0x80000000));
1758 Split(eq, if_true, if_false, NULL); 1742 Split(eq, if_true, if_false, fall_through);
1759 1743
1760 Apply(context_, if_true, if_false); 1744 Apply(context_, if_true, if_false);
1761 } 1745 }
1762 1746
1763 1747
1764 void FullCodeGenerator::EmitIsObject(ZoneList<Expression*>* args) { 1748 void FullCodeGenerator::EmitIsObject(ZoneList<Expression*>* args) {
1765 ASSERT(args->length() == 1); 1749 ASSERT(args->length() == 1);
1766 1750
1767 VisitForValue(args->at(0), kAccumulator); 1751 VisitForValue(args->at(0), kAccumulator);
1768 1752
1769 Label materialize_true, materialize_false; 1753 Label materialize_true, materialize_false;
1770 Label* if_true = NULL; 1754 Label* if_true = NULL;
1771 Label* if_false = NULL; 1755 Label* if_false = NULL;
1772 PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false); 1756 Label* fall_through = NULL;
1757 PrepareTest(&materialize_true, &materialize_false,
1758 &if_true, &if_false, &fall_through);
1759
1773 __ BranchOnSmi(r0, if_false); 1760 __ BranchOnSmi(r0, if_false);
1774 __ LoadRoot(ip, Heap::kNullValueRootIndex); 1761 __ LoadRoot(ip, Heap::kNullValueRootIndex);
1775 __ cmp(r0, ip); 1762 __ cmp(r0, ip);
1776 __ b(eq, if_true); 1763 __ b(eq, if_true);
1777 __ ldr(r2, FieldMemOperand(r0, HeapObject::kMapOffset)); 1764 __ ldr(r2, FieldMemOperand(r0, HeapObject::kMapOffset));
1778 // Undetectable objects behave like undefined when tested with typeof. 1765 // Undetectable objects behave like undefined when tested with typeof.
1779 __ ldrb(r1, FieldMemOperand(r2, Map::kBitFieldOffset)); 1766 __ ldrb(r1, FieldMemOperand(r2, Map::kBitFieldOffset));
1780 __ tst(r1, Operand(1 << Map::kIsUndetectable)); 1767 __ tst(r1, Operand(1 << Map::kIsUndetectable));
1781 __ b(ne, if_false); 1768 __ b(ne, if_false);
1782 __ ldrb(r1, FieldMemOperand(r2, Map::kInstanceTypeOffset)); 1769 __ ldrb(r1, FieldMemOperand(r2, Map::kInstanceTypeOffset));
1783 __ cmp(r1, Operand(FIRST_JS_OBJECT_TYPE)); 1770 __ cmp(r1, Operand(FIRST_JS_OBJECT_TYPE));
1784 __ b(lt, if_false); 1771 __ b(lt, if_false);
1785 __ cmp(r1, Operand(LAST_JS_OBJECT_TYPE)); 1772 __ cmp(r1, Operand(LAST_JS_OBJECT_TYPE));
1786 Split(le, if_true, if_false, NULL); 1773 Split(le, if_true, if_false, fall_through);
1787 1774
1788 Apply(context_, if_true, if_false); 1775 Apply(context_, if_true, if_false);
1789 } 1776 }
1790 1777
1791 1778
1792 void FullCodeGenerator::EmitIsSpecObject(ZoneList<Expression*>* args) { 1779 void FullCodeGenerator::EmitIsSpecObject(ZoneList<Expression*>* args) {
1793 ASSERT(args->length() == 1); 1780 ASSERT(args->length() == 1);
1794 1781
1795 VisitForValue(args->at(0), kAccumulator); 1782 VisitForValue(args->at(0), kAccumulator);
1796 1783
1797 Label materialize_true, materialize_false; 1784 Label materialize_true, materialize_false;
1798 Label* if_true = NULL; 1785 Label* if_true = NULL;
1799 Label* if_false = NULL; 1786 Label* if_false = NULL;
1800 PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false); 1787 Label* fall_through = NULL;
1788 PrepareTest(&materialize_true, &materialize_false,
1789 &if_true, &if_false, &fall_through);
1801 1790
1802 __ BranchOnSmi(r0, if_false); 1791 __ BranchOnSmi(r0, if_false);
1803 __ CompareObjectType(r0, r1, r1, FIRST_JS_OBJECT_TYPE); 1792 __ CompareObjectType(r0, r1, r1, FIRST_JS_OBJECT_TYPE);
1804 Split(ge, if_true, if_false, NULL); 1793 Split(ge, if_true, if_false, fall_through);
1805 1794
1806 Apply(context_, if_true, if_false); 1795 Apply(context_, if_true, if_false);
1807 } 1796 }
1808 1797
1809 1798
1810 void FullCodeGenerator::EmitIsUndetectableObject(ZoneList<Expression*>* args) { 1799 void FullCodeGenerator::EmitIsUndetectableObject(ZoneList<Expression*>* args) {
1811 ASSERT(args->length() == 1); 1800 ASSERT(args->length() == 1);
1812 1801
1813 VisitForValue(args->at(0), kAccumulator); 1802 VisitForValue(args->at(0), kAccumulator);
1814 1803
1815 Label materialize_true, materialize_false; 1804 Label materialize_true, materialize_false;
1816 Label* if_true = NULL; 1805 Label* if_true = NULL;
1817 Label* if_false = NULL; 1806 Label* if_false = NULL;
1818 PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false); 1807 Label* fall_through = NULL;
1808 PrepareTest(&materialize_true, &materialize_false,
1809 &if_true, &if_false, &fall_through);
1819 1810
1820 __ BranchOnSmi(r0, if_false); 1811 __ BranchOnSmi(r0, if_false);
1821 __ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset)); 1812 __ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset));
1822 __ ldrb(r1, FieldMemOperand(r1, Map::kBitFieldOffset)); 1813 __ ldrb(r1, FieldMemOperand(r1, Map::kBitFieldOffset));
1823 __ tst(r1, Operand(1 << Map::kIsUndetectable)); 1814 __ tst(r1, Operand(1 << Map::kIsUndetectable));
1824 Split(ne, if_true, if_false, NULL); 1815 Split(ne, if_true, if_false, fall_through);
1825 1816
1826 Apply(context_, if_true, if_false); 1817 Apply(context_, if_true, if_false);
1827 } 1818 }
1828 1819
1829 1820
1830 void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf( 1821 void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf(
1831 ZoneList<Expression*>* args) { 1822 ZoneList<Expression*>* args) {
1832 1823
1833 ASSERT(args->length() == 1); 1824 ASSERT(args->length() == 1);
1834 1825
1835 VisitForValue(args->at(0), kAccumulator); 1826 VisitForValue(args->at(0), kAccumulator);
1836 1827
1837 Label materialize_true, materialize_false; 1828 Label materialize_true, materialize_false;
1838 Label* if_true = NULL; 1829 Label* if_true = NULL;
1839 Label* if_false = NULL; 1830 Label* if_false = NULL;
1840 PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false); 1831 Label* fall_through = NULL;
1832 PrepareTest(&materialize_true, &materialize_false,
1833 &if_true, &if_false, &fall_through);
1841 1834
1842 // Just indicate false, as %_IsStringWrapperSafeForDefaultValueOf() is only 1835 // Just indicate false, as %_IsStringWrapperSafeForDefaultValueOf() is only
1843 // used in a few functions in runtime.js which should not normally be hit by 1836 // used in a few functions in runtime.js which should not normally be hit by
1844 // this compiler. 1837 // this compiler.
1845 __ jmp(if_false); 1838 __ jmp(if_false);
1846 Apply(context_, if_true, if_false); 1839 Apply(context_, if_true, if_false);
1847 } 1840 }
1848 1841
1849 1842
1850 void FullCodeGenerator::EmitIsFunction(ZoneList<Expression*>* args) { 1843 void FullCodeGenerator::EmitIsFunction(ZoneList<Expression*>* args) {
1851 ASSERT(args->length() == 1); 1844 ASSERT(args->length() == 1);
1852 1845
1853 VisitForValue(args->at(0), kAccumulator); 1846 VisitForValue(args->at(0), kAccumulator);
1854 1847
1855 Label materialize_true, materialize_false; 1848 Label materialize_true, materialize_false;
1856 Label* if_true = NULL; 1849 Label* if_true = NULL;
1857 Label* if_false = NULL; 1850 Label* if_false = NULL;
1858 PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false); 1851 Label* fall_through = NULL;
1852 PrepareTest(&materialize_true, &materialize_false,
1853 &if_true, &if_false, &fall_through);
1859 1854
1860 __ BranchOnSmi(r0, if_false); 1855 __ BranchOnSmi(r0, if_false);
1861 __ CompareObjectType(r0, r1, r1, JS_FUNCTION_TYPE); 1856 __ CompareObjectType(r0, r1, r1, JS_FUNCTION_TYPE);
1862 Split(eq, if_true, if_false, NULL); 1857 Split(eq, if_true, if_false, fall_through);
1863 1858
1864 Apply(context_, if_true, if_false); 1859 Apply(context_, if_true, if_false);
1865 } 1860 }
1866 1861
1867 1862
1868 void FullCodeGenerator::EmitIsArray(ZoneList<Expression*>* args) { 1863 void FullCodeGenerator::EmitIsArray(ZoneList<Expression*>* args) {
1869 ASSERT(args->length() == 1); 1864 ASSERT(args->length() == 1);
1870 1865
1871 VisitForValue(args->at(0), kAccumulator); 1866 VisitForValue(args->at(0), kAccumulator);
1872 1867
1873 Label materialize_true, materialize_false; 1868 Label materialize_true, materialize_false;
1874 Label* if_true = NULL; 1869 Label* if_true = NULL;
1875 Label* if_false = NULL; 1870 Label* if_false = NULL;
1876 PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false); 1871 Label* fall_through = NULL;
1872 PrepareTest(&materialize_true, &materialize_false,
1873 &if_true, &if_false, &fall_through);
1877 1874
1878 __ BranchOnSmi(r0, if_false); 1875 __ BranchOnSmi(r0, if_false);
1879 __ CompareObjectType(r0, r1, r1, JS_ARRAY_TYPE); 1876 __ CompareObjectType(r0, r1, r1, JS_ARRAY_TYPE);
1880 Split(eq, if_true, if_false, NULL); 1877 Split(eq, if_true, if_false, fall_through);
1881 1878
1882 Apply(context_, if_true, if_false); 1879 Apply(context_, if_true, if_false);
1883 } 1880 }
1884 1881
1885 1882
1886 void FullCodeGenerator::EmitIsRegExp(ZoneList<Expression*>* args) { 1883 void FullCodeGenerator::EmitIsRegExp(ZoneList<Expression*>* args) {
1887 ASSERT(args->length() == 1); 1884 ASSERT(args->length() == 1);
1888 1885
1889 VisitForValue(args->at(0), kAccumulator); 1886 VisitForValue(args->at(0), kAccumulator);
1890 1887
1891 Label materialize_true, materialize_false; 1888 Label materialize_true, materialize_false;
1892 Label* if_true = NULL; 1889 Label* if_true = NULL;
1893 Label* if_false = NULL; 1890 Label* if_false = NULL;
1894 PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false); 1891 Label* fall_through = NULL;
1892 PrepareTest(&materialize_true, &materialize_false,
1893 &if_true, &if_false, &fall_through);
1895 1894
1896 __ BranchOnSmi(r0, if_false); 1895 __ BranchOnSmi(r0, if_false);
1897 __ CompareObjectType(r0, r1, r1, JS_REGEXP_TYPE); 1896 __ CompareObjectType(r0, r1, r1, JS_REGEXP_TYPE);
1898 Split(eq, if_true, if_false, NULL); 1897 Split(eq, if_true, if_false, fall_through);
1899 1898
1900 Apply(context_, if_true, if_false); 1899 Apply(context_, if_true, if_false);
1901 } 1900 }
1902 1901
1903 1902
1904 1903
1905 void FullCodeGenerator::EmitIsConstructCall(ZoneList<Expression*>* args) { 1904 void FullCodeGenerator::EmitIsConstructCall(ZoneList<Expression*>* args) {
1906 ASSERT(args->length() == 0); 1905 ASSERT(args->length() == 0);
1907 1906
1908 Label materialize_true, materialize_false; 1907 Label materialize_true, materialize_false;
1909 Label* if_true = NULL; 1908 Label* if_true = NULL;
1910 Label* if_false = NULL; 1909 Label* if_false = NULL;
1911 PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false); 1910 Label* fall_through = NULL;
1911 PrepareTest(&materialize_true, &materialize_false,
1912 &if_true, &if_false, &fall_through);
1912 1913
1913 // Get the frame pointer for the calling frame. 1914 // Get the frame pointer for the calling frame.
1914 __ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); 1915 __ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
1915 1916
1916 // Skip the arguments adaptor frame if it exists. 1917 // Skip the arguments adaptor frame if it exists.
1917 Label check_frame_marker; 1918 Label check_frame_marker;
1918 __ ldr(r1, MemOperand(r2, StandardFrameConstants::kContextOffset)); 1919 __ ldr(r1, MemOperand(r2, StandardFrameConstants::kContextOffset));
1919 __ cmp(r1, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 1920 __ cmp(r1, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
1920 __ b(ne, &check_frame_marker); 1921 __ b(ne, &check_frame_marker);
1921 __ ldr(r2, MemOperand(r2, StandardFrameConstants::kCallerFPOffset)); 1922 __ ldr(r2, MemOperand(r2, StandardFrameConstants::kCallerFPOffset));
1922 1923
1923 // Check the marker in the calling frame. 1924 // Check the marker in the calling frame.
1924 __ bind(&check_frame_marker); 1925 __ bind(&check_frame_marker);
1925 __ ldr(r1, MemOperand(r2, StandardFrameConstants::kMarkerOffset)); 1926 __ ldr(r1, MemOperand(r2, StandardFrameConstants::kMarkerOffset));
1926 __ cmp(r1, Operand(Smi::FromInt(StackFrame::CONSTRUCT))); 1927 __ cmp(r1, Operand(Smi::FromInt(StackFrame::CONSTRUCT)));
1927 Split(eq, if_true, if_false, NULL); 1928 Split(eq, if_true, if_false, fall_through);
1928 1929
1929 Apply(context_, if_true, if_false); 1930 Apply(context_, if_true, if_false);
1930 } 1931 }
1931 1932
1932 1933
1933 void FullCodeGenerator::EmitObjectEquals(ZoneList<Expression*>* args) { 1934 void FullCodeGenerator::EmitObjectEquals(ZoneList<Expression*>* args) {
1934 ASSERT(args->length() == 2); 1935 ASSERT(args->length() == 2);
1935 1936
1936 // Load the two objects into registers and perform the comparison. 1937 // Load the two objects into registers and perform the comparison.
1937 VisitForValue(args->at(0), kStack); 1938 VisitForValue(args->at(0), kStack);
1938 VisitForValue(args->at(1), kAccumulator); 1939 VisitForValue(args->at(1), kAccumulator);
1939 1940
1940 Label materialize_true, materialize_false; 1941 Label materialize_true, materialize_false;
1941 Label* if_true = NULL; 1942 Label* if_true = NULL;
1942 Label* if_false = NULL; 1943 Label* if_false = NULL;
1943 PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false); 1944 Label* fall_through = NULL;
1945 PrepareTest(&materialize_true, &materialize_false,
1946 &if_true, &if_false, &fall_through);
1944 1947
1945 __ pop(r1); 1948 __ pop(r1);
1946 __ cmp(r0, r1); 1949 __ cmp(r0, r1);
1947 Split(eq, if_true, if_false, NULL); 1950 Split(eq, if_true, if_false, fall_through);
1948 1951
1949 Apply(context_, if_true, if_false); 1952 Apply(context_, if_true, if_false);
1950 } 1953 }
1951 1954
1952 1955
1953 void FullCodeGenerator::EmitArguments(ZoneList<Expression*>* args) { 1956 void FullCodeGenerator::EmitArguments(ZoneList<Expression*>* args) {
1954 ASSERT(args->length() == 1); 1957 ASSERT(args->length() == 1);
1955 1958
1956 // ArgumentsAccessStub expects the key in edx and the formal 1959 // ArgumentsAccessStub expects the key in edx and the formal
1957 // parameter count in eax. 1960 // parameter count in eax.
(...skipping 652 matching lines...) Expand 10 before | Expand all | Expand 10 after
2610 break; 2613 break;
2611 } 2614 }
2612 break; 2615 break;
2613 } 2616 }
2614 2617
2615 case Token::NOT: { 2618 case Token::NOT: {
2616 Comment cmnt(masm_, "[ UnaryOperation (NOT)"); 2619 Comment cmnt(masm_, "[ UnaryOperation (NOT)");
2617 Label materialize_true, materialize_false; 2620 Label materialize_true, materialize_false;
2618 Label* if_true = NULL; 2621 Label* if_true = NULL;
2619 Label* if_false = NULL; 2622 Label* if_false = NULL;
2623 Label* fall_through = NULL;
2620 2624
2621 // Notice that the labels are swapped. 2625 // Notice that the labels are swapped.
2622 PrepareTest(&materialize_true, &materialize_false, &if_false, &if_true); 2626 PrepareTest(&materialize_true, &materialize_false,
2623 2627 &if_false, &if_true, &fall_through);
2624 VisitForControl(expr->expression(), if_true, if_false); 2628 VisitForControl(expr->expression(), if_true, if_false, fall_through);
2625
2626 Apply(context_, if_false, if_true); // Labels swapped. 2629 Apply(context_, if_false, if_true); // Labels swapped.
2627 break; 2630 break;
2628 } 2631 }
2629 2632
2630 case Token::TYPEOF: { 2633 case Token::TYPEOF: {
2631 Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)"); 2634 Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)");
2632 VisitForTypeofValue(expr->expression(), kStack); 2635 VisitForTypeofValue(expr->expression(), kStack);
2633 __ CallRuntime(Runtime::kTypeof, 1); 2636 __ CallRuntime(Runtime::kTypeof, 1);
2634 Apply(context_, r0); 2637 Apply(context_, r0);
2635 break; 2638 break;
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after
2972 void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) { 2975 void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
2973 Comment cmnt(masm_, "[ CompareOperation"); 2976 Comment cmnt(masm_, "[ CompareOperation");
2974 SetSourcePosition(expr->position()); 2977 SetSourcePosition(expr->position());
2975 2978
2976 // Always perform the comparison for its control flow. Pack the result 2979 // Always perform the comparison for its control flow. Pack the result
2977 // into the expression's context after the comparison is performed. 2980 // into the expression's context after the comparison is performed.
2978 2981
2979 Label materialize_true, materialize_false; 2982 Label materialize_true, materialize_false;
2980 Label* if_true = NULL; 2983 Label* if_true = NULL;
2981 Label* if_false = NULL; 2984 Label* if_false = NULL;
2982 PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false); 2985 Label* fall_through = NULL;
2986 PrepareTest(&materialize_true, &materialize_false,
2987 &if_true, &if_false, &fall_through);
2983 2988
2984 // First we try a fast inlined version of the compare when one of 2989 // First we try a fast inlined version of the compare when one of
2985 // the operands is a literal. 2990 // the operands is a literal.
2986 Token::Value op = expr->op(); 2991 Token::Value op = expr->op();
2987 Expression* left = expr->left(); 2992 Expression* left = expr->left();
2988 Expression* right = expr->right(); 2993 Expression* right = expr->right();
2989 if (TryLiteralCompare(op, left, right, if_true, if_false, NULL)) { 2994 if (TryLiteralCompare(op, left, right, if_true, if_false, fall_through)) {
2990 Apply(context_, if_true, if_false); 2995 Apply(context_, if_true, if_false);
2991 return; 2996 return;
2992 } 2997 }
2993 2998
2994 VisitForValue(expr->left(), kStack); 2999 VisitForValue(expr->left(), kStack);
2995 switch (expr->op()) { 3000 switch (expr->op()) {
2996 case Token::IN: 3001 case Token::IN:
2997 VisitForValue(expr->right(), kStack); 3002 VisitForValue(expr->right(), kStack);
2998 __ InvokeBuiltin(Builtins::IN, CALL_JS); 3003 __ InvokeBuiltin(Builtins::IN, CALL_JS);
2999 __ LoadRoot(ip, Heap::kTrueValueRootIndex); 3004 __ LoadRoot(ip, Heap::kTrueValueRootIndex);
3000 __ cmp(r0, ip); 3005 __ cmp(r0, ip);
3001 Split(eq, if_true, if_false, NULL); 3006 Split(eq, if_true, if_false, fall_through);
3002 break; 3007 break;
3003 3008
3004 case Token::INSTANCEOF: { 3009 case Token::INSTANCEOF: {
3005 VisitForValue(expr->right(), kStack); 3010 VisitForValue(expr->right(), kStack);
3006 InstanceofStub stub; 3011 InstanceofStub stub;
3007 __ CallStub(&stub); 3012 __ CallStub(&stub);
3008 // The stub returns 0 for true. 3013 // The stub returns 0 for true.
3009 __ tst(r0, r0); 3014 __ tst(r0, r0);
3010 Split(eq, if_true, if_false, NULL); 3015 Split(eq, if_true, if_false, fall_through);
3011 break; 3016 break;
3012 } 3017 }
3013 3018
3014 default: { 3019 default: {
3015 VisitForValue(expr->right(), kAccumulator); 3020 VisitForValue(expr->right(), kAccumulator);
3016 Condition cc = eq; 3021 Condition cc = eq;
3017 bool strict = false; 3022 bool strict = false;
3018 switch (expr->op()) { 3023 switch (expr->op()) {
3019 case Token::EQ_STRICT: 3024 case Token::EQ_STRICT:
3020 strict = true; 3025 strict = true;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
3055 __ orr(r2, r0, Operand(r1)); 3060 __ orr(r2, r0, Operand(r1));
3056 __ BranchOnNotSmi(r2, &slow_case); 3061 __ BranchOnNotSmi(r2, &slow_case);
3057 __ cmp(r1, r0); 3062 __ cmp(r1, r0);
3058 __ b(cc, if_true); 3063 __ b(cc, if_true);
3059 __ jmp(if_false); 3064 __ jmp(if_false);
3060 3065
3061 __ bind(&slow_case); 3066 __ bind(&slow_case);
3062 CompareStub stub(cc, strict, kBothCouldBeNaN, true, r1, r0); 3067 CompareStub stub(cc, strict, kBothCouldBeNaN, true, r1, r0);
3063 __ CallStub(&stub); 3068 __ CallStub(&stub);
3064 __ cmp(r0, Operand(0)); 3069 __ cmp(r0, Operand(0));
3065 Split(cc, if_true, if_false, NULL); 3070 Split(cc, if_true, if_false, fall_through);
3066 } 3071 }
3067 } 3072 }
3068 3073
3069 // Convert the result of the comparison into one expected for this 3074 // Convert the result of the comparison into one expected for this
3070 // expression's context. 3075 // expression's context.
3071 Apply(context_, if_true, if_false); 3076 Apply(context_, if_true, if_false);
3072 } 3077 }
3073 3078
3074 3079
3075 void FullCodeGenerator::VisitCompareToNull(CompareToNull* expr) { 3080 void FullCodeGenerator::VisitCompareToNull(CompareToNull* expr) {
3076 Comment cmnt(masm_, "[ CompareToNull"); 3081 Comment cmnt(masm_, "[ CompareToNull");
3077 Label materialize_true, materialize_false; 3082 Label materialize_true, materialize_false;
3078 Label* if_true = NULL; 3083 Label* if_true = NULL;
3079 Label* if_false = NULL; 3084 Label* if_false = NULL;
3080 PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false); 3085 Label* fall_through = NULL;
3086 PrepareTest(&materialize_true, &materialize_false,
3087 &if_true, &if_false, &fall_through);
3081 3088
3082 VisitForValue(expr->expression(), kAccumulator); 3089 VisitForValue(expr->expression(), kAccumulator);
3083 __ LoadRoot(r1, Heap::kNullValueRootIndex); 3090 __ LoadRoot(r1, Heap::kNullValueRootIndex);
3084 __ cmp(r0, r1); 3091 __ cmp(r0, r1);
3085 if (expr->is_strict()) { 3092 if (expr->is_strict()) {
3086 Split(eq, if_true, if_false, NULL); 3093 Split(eq, if_true, if_false, fall_through);
3087 } else { 3094 } else {
3088 __ b(eq, if_true); 3095 __ b(eq, if_true);
3089 __ LoadRoot(r1, Heap::kUndefinedValueRootIndex); 3096 __ LoadRoot(r1, Heap::kUndefinedValueRootIndex);
3090 __ cmp(r0, r1); 3097 __ cmp(r0, r1);
3091 __ b(eq, if_true); 3098 __ b(eq, if_true);
3092 __ tst(r0, Operand(kSmiTagMask)); 3099 __ tst(r0, Operand(kSmiTagMask));
3093 __ b(eq, if_false); 3100 __ b(eq, if_false);
3094 // It can be an undetectable object. 3101 // It can be an undetectable object.
3095 __ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset)); 3102 __ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset));
3096 __ ldrb(r1, FieldMemOperand(r1, Map::kBitFieldOffset)); 3103 __ ldrb(r1, FieldMemOperand(r1, Map::kBitFieldOffset));
3097 __ and_(r1, r1, Operand(1 << Map::kIsUndetectable)); 3104 __ and_(r1, r1, Operand(1 << Map::kIsUndetectable));
3098 __ cmp(r1, Operand(1 << Map::kIsUndetectable)); 3105 __ cmp(r1, Operand(1 << Map::kIsUndetectable));
3099 Split(eq, if_true, if_false, NULL); 3106 Split(eq, if_true, if_false, fall_through);
3100 } 3107 }
3101 Apply(context_, if_true, if_false); 3108 Apply(context_, if_true, if_false);
3102 } 3109 }
3103 3110
3104 3111
3105 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) { 3112 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) {
3106 __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 3113 __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
3107 Apply(context_, r0); 3114 Apply(context_, r0);
3108 } 3115 }
3109 3116
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
3151 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. 3158 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value.
3152 __ add(pc, r1, Operand(masm_->CodeObject())); 3159 __ add(pc, r1, Operand(masm_->CodeObject()));
3153 } 3160 }
3154 3161
3155 3162
3156 #undef __ 3163 #undef __
3157 3164
3158 } } // namespace v8::internal 3165 } } // namespace v8::internal
3159 3166
3160 #endif // V8_TARGET_ARCH_ARM 3167 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | src/full-codegen.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698