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

Side by Side Diff: runtime/vm/code_generator_x64.cc

Issue 9562045: Added stack overflow checks at backward branches in order to allow interrupting endless loops. Bett… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 9 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 | « runtime/vm/code_generator_x64.h ('k') | runtime/vm/dart_api_impl_test.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 (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
7 7
8 #include "vm/code_generator.h" 8 #include "vm/code_generator.h"
9 9
10 #include "lib/error.h" 10 #include "lib/error.h"
(...skipping 1779 matching lines...) Expand 10 before | Expand all | Expand 10 after
1790 1790
1791 // Call operator. 1791 // Call operator.
1792 GenerateBinaryOperatorCall(node->id(), node->token_index(), node->Name()); 1792 GenerateBinaryOperatorCall(node->id(), node->token_index(), node->Name());
1793 // Result is in RAX. 1793 // Result is in RAX.
1794 if (IsResultNeeded(node)) { 1794 if (IsResultNeeded(node)) {
1795 __ pushq(RAX); 1795 __ pushq(RAX);
1796 } 1796 }
1797 } 1797 }
1798 1798
1799 1799
1800 void CodeGenerator::HandleBackwardBranch(
1801 intptr_t loop_id, intptr_t token_index) {
1802 // Use stack overflow check to eventually stop execution of loops.
1803 // This is necessary only if a loop does not have calls.
1804 __ movq(TMP, Immediate(Isolate::Current()->stack_limit_address()));
1805 __ cmpq(RSP, Address(TMP, 0));
1806 Label no_stack_overflow;
1807 __ j(ABOVE, &no_stack_overflow);
1808 GenerateCallRuntime(AstNode::kNoId,
1809 0,
regis 2012/03/02 01:49:17 Why do you pass kNoId and 0 instead of loop_id and
srdjan 2012/03/02 17:40:00 My mistake, you have done it right. Fixed.
1810 kStackOverflowRuntimeEntry);
1811 __ Bind(&no_stack_overflow);
1812 }
1813
1814
1800 void CodeGenerator::VisitWhileNode(WhileNode* node) { 1815 void CodeGenerator::VisitWhileNode(WhileNode* node) {
1801 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); 1816 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
1802 SourceLabel* label = node->label(); 1817 SourceLabel* label = node->label();
1803 __ Bind(label->continue_label()); 1818 __ Bind(label->continue_label());
1804 node->condition()->Visit(this); 1819 node->condition()->Visit(this);
1805 GenerateConditionTypeCheck(node->id(), node->condition()->token_index()); 1820 GenerateConditionTypeCheck(node->id(), node->condition()->token_index());
1806 __ popq(RAX); 1821 __ popq(RAX);
1807 __ LoadObject(RDX, bool_true); 1822 __ LoadObject(RDX, bool_true);
1808 __ cmpq(RAX, RDX); 1823 __ cmpq(RAX, RDX);
1809 __ j(NOT_EQUAL, label->break_label()); 1824 __ j(NOT_EQUAL, label->break_label());
1810 node->body()->Visit(this); 1825 node->body()->Visit(this);
1826 HandleBackwardBranch(node->id(), node->token_index());
1811 __ jmp(label->continue_label()); 1827 __ jmp(label->continue_label());
1812 __ Bind(label->break_label()); 1828 __ Bind(label->break_label());
1813 } 1829 }
1814 1830
1815 1831
1816 void CodeGenerator::VisitDoWhileNode(DoWhileNode* node) { 1832 void CodeGenerator::VisitDoWhileNode(DoWhileNode* node) {
1817 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); 1833 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
1818 SourceLabel* label = node->label(); 1834 SourceLabel* label = node->label();
1819 Label loop; 1835 Label loop;
1820 __ Bind(&loop); 1836 __ Bind(&loop);
1821 node->body()->Visit(this); 1837 node->body()->Visit(this);
1838 HandleBackwardBranch(node->id(), node->token_index());
1822 __ Bind(label->continue_label()); 1839 __ Bind(label->continue_label());
1823 node->condition()->Visit(this); 1840 node->condition()->Visit(this);
1824 GenerateConditionTypeCheck(node->id(), node->condition()->token_index()); 1841 GenerateConditionTypeCheck(node->id(), node->condition()->token_index());
1825 __ popq(RAX); 1842 __ popq(RAX);
1826 __ LoadObject(RDX, bool_true); 1843 __ LoadObject(RDX, bool_true);
1827 __ cmpq(RAX, RDX); 1844 __ cmpq(RAX, RDX);
1828 __ j(EQUAL, &loop); 1845 __ j(EQUAL, &loop);
1829 __ Bind(label->break_label()); 1846 __ Bind(label->break_label());
1830 } 1847 }
1831 1848
1832 1849
1833 void CodeGenerator::VisitForNode(ForNode* node) { 1850 void CodeGenerator::VisitForNode(ForNode* node) {
1834 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); 1851 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
1835 node->initializer()->Visit(this); 1852 node->initializer()->Visit(this);
1836 SourceLabel* label = node->label(); 1853 SourceLabel* label = node->label();
1837 Label loop; 1854 Label loop;
1838 __ Bind(&loop); 1855 __ Bind(&loop);
1839 if (node->condition() != NULL) { 1856 if (node->condition() != NULL) {
1840 node->condition()->Visit(this); 1857 node->condition()->Visit(this);
1841 GenerateConditionTypeCheck(node->id(), node->condition()->token_index()); 1858 GenerateConditionTypeCheck(node->id(), node->condition()->token_index());
1842 __ popq(RAX); 1859 __ popq(RAX);
1843 __ LoadObject(RDX, bool_true); 1860 __ LoadObject(RDX, bool_true);
1844 __ cmpq(RAX, RDX); 1861 __ cmpq(RAX, RDX);
1845 __ j(NOT_EQUAL, label->break_label()); 1862 __ j(NOT_EQUAL, label->break_label());
1846 } 1863 }
1847 node->body()->Visit(this); 1864 node->body()->Visit(this);
1865 HandleBackwardBranch(node->id(), node->token_index());
1848 __ Bind(label->continue_label()); 1866 __ Bind(label->continue_label());
1849 node->increment()->Visit(this); 1867 node->increment()->Visit(this);
1850 __ jmp(&loop); 1868 __ jmp(&loop);
1851 __ Bind(label->break_label()); 1869 __ Bind(label->break_label());
1852 } 1870 }
1853 1871
1854 1872
1855 void CodeGenerator::VisitJumpNode(JumpNode* node) { 1873 void CodeGenerator::VisitJumpNode(JumpNode* node) {
1856 SourceLabel* label = node->label(); 1874 SourceLabel* label = node->label();
1857 1875
(...skipping 831 matching lines...) Expand 10 before | Expand all | Expand 10 after
2689 const Error& error = Error::Handle( 2707 const Error& error = Error::Handle(
2690 Parser::FormatError(script, token_index, "Error", format, args)); 2708 Parser::FormatError(script, token_index, "Error", format, args));
2691 va_end(args); 2709 va_end(args);
2692 Isolate::Current()->long_jump_base()->Jump(1, error); 2710 Isolate::Current()->long_jump_base()->Jump(1, error);
2693 UNREACHABLE(); 2711 UNREACHABLE();
2694 } 2712 }
2695 2713
2696 } // namespace dart 2714 } // namespace dart
2697 2715
2698 #endif // defined TARGET_ARCH_X64 2716 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/code_generator_x64.h ('k') | runtime/vm/dart_api_impl_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698