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

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

Issue 27047: Cleanup the ARM code generator for try...catch and try...finally by... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 11 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 | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 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 1746 matching lines...) Expand 10 before | Expand all | Expand 10 after
1757 // label. 1757 // label.
1758 int nof_escapes = node->escaping_labels()->length(); 1758 int nof_escapes = node->escaping_labels()->length();
1759 List<LabelShadow*> shadows(1 + nof_escapes); 1759 List<LabelShadow*> shadows(1 + nof_escapes);
1760 shadows.Add(new LabelShadow(&function_return_)); 1760 shadows.Add(new LabelShadow(&function_return_));
1761 for (int i = 0; i < nof_escapes; i++) { 1761 for (int i = 0; i < nof_escapes; i++) {
1762 shadows.Add(new LabelShadow(node->escaping_labels()->at(i))); 1762 shadows.Add(new LabelShadow(node->escaping_labels()->at(i)));
1763 } 1763 }
1764 1764
1765 // Generate code for the statements in the try block. 1765 // Generate code for the statements in the try block.
1766 VisitStatements(node->try_block()->statements()); 1766 VisitStatements(node->try_block()->statements());
1767 frame_->Pop(); // Discard the result. 1767 // Discard the code slot from the handler.
1768 frame_->Pop();
1768 1769
1769 // Stop the introduced shadowing and count the number of required unlinks. 1770 // Stop the introduced shadowing and count the number of required unlinks.
1770 // After shadowing stops, the original labels are unshadowed and the 1771 // After shadowing stops, the original labels are unshadowed and the
1771 // LabelShadows represent the formerly shadowing labels. 1772 // LabelShadows represent the formerly shadowing labels.
1772 int nof_unlinks = 0; 1773 int nof_unlinks = 0;
1773 for (int i = 0; i <= nof_escapes; i++) { 1774 for (int i = 0; i <= nof_escapes; i++) {
1774 shadows[i]->StopShadowing(); 1775 shadows[i]->StopShadowing();
1775 if (shadows[i]->is_linked()) nof_unlinks++; 1776 if (shadows[i]->is_linked()) nof_unlinks++;
1776 } 1777 }
1777 1778
1778 // Unlink from try chain. 1779 // Unlink from try chain.
1779 // TOS contains code slot 1780 // The code slot has already been discarded, so the next index is
1780 const int kNextIndex = (StackHandlerConstants::kNextOffset 1781 // adjusted by 1.
1781 + StackHandlerConstants::kAddressDisplacement) 1782 const int kNextIndex =
1782 / kPointerSize; 1783 (StackHandlerConstants::kNextOffset / kPointerSize) - 1;
1783 __ ldr(r1, frame_->Element(kNextIndex)); // read next_sp 1784 __ ldr(r1, frame_->Element(kNextIndex)); // read next_sp
1784 __ mov(r3, Operand(ExternalReference(Top::k_handler_address))); 1785 __ mov(r3, Operand(ExternalReference(Top::k_handler_address)));
1785 __ str(r1, MemOperand(r3)); 1786 __ str(r1, MemOperand(r3));
1786 ASSERT(StackHandlerConstants::kCodeOffset == 0); // first field is code 1787 // The code slot has already been dropped from the handler.
1787 frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1); 1788 frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1);
1788 // Code slot popped.
1789 if (nof_unlinks > 0) __ b(&exit); 1789 if (nof_unlinks > 0) __ b(&exit);
1790 1790
1791 // Generate unlink code for the (formerly) shadowing labels that have been 1791 // Generate unlink code for the (formerly) shadowing labels that have been
1792 // jumped to. 1792 // jumped to.
1793 for (int i = 0; i <= nof_escapes; i++) { 1793 for (int i = 0; i <= nof_escapes; i++) {
1794 if (shadows[i]->is_linked()) { 1794 if (shadows[i]->is_linked()) {
1795 // Unlink from try chain; 1795 // Unlink from try chain;
1796 __ bind(shadows[i]); 1796 __ bind(shadows[i]);
1797 1797
1798 // Reload sp from the top handler, because some statements that we 1798 // Reload sp from the top handler, because some statements that we
1799 // break from (eg, for...in) may have left stuff on the stack. 1799 // break from (eg, for...in) may have left stuff on the stack.
1800 __ mov(r3, Operand(ExternalReference(Top::k_handler_address))); 1800 __ mov(r3, Operand(ExternalReference(Top::k_handler_address)));
1801 __ ldr(sp, MemOperand(r3)); 1801 __ ldr(sp, MemOperand(r3));
1802 1802
1803 __ ldr(r1, frame_->Element(kNextIndex)); 1803 __ ldr(r1, frame_->Element(kNextIndex));
1804 __ str(r1, MemOperand(r3)); 1804 __ str(r1, MemOperand(r3));
1805 ASSERT(StackHandlerConstants::kCodeOffset == 0); // first field is code 1805 // The code slot has already been dropped from the handler.
1806 frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1); 1806 frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1);
1807 // Code slot popped.
1808 1807
1809 __ b(shadows[i]->original_label()); 1808 __ b(shadows[i]->original_label());
1810 } 1809 }
1811 } 1810 }
1812 1811
1813 __ bind(&exit); 1812 __ bind(&exit);
1814 } 1813 }
1815 1814
1816 1815
1817 void CodeGenerator::VisitTryFinally(TryFinally* node) { 1816 void CodeGenerator::VisitTryFinally(TryFinally* node) {
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1884 frame_->Push(r0); 1883 frame_->Push(r0);
1885 } 1884 }
1886 __ mov(r2, Operand(Smi::FromInt(JUMPING + i))); 1885 __ mov(r2, Operand(Smi::FromInt(JUMPING + i)));
1887 __ b(&unlink); 1886 __ b(&unlink);
1888 } 1887 }
1889 } 1888 }
1890 1889
1891 // Unlink from try chain; 1890 // Unlink from try chain;
1892 __ bind(&unlink); 1891 __ bind(&unlink);
1893 1892
1894 frame_->Pop(r0); // Store TOS in r0 across stack manipulation 1893 frame_->Pop(r0); // Preserve TOS result in r0 across stack manipulation.
1895 // Reload sp from the top handler, because some statements that we 1894 // Reload sp from the top handler, because some statements that we
1896 // break from (eg, for...in) may have left stuff on the stack. 1895 // break from (eg, for...in) may have left stuff on the stack.
1897 __ mov(r3, Operand(ExternalReference(Top::k_handler_address))); 1896 __ mov(r3, Operand(ExternalReference(Top::k_handler_address)));
1898 __ ldr(sp, MemOperand(r3)); 1897 __ ldr(sp, MemOperand(r3));
1899 const int kNextIndex = (StackHandlerConstants::kNextOffset 1898 const int kNextIndex = (StackHandlerConstants::kNextOffset
1900 + StackHandlerConstants::kAddressDisplacement) 1899 + StackHandlerConstants::kAddressDisplacement)
1901 / kPointerSize; 1900 / kPointerSize;
1902 __ ldr(r1, frame_->Element(kNextIndex)); 1901 __ ldr(r1, frame_->Element(kNextIndex));
1903 __ str(r1, MemOperand(r3)); 1902 __ str(r1, MemOperand(r3));
1904 ASSERT(StackHandlerConstants::kCodeOffset == 0); // first field is code 1903 ASSERT(StackHandlerConstants::kCodeOffset == 0); // first field is code
1904 // The stack pointer was restored to just below the code slot (the
1905 // topmost slot) of the handler, so all but the code slot need to be
1906 // dropped.
1905 frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1); 1907 frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1);
1906 // Code slot popped. 1908 // Restore result to TOS.
1907 frame_->Push(r0); 1909 frame_->Push(r0);
1908 1910
1909 // --- Finally block --- 1911 // --- Finally block ---
1910 __ bind(&finally_block); 1912 __ bind(&finally_block);
1911 1913
1912 // Push the state on the stack. 1914 // Push the state on the stack.
1913 frame_->Push(r2); 1915 frame_->Push(r2);
1914 1916
1915 // We keep two elements on the stack - the (possibly faked) result 1917 // We keep two elements on the stack - the (possibly faked) result
1916 // and the state - while evaluating the finally block. Record it, so 1918 // and the state - while evaluating the finally block. Record it, so
1917 // that a break/continue crossing this statement can restore the 1919 // that a break/continue crossing this statement can restore the
1918 // stack. 1920 // stack.
1919 const int kFinallyStackSize = 2 * kPointerSize; 1921 const int kFinallyStackSize = 2 * kPointerSize;
1920 break_stack_height_ += kFinallyStackSize; 1922 break_stack_height_ += kFinallyStackSize;
1921 1923
1922 // Generate code for the statements in the finally block. 1924 // Generate code for the statements in the finally block.
1923 VisitStatements(node->finally_block()->statements()); 1925 VisitStatements(node->finally_block()->statements());
1924 1926
1925 // Restore state and return value or faked TOS. 1927 // Restore state and return value or faked TOS.
1926 frame_->Pop(r2); 1928 frame_->Pop(r2);
1927 frame_->Pop(r0); 1929 frame_->Pop(r0);
1928 break_stack_height_ -= kFinallyStackSize; 1930 break_stack_height_ -= kFinallyStackSize;
1929 1931
1930 // Generate code to jump to the right destination for all used (formerly) 1932 // Generate code to jump to the right destination for all used (formerly)
1931 // shadowing labels. 1933 // shadowing labels.
1932 for (int i = 0; i <= nof_escapes; i++) { 1934 for (int i = 0; i <= nof_escapes; i++) {
1933 if (shadows[i]->is_bound()) { 1935 if (shadows[i]->is_bound()) {
1934 __ cmp(r2, Operand(Smi::FromInt(JUMPING + i))); 1936 __ cmp(r2, Operand(Smi::FromInt(JUMPING + i)));
1935 if (shadows[i]->original_label() != &function_return_) { 1937 __ b(eq, shadows[i]->original_label());
1936 Label next;
1937 __ b(ne, &next);
1938 __ b(shadows[i]->original_label());
1939 __ bind(&next);
1940 } else {
1941 __ b(eq, shadows[i]->original_label());
1942 }
1943 } 1938 }
1944 } 1939 }
1945 1940
1946 // Check if we need to rethrow the exception. 1941 // Check if we need to rethrow the exception.
1947 __ cmp(r2, Operand(Smi::FromInt(THROWING))); 1942 __ cmp(r2, Operand(Smi::FromInt(THROWING)));
1948 __ b(ne, &exit); 1943 __ b(ne, &exit);
1949 1944
1950 // Rethrow exception. 1945 // Rethrow exception.
1951 frame_->Push(r0); 1946 frame_->Push(r0);
1952 __ CallRuntime(Runtime::kReThrow, 1); 1947 __ CallRuntime(Runtime::kReThrow, 1);
(...skipping 2505 matching lines...) Expand 10 before | Expand all | Expand 10 after
4458 __ mov(r2, Operand(0)); 4453 __ mov(r2, Operand(0));
4459 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); 4454 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION);
4460 __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)), 4455 __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)),
4461 RelocInfo::CODE_TARGET); 4456 RelocInfo::CODE_TARGET);
4462 } 4457 }
4463 4458
4464 4459
4465 #undef __ 4460 #undef __
4466 4461
4467 } } // namespace v8::internal 4462 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698