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

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

Issue 1645008: Add tracking of loop nesting to ARM code. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 years, 8 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/arm/codegen-arm.h ('k') | 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 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 // CodeGenerator implementation 126 // CodeGenerator implementation
127 127
128 CodeGenerator::CodeGenerator(MacroAssembler* masm) 128 CodeGenerator::CodeGenerator(MacroAssembler* masm)
129 : deferred_(8), 129 : deferred_(8),
130 masm_(masm), 130 masm_(masm),
131 info_(NULL), 131 info_(NULL),
132 frame_(NULL), 132 frame_(NULL),
133 allocator_(NULL), 133 allocator_(NULL),
134 cc_reg_(al), 134 cc_reg_(al),
135 state_(NULL), 135 state_(NULL),
136 loop_nesting_(0),
136 function_return_is_shadowed_(false) { 137 function_return_is_shadowed_(false) {
137 } 138 }
138 139
139 140
140 // Calling conventions: 141 // Calling conventions:
141 // fp: caller's frame pointer 142 // fp: caller's frame pointer
142 // sp: stack pointer 143 // sp: stack pointer
143 // r1: called JS function 144 // r1: called JS function
144 // cp: callee's context 145 // cp: callee's context
145 146
146 void CodeGenerator::Generate(CompilationInfo* info) { 147 void CodeGenerator::Generate(CompilationInfo* info) {
147 // Record the position for debugging purposes. 148 // Record the position for debugging purposes.
148 CodeForFunctionPosition(info->function()); 149 CodeForFunctionPosition(info->function());
149 Comment cmnt(masm_, "[ function compiled by virtual frame code generator"); 150 Comment cmnt(masm_, "[ function compiled by virtual frame code generator");
150 151
151 // Initialize state. 152 // Initialize state.
152 info_ = info; 153 info_ = info;
153 ASSERT(allocator_ == NULL); 154 ASSERT(allocator_ == NULL);
154 RegisterAllocator register_allocator(this); 155 RegisterAllocator register_allocator(this);
155 allocator_ = &register_allocator; 156 allocator_ = &register_allocator;
156 ASSERT(frame_ == NULL); 157 ASSERT(frame_ == NULL);
157 frame_ = new VirtualFrame(); 158 frame_ = new VirtualFrame();
158 cc_reg_ = al; 159 cc_reg_ = al;
160
161 // Adjust for function-level loop nesting.
162 loop_nesting_ += info->loop_nesting();
163
159 { 164 {
160 CodeGenState state(this); 165 CodeGenState state(this);
161 166
162 // Entry: 167 // Entry:
163 // Stack: receiver, arguments 168 // Stack: receiver, arguments
164 // lr: return address 169 // lr: return address
165 // fp: caller's frame pointer 170 // fp: caller's frame pointer
166 // sp: stack pointer 171 // sp: stack pointer
167 // r1: called JS function 172 // r1: called JS function
168 // cp: callee's context 173 // cp: callee's context
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
373 // Check that the size of the code used for returning matches what is 378 // Check that the size of the code used for returning matches what is
374 // expected by the debugger. The add instruction above is an addressing 379 // expected by the debugger. The add instruction above is an addressing
375 // mode 1 instruction where there are restrictions on which immediate values 380 // mode 1 instruction where there are restrictions on which immediate values
376 // can be encoded in the instruction and which immediate values requires 381 // can be encoded in the instruction and which immediate values requires
377 // use of an additional instruction for moving the immediate to a temporary 382 // use of an additional instruction for moving the immediate to a temporary
378 // register. 383 // register.
379 ASSERT_EQ(return_sequence_length, 384 ASSERT_EQ(return_sequence_length,
380 masm_->InstructionsGeneratedSince(&check_exit_codesize)); 385 masm_->InstructionsGeneratedSince(&check_exit_codesize));
381 } 386 }
382 387
388 // Adjust for function-level loop nesting.
389 loop_nesting_ -= info->loop_nesting();
Erik Corry 2010/04/15 12:46:18 Seems simpler to ASSERT that loop_nesting() == inf
390
383 // Code generation state must be reset. 391 // Code generation state must be reset.
384 ASSERT(!has_cc()); 392 ASSERT(!has_cc());
385 ASSERT(state_ == NULL); 393 ASSERT(state_ == NULL);
394 ASSERT(loop_nesting() == 0);
386 ASSERT(!function_return_is_shadowed_); 395 ASSERT(!function_return_is_shadowed_);
387 function_return_.Unuse(); 396 function_return_.Unuse();
388 DeleteFrame(); 397 DeleteFrame();
389 398
390 // Process any deferred code using the register allocator. 399 // Process any deferred code using the register allocator.
391 if (!HasStackOverflow()) { 400 if (!HasStackOverflow()) {
392 ProcessDeferred(); 401 ProcessDeferred();
393 } 402 }
394 403
395 allocator_ = NULL; 404 allocator_ = NULL;
(...skipping 1482 matching lines...) Expand 10 before | Expand all | Expand 10 after
1878 1887
1879 void CodeGenerator::VisitDoWhileStatement(DoWhileStatement* node) { 1888 void CodeGenerator::VisitDoWhileStatement(DoWhileStatement* node) {
1880 #ifdef DEBUG 1889 #ifdef DEBUG
1881 int original_height = frame_->height(); 1890 int original_height = frame_->height();
1882 #endif 1891 #endif
1883 VirtualFrame::SpilledScope spilled_scope(frame_); 1892 VirtualFrame::SpilledScope spilled_scope(frame_);
1884 Comment cmnt(masm_, "[ DoWhileStatement"); 1893 Comment cmnt(masm_, "[ DoWhileStatement");
1885 CodeForStatementPosition(node); 1894 CodeForStatementPosition(node);
1886 node->break_target()->set_direction(JumpTarget::FORWARD_ONLY); 1895 node->break_target()->set_direction(JumpTarget::FORWARD_ONLY);
1887 JumpTarget body(JumpTarget::BIDIRECTIONAL); 1896 JumpTarget body(JumpTarget::BIDIRECTIONAL);
1897 IncrementLoopNesting();
1888 1898
1889 // Label the top of the loop for the backward CFG edge. If the test 1899 // Label the top of the loop for the backward CFG edge. If the test
1890 // is always true we can use the continue target, and if the test is 1900 // is always true we can use the continue target, and if the test is
1891 // always false there is no need. 1901 // always false there is no need.
1892 ConditionAnalysis info = AnalyzeCondition(node->cond()); 1902 ConditionAnalysis info = AnalyzeCondition(node->cond());
1893 switch (info) { 1903 switch (info) {
1894 case ALWAYS_TRUE: 1904 case ALWAYS_TRUE:
1895 node->continue_target()->set_direction(JumpTarget::BIDIRECTIONAL); 1905 node->continue_target()->set_direction(JumpTarget::BIDIRECTIONAL);
1896 node->continue_target()->Bind(); 1906 node->continue_target()->Bind();
1897 break; 1907 break;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1938 // fall out of the test expression. 1948 // fall out of the test expression.
1939 Branch(true, &body); 1949 Branch(true, &body);
1940 } 1950 }
1941 } 1951 }
1942 break; 1952 break;
1943 } 1953 }
1944 1954
1945 if (node->break_target()->is_linked()) { 1955 if (node->break_target()->is_linked()) {
1946 node->break_target()->Bind(); 1956 node->break_target()->Bind();
1947 } 1957 }
1958 DecrementLoopNesting();
1948 ASSERT(!has_valid_frame() || frame_->height() == original_height); 1959 ASSERT(!has_valid_frame() || frame_->height() == original_height);
1949 } 1960 }
1950 1961
1951 1962
1952 void CodeGenerator::VisitWhileStatement(WhileStatement* node) { 1963 void CodeGenerator::VisitWhileStatement(WhileStatement* node) {
1953 #ifdef DEBUG 1964 #ifdef DEBUG
1954 int original_height = frame_->height(); 1965 int original_height = frame_->height();
1955 #endif 1966 #endif
1956 VirtualFrame::SpilledScope spilled_scope(frame_); 1967 VirtualFrame::SpilledScope spilled_scope(frame_);
1957 Comment cmnt(masm_, "[ WhileStatement"); 1968 Comment cmnt(masm_, "[ WhileStatement");
1958 CodeForStatementPosition(node); 1969 CodeForStatementPosition(node);
1959 1970
1960 // If the test is never true and has no side effects there is no need 1971 // If the test is never true and has no side effects there is no need
1961 // to compile the test or body. 1972 // to compile the test or body.
1962 ConditionAnalysis info = AnalyzeCondition(node->cond()); 1973 ConditionAnalysis info = AnalyzeCondition(node->cond());
1963 if (info == ALWAYS_FALSE) return; 1974 if (info == ALWAYS_FALSE) return;
1964 1975
1965 node->break_target()->set_direction(JumpTarget::FORWARD_ONLY); 1976 node->break_target()->set_direction(JumpTarget::FORWARD_ONLY);
1977 IncrementLoopNesting();
1966 1978
1967 // Label the top of the loop with the continue target for the backward 1979 // Label the top of the loop with the continue target for the backward
1968 // CFG edge. 1980 // CFG edge.
1969 node->continue_target()->set_direction(JumpTarget::BIDIRECTIONAL); 1981 node->continue_target()->set_direction(JumpTarget::BIDIRECTIONAL);
1970 node->continue_target()->Bind(); 1982 node->continue_target()->Bind();
1971 1983
1972 if (info == DONT_KNOW) { 1984 if (info == DONT_KNOW) {
1973 JumpTarget body; 1985 JumpTarget body;
1974 LoadConditionAndSpill(node->cond(), &body, node->break_target(), true); 1986 LoadConditionAndSpill(node->cond(), &body, node->break_target(), true);
1975 if (has_valid_frame()) { 1987 if (has_valid_frame()) {
(...skipping 11 matching lines...) Expand all
1987 VisitAndSpill(node->body()); 1999 VisitAndSpill(node->body());
1988 2000
1989 // If control flow can fall out of the body, jump back to the top. 2001 // If control flow can fall out of the body, jump back to the top.
1990 if (has_valid_frame()) { 2002 if (has_valid_frame()) {
1991 node->continue_target()->Jump(); 2003 node->continue_target()->Jump();
1992 } 2004 }
1993 } 2005 }
1994 if (node->break_target()->is_linked()) { 2006 if (node->break_target()->is_linked()) {
1995 node->break_target()->Bind(); 2007 node->break_target()->Bind();
1996 } 2008 }
2009 DecrementLoopNesting();
1997 ASSERT(!has_valid_frame() || frame_->height() == original_height); 2010 ASSERT(!has_valid_frame() || frame_->height() == original_height);
1998 } 2011 }
1999 2012
2000 2013
2001 void CodeGenerator::VisitForStatement(ForStatement* node) { 2014 void CodeGenerator::VisitForStatement(ForStatement* node) {
2002 #ifdef DEBUG 2015 #ifdef DEBUG
2003 int original_height = frame_->height(); 2016 int original_height = frame_->height();
2004 #endif 2017 #endif
2005 VirtualFrame::SpilledScope spilled_scope(frame_); 2018 VirtualFrame::SpilledScope spilled_scope(frame_);
2006 Comment cmnt(masm_, "[ ForStatement"); 2019 Comment cmnt(masm_, "[ ForStatement");
2007 CodeForStatementPosition(node); 2020 CodeForStatementPosition(node);
2008 if (node->init() != NULL) { 2021 if (node->init() != NULL) {
2009 VisitAndSpill(node->init()); 2022 VisitAndSpill(node->init());
2010 } 2023 }
2011 2024
2012 // If the test is never true there is no need to compile the test or 2025 // If the test is never true there is no need to compile the test or
2013 // body. 2026 // body.
2014 ConditionAnalysis info = AnalyzeCondition(node->cond()); 2027 ConditionAnalysis info = AnalyzeCondition(node->cond());
2015 if (info == ALWAYS_FALSE) return; 2028 if (info == ALWAYS_FALSE) return;
2016 2029
2017 node->break_target()->set_direction(JumpTarget::FORWARD_ONLY); 2030 node->break_target()->set_direction(JumpTarget::FORWARD_ONLY);
2031 IncrementLoopNesting();
2018 2032
2019 // If there is no update statement, label the top of the loop with the 2033 // If there is no update statement, label the top of the loop with the
2020 // continue target, otherwise with the loop target. 2034 // continue target, otherwise with the loop target.
2021 JumpTarget loop(JumpTarget::BIDIRECTIONAL); 2035 JumpTarget loop(JumpTarget::BIDIRECTIONAL);
2022 if (node->next() == NULL) { 2036 if (node->next() == NULL) {
2023 node->continue_target()->set_direction(JumpTarget::BIDIRECTIONAL); 2037 node->continue_target()->set_direction(JumpTarget::BIDIRECTIONAL);
2024 node->continue_target()->Bind(); 2038 node->continue_target()->Bind();
2025 } else { 2039 } else {
2026 node->continue_target()->set_direction(JumpTarget::FORWARD_ONLY); 2040 node->continue_target()->set_direction(JumpTarget::FORWARD_ONLY);
2027 loop.Bind(); 2041 loop.Bind();
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
2062 // statement and not the body. 2076 // statement and not the body.
2063 CodeForStatementPosition(node); 2077 CodeForStatementPosition(node);
2064 VisitAndSpill(node->next()); 2078 VisitAndSpill(node->next());
2065 loop.Jump(); 2079 loop.Jump();
2066 } 2080 }
2067 } 2081 }
2068 } 2082 }
2069 if (node->break_target()->is_linked()) { 2083 if (node->break_target()->is_linked()) {
2070 node->break_target()->Bind(); 2084 node->break_target()->Bind();
2071 } 2085 }
2086 DecrementLoopNesting();
2072 ASSERT(!has_valid_frame() || frame_->height() == original_height); 2087 ASSERT(!has_valid_frame() || frame_->height() == original_height);
2073 } 2088 }
2074 2089
2075 2090
2076 void CodeGenerator::VisitForInStatement(ForInStatement* node) { 2091 void CodeGenerator::VisitForInStatement(ForInStatement* node) {
Erik Corry 2010/04/15 12:46:18 Wot no loop nesting?
2077 #ifdef DEBUG 2092 #ifdef DEBUG
2078 int original_height = frame_->height(); 2093 int original_height = frame_->height();
2079 #endif 2094 #endif
2080 VirtualFrame::SpilledScope spilled_scope(frame_); 2095 VirtualFrame::SpilledScope spilled_scope(frame_);
2081 Comment cmnt(masm_, "[ ForInStatement"); 2096 Comment cmnt(masm_, "[ ForInStatement");
2082 CodeForStatementPosition(node); 2097 CodeForStatementPosition(node);
2083 2098
2084 JumpTarget primitive; 2099 JumpTarget primitive;
2085 JumpTarget jsobject; 2100 JumpTarget jsobject;
2086 JumpTarget fixed_array; 2101 JumpTarget fixed_array;
(...skipping 6852 matching lines...) Expand 10 before | Expand all | Expand 10 after
8939 8954
8940 // Just jump to runtime to add the two strings. 8955 // Just jump to runtime to add the two strings.
8941 __ bind(&string_add_runtime); 8956 __ bind(&string_add_runtime);
8942 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); 8957 __ TailCallRuntime(Runtime::kStringAdd, 2, 1);
8943 } 8958 }
8944 8959
8945 8960
8946 #undef __ 8961 #undef __
8947 8962
8948 } } // namespace v8::internal 8963 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/codegen-arm.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698