OLD | NEW |
---|---|
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 15 matching lines...) Expand all Loading... | |
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | 27 |
28 #include "v8.h" | 28 #include "v8.h" |
29 | 29 |
30 #include "bootstrapper.h" | 30 #include "bootstrapper.h" |
31 #include "codegen-inl.h" | 31 #include "codegen-inl.h" |
32 #include "compiler.h" | 32 #include "compiler.h" |
33 #include "debug.h" | 33 #include "debug.h" |
34 #include "ic-inl.h" | 34 #include "ic-inl.h" |
35 #include "jsregexp.h" | 35 #include "jsregexp.h" |
36 #include "jump-target-light-inl.h" | |
36 #include "parser.h" | 37 #include "parser.h" |
37 #include "regexp-macro-assembler.h" | 38 #include "regexp-macro-assembler.h" |
38 #include "regexp-stack.h" | 39 #include "regexp-stack.h" |
39 #include "register-allocator-inl.h" | 40 #include "register-allocator-inl.h" |
40 #include "runtime.h" | 41 #include "runtime.h" |
41 #include "scopes.h" | 42 #include "scopes.h" |
42 #include "virtual-frame-inl.h" | 43 #include "virtual-frame-inl.h" |
43 | 44 |
44 namespace v8 { | 45 namespace v8 { |
45 namespace internal { | 46 namespace internal { |
46 | 47 |
48 | |
49 // These VirtualFrame methods should actually be in a virtual-frame-arm-inl.h | |
Søren Thygesen Gjesse
2010/05/06 07:48:11
Considered adding virtual-frame-arm-inl.h?
| |
50 // file if such a thing existed. | |
51 MemOperand VirtualFrame::ParameterAt(int index) { | |
52 // Index -1 corresponds to the receiver. | |
53 ASSERT(-1 <= index); // -1 is the receiver. | |
54 ASSERT(index <= parameter_count()); | |
55 return MemOperand(fp, (1 + parameter_count() - index) * kPointerSize); | |
56 } | |
57 | |
58 // The receiver frame slot. | |
59 MemOperand VirtualFrame::Receiver() { | |
60 return ParameterAt(-1); | |
61 } | |
62 | |
63 | |
47 #define __ ACCESS_MASM(masm_) | 64 #define __ ACCESS_MASM(masm_) |
48 | 65 |
49 static void EmitIdenticalObjectComparison(MacroAssembler* masm, | 66 static void EmitIdenticalObjectComparison(MacroAssembler* masm, |
50 Label* slow, | 67 Label* slow, |
51 Condition cc, | 68 Condition cc, |
52 bool never_nan_nan); | 69 bool never_nan_nan); |
53 static void EmitSmiNonsmiComparison(MacroAssembler* masm, | 70 static void EmitSmiNonsmiComparison(MacroAssembler* masm, |
54 Label* lhs_not_nan, | 71 Label* lhs_not_nan, |
55 Label* slow, | 72 Label* slow, |
56 bool strict); | 73 bool strict); |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
267 | 284 |
268 // Bind all the bailout labels to the beginning of the function. | 285 // Bind all the bailout labels to the beginning of the function. |
269 List<CompilationInfo::Bailout*>* bailouts = info->bailouts(); | 286 List<CompilationInfo::Bailout*>* bailouts = info->bailouts(); |
270 for (int i = 0; i < bailouts->length(); i++) { | 287 for (int i = 0; i < bailouts->length(); i++) { |
271 __ bind(bailouts->at(i)->label()); | 288 __ bind(bailouts->at(i)->label()); |
272 } | 289 } |
273 } | 290 } |
274 | 291 |
275 // Initialize the function return target after the locals are set | 292 // Initialize the function return target after the locals are set |
276 // up, because it needs the expected frame height from the frame. | 293 // up, because it needs the expected frame height from the frame. |
277 function_return_.set_direction(JumpTarget::BIDIRECTIONAL); | 294 function_return_.SetExpectedHeight(); |
278 function_return_is_shadowed_ = false; | 295 function_return_is_shadowed_ = false; |
279 | 296 |
280 // Generate code to 'execute' declarations and initialize functions | 297 // Generate code to 'execute' declarations and initialize functions |
281 // (source elements). In case of an illegal redeclaration we need to | 298 // (source elements). In case of an illegal redeclaration we need to |
282 // handle that instead of processing the declarations. | 299 // handle that instead of processing the declarations. |
283 if (scope()->HasIllegalRedeclaration()) { | 300 if (scope()->HasIllegalRedeclaration()) { |
284 Comment cmnt(masm_, "[ illegal redeclarations"); | 301 Comment cmnt(masm_, "[ illegal redeclarations"); |
285 scope()->VisitIllegalRedeclaration(this); | 302 scope()->VisitIllegalRedeclaration(this); |
286 } else { | 303 } else { |
287 Comment cmnt(masm_, "[ declarations"); | 304 Comment cmnt(masm_, "[ declarations"); |
(...skipping 1255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1543 } | 1560 } |
1544 | 1561 |
1545 | 1562 |
1546 void CodeGenerator::VisitBlock(Block* node) { | 1563 void CodeGenerator::VisitBlock(Block* node) { |
1547 #ifdef DEBUG | 1564 #ifdef DEBUG |
1548 int original_height = frame_->height(); | 1565 int original_height = frame_->height(); |
1549 #endif | 1566 #endif |
1550 VirtualFrame::SpilledScope spilled_scope(frame_); | 1567 VirtualFrame::SpilledScope spilled_scope(frame_); |
1551 Comment cmnt(masm_, "[ Block"); | 1568 Comment cmnt(masm_, "[ Block"); |
1552 CodeForStatementPosition(node); | 1569 CodeForStatementPosition(node); |
1553 node->break_target()->set_direction(JumpTarget::FORWARD_ONLY); | 1570 node->break_target()->SetExpectedHeight(); |
1554 VisitStatementsAndSpill(node->statements()); | 1571 VisitStatementsAndSpill(node->statements()); |
1555 if (node->break_target()->is_linked()) { | 1572 if (node->break_target()->is_linked()) { |
1556 node->break_target()->Bind(); | 1573 node->break_target()->Bind(); |
1557 } | 1574 } |
1558 node->break_target()->Unuse(); | 1575 node->break_target()->Unuse(); |
1559 ASSERT(!has_valid_frame() || frame_->height() == original_height); | 1576 ASSERT(!has_valid_frame() || frame_->height() == original_height); |
1560 } | 1577 } |
1561 | 1578 |
1562 | 1579 |
1563 void CodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { | 1580 void CodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { |
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1830 } | 1847 } |
1831 | 1848 |
1832 | 1849 |
1833 void CodeGenerator::VisitSwitchStatement(SwitchStatement* node) { | 1850 void CodeGenerator::VisitSwitchStatement(SwitchStatement* node) { |
1834 #ifdef DEBUG | 1851 #ifdef DEBUG |
1835 int original_height = frame_->height(); | 1852 int original_height = frame_->height(); |
1836 #endif | 1853 #endif |
1837 VirtualFrame::SpilledScope spilled_scope(frame_); | 1854 VirtualFrame::SpilledScope spilled_scope(frame_); |
1838 Comment cmnt(masm_, "[ SwitchStatement"); | 1855 Comment cmnt(masm_, "[ SwitchStatement"); |
1839 CodeForStatementPosition(node); | 1856 CodeForStatementPosition(node); |
1840 node->break_target()->set_direction(JumpTarget::FORWARD_ONLY); | 1857 node->break_target()->SetExpectedHeight(); |
1841 | 1858 |
1842 LoadAndSpill(node->tag()); | 1859 LoadAndSpill(node->tag()); |
1843 | 1860 |
1844 JumpTarget next_test; | 1861 JumpTarget next_test; |
1845 JumpTarget fall_through; | 1862 JumpTarget fall_through; |
1846 JumpTarget default_entry; | 1863 JumpTarget default_entry; |
1847 JumpTarget default_exit(JumpTarget::BIDIRECTIONAL); | 1864 JumpTarget default_exit(JumpTarget::BIDIRECTIONAL); |
1848 ZoneList<CaseClause*>* cases = node->cases(); | 1865 ZoneList<CaseClause*>* cases = node->cases(); |
1849 int length = cases->length(); | 1866 int length = cases->length(); |
1850 CaseClause* default_clause = NULL; | 1867 CaseClause* default_clause = NULL; |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1919 } | 1936 } |
1920 | 1937 |
1921 | 1938 |
1922 void CodeGenerator::VisitDoWhileStatement(DoWhileStatement* node) { | 1939 void CodeGenerator::VisitDoWhileStatement(DoWhileStatement* node) { |
1923 #ifdef DEBUG | 1940 #ifdef DEBUG |
1924 int original_height = frame_->height(); | 1941 int original_height = frame_->height(); |
1925 #endif | 1942 #endif |
1926 VirtualFrame::SpilledScope spilled_scope(frame_); | 1943 VirtualFrame::SpilledScope spilled_scope(frame_); |
1927 Comment cmnt(masm_, "[ DoWhileStatement"); | 1944 Comment cmnt(masm_, "[ DoWhileStatement"); |
1928 CodeForStatementPosition(node); | 1945 CodeForStatementPosition(node); |
1929 node->break_target()->set_direction(JumpTarget::FORWARD_ONLY); | 1946 node->break_target()->SetExpectedHeight(); |
1930 JumpTarget body(JumpTarget::BIDIRECTIONAL); | 1947 JumpTarget body(JumpTarget::BIDIRECTIONAL); |
1931 IncrementLoopNesting(); | 1948 IncrementLoopNesting(); |
1932 | 1949 |
1933 // Label the top of the loop for the backward CFG edge. If the test | 1950 // Label the top of the loop for the backward CFG edge. If the test |
1934 // is always true we can use the continue target, and if the test is | 1951 // is always true we can use the continue target, and if the test is |
1935 // always false there is no need. | 1952 // always false there is no need. |
1936 ConditionAnalysis info = AnalyzeCondition(node->cond()); | 1953 ConditionAnalysis info = AnalyzeCondition(node->cond()); |
1937 switch (info) { | 1954 switch (info) { |
1938 case ALWAYS_TRUE: | 1955 case ALWAYS_TRUE: |
1939 node->continue_target()->set_direction(JumpTarget::BIDIRECTIONAL); | 1956 node->continue_target()->SetExpectedHeight(); |
1940 node->continue_target()->Bind(); | 1957 node->continue_target()->Bind(); |
1941 break; | 1958 break; |
1942 case ALWAYS_FALSE: | 1959 case ALWAYS_FALSE: |
1943 node->continue_target()->set_direction(JumpTarget::FORWARD_ONLY); | 1960 node->continue_target()->SetExpectedHeight(); |
1944 break; | 1961 break; |
1945 case DONT_KNOW: | 1962 case DONT_KNOW: |
1946 node->continue_target()->set_direction(JumpTarget::FORWARD_ONLY); | 1963 node->continue_target()->SetExpectedHeight(); |
1947 body.Bind(); | 1964 body.Bind(); |
1948 break; | 1965 break; |
1949 } | 1966 } |
1950 | 1967 |
1951 CheckStack(); // TODO(1222600): ignore if body contains calls. | 1968 CheckStack(); // TODO(1222600): ignore if body contains calls. |
1952 VisitAndSpill(node->body()); | 1969 VisitAndSpill(node->body()); |
1953 | 1970 |
1954 // Compile the test. | 1971 // Compile the test. |
1955 switch (info) { | 1972 switch (info) { |
1956 case ALWAYS_TRUE: | 1973 case ALWAYS_TRUE: |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2000 #endif | 2017 #endif |
2001 VirtualFrame::SpilledScope spilled_scope(frame_); | 2018 VirtualFrame::SpilledScope spilled_scope(frame_); |
2002 Comment cmnt(masm_, "[ WhileStatement"); | 2019 Comment cmnt(masm_, "[ WhileStatement"); |
2003 CodeForStatementPosition(node); | 2020 CodeForStatementPosition(node); |
2004 | 2021 |
2005 // If the test is never true and has no side effects there is no need | 2022 // If the test is never true and has no side effects there is no need |
2006 // to compile the test or body. | 2023 // to compile the test or body. |
2007 ConditionAnalysis info = AnalyzeCondition(node->cond()); | 2024 ConditionAnalysis info = AnalyzeCondition(node->cond()); |
2008 if (info == ALWAYS_FALSE) return; | 2025 if (info == ALWAYS_FALSE) return; |
2009 | 2026 |
2010 node->break_target()->set_direction(JumpTarget::FORWARD_ONLY); | 2027 node->break_target()->SetExpectedHeight(); |
2011 IncrementLoopNesting(); | 2028 IncrementLoopNesting(); |
2012 | 2029 |
2013 // Label the top of the loop with the continue target for the backward | 2030 // Label the top of the loop with the continue target for the backward |
2014 // CFG edge. | 2031 // CFG edge. |
2015 node->continue_target()->set_direction(JumpTarget::BIDIRECTIONAL); | 2032 node->continue_target()->SetExpectedHeight(); |
2016 node->continue_target()->Bind(); | 2033 node->continue_target()->Bind(); |
2017 | 2034 |
2018 if (info == DONT_KNOW) { | 2035 if (info == DONT_KNOW) { |
2019 JumpTarget body; | 2036 JumpTarget body; |
2020 LoadConditionAndSpill(node->cond(), &body, node->break_target(), true); | 2037 LoadConditionAndSpill(node->cond(), &body, node->break_target(), true); |
2021 if (has_valid_frame()) { | 2038 if (has_valid_frame()) { |
2022 // A NULL frame indicates that control did not fall out of the | 2039 // A NULL frame indicates that control did not fall out of the |
2023 // test expression. | 2040 // test expression. |
2024 Branch(false, node->break_target()); | 2041 Branch(false, node->break_target()); |
2025 } | 2042 } |
(...skipping 28 matching lines...) Expand all Loading... | |
2054 CodeForStatementPosition(node); | 2071 CodeForStatementPosition(node); |
2055 if (node->init() != NULL) { | 2072 if (node->init() != NULL) { |
2056 VisitAndSpill(node->init()); | 2073 VisitAndSpill(node->init()); |
2057 } | 2074 } |
2058 | 2075 |
2059 // If the test is never true there is no need to compile the test or | 2076 // If the test is never true there is no need to compile the test or |
2060 // body. | 2077 // body. |
2061 ConditionAnalysis info = AnalyzeCondition(node->cond()); | 2078 ConditionAnalysis info = AnalyzeCondition(node->cond()); |
2062 if (info == ALWAYS_FALSE) return; | 2079 if (info == ALWAYS_FALSE) return; |
2063 | 2080 |
2064 node->break_target()->set_direction(JumpTarget::FORWARD_ONLY); | 2081 node->break_target()->SetExpectedHeight(); |
2065 IncrementLoopNesting(); | 2082 IncrementLoopNesting(); |
2066 | 2083 |
2067 // If there is no update statement, label the top of the loop with the | 2084 // If there is no update statement, label the top of the loop with the |
2068 // continue target, otherwise with the loop target. | 2085 // continue target, otherwise with the loop target. |
2069 JumpTarget loop(JumpTarget::BIDIRECTIONAL); | 2086 JumpTarget loop(JumpTarget::BIDIRECTIONAL); |
2070 if (node->next() == NULL) { | 2087 if (node->next() == NULL) { |
2071 node->continue_target()->set_direction(JumpTarget::BIDIRECTIONAL); | 2088 node->continue_target()->SetExpectedHeight(); |
2072 node->continue_target()->Bind(); | 2089 node->continue_target()->Bind(); |
2073 } else { | 2090 } else { |
2074 node->continue_target()->set_direction(JumpTarget::FORWARD_ONLY); | 2091 node->continue_target()->SetExpectedHeight(); |
2075 loop.Bind(); | 2092 loop.Bind(); |
2076 } | 2093 } |
2077 | 2094 |
2078 // If the test is always true, there is no need to compile it. | 2095 // If the test is always true, there is no need to compile it. |
2079 if (info == DONT_KNOW) { | 2096 if (info == DONT_KNOW) { |
2080 JumpTarget body; | 2097 JumpTarget body; |
2081 LoadConditionAndSpill(node->cond(), &body, node->break_target(), true); | 2098 LoadConditionAndSpill(node->cond(), &body, node->break_target(), true); |
2082 if (has_valid_frame()) { | 2099 if (has_valid_frame()) { |
2083 Branch(false, node->break_target()); | 2100 Branch(false, node->break_target()); |
2084 } | 2101 } |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2269 | 2286 |
2270 // Condition. | 2287 // Condition. |
2271 entry.Bind(); | 2288 entry.Bind(); |
2272 // sp[0] : index | 2289 // sp[0] : index |
2273 // sp[1] : array/enum cache length | 2290 // sp[1] : array/enum cache length |
2274 // sp[2] : array or enum cache | 2291 // sp[2] : array or enum cache |
2275 // sp[3] : 0 or map | 2292 // sp[3] : 0 or map |
2276 // sp[4] : enumerable | 2293 // sp[4] : enumerable |
2277 // Grab the current frame's height for the break and continue | 2294 // Grab the current frame's height for the break and continue |
2278 // targets only after all the state is pushed on the frame. | 2295 // targets only after all the state is pushed on the frame. |
2279 node->break_target()->set_direction(JumpTarget::FORWARD_ONLY); | 2296 node->break_target()->SetExpectedHeight(); |
2280 node->continue_target()->set_direction(JumpTarget::FORWARD_ONLY); | 2297 node->continue_target()->SetExpectedHeight(); |
2281 | 2298 |
2282 __ ldr(r0, frame_->ElementAt(0)); // load the current count | 2299 __ ldr(r0, frame_->ElementAt(0)); // load the current count |
2283 __ ldr(r1, frame_->ElementAt(1)); // load the length | 2300 __ ldr(r1, frame_->ElementAt(1)); // load the length |
2284 __ cmp(r0, r1); // compare to the array length | 2301 __ cmp(r0, r1); // compare to the array length |
2285 node->break_target()->Branch(hs); | 2302 node->break_target()->Branch(hs); |
2286 | 2303 |
2287 __ ldr(r0, frame_->ElementAt(0)); | 2304 __ ldr(r0, frame_->ElementAt(0)); |
2288 | 2305 |
2289 // Get the i'th entry of the array. | 2306 // Get the i'th entry of the array. |
2290 __ ldr(r2, frame_->ElementAt(2)); | 2307 __ ldr(r2, frame_->ElementAt(2)); |
(...skipping 7589 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9880 | 9897 |
9881 // Just jump to runtime to add the two strings. | 9898 // Just jump to runtime to add the two strings. |
9882 __ bind(&string_add_runtime); | 9899 __ bind(&string_add_runtime); |
9883 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); | 9900 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); |
9884 } | 9901 } |
9885 | 9902 |
9886 | 9903 |
9887 #undef __ | 9904 #undef __ |
9888 | 9905 |
9889 } } // namespace v8::internal | 9906 } } // namespace v8::internal |
OLD | NEW |