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

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

Issue 18362: Experimental: statically distinguish between named basic block entries... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/toiger/
Patch Set: Created 11 years, 11 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/codegen.cc ('k') | src/jump-target.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 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 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 ZoneList<Statement*>* body = fun->body(); 131 ZoneList<Statement*>* body = fun->body();
132 132
133 // Initialize state. 133 // Initialize state.
134 ASSERT(scope_ == NULL); 134 ASSERT(scope_ == NULL);
135 scope_ = fun->scope(); 135 scope_ = fun->scope();
136 ASSERT(allocator_ == NULL); 136 ASSERT(allocator_ == NULL);
137 RegisterAllocator register_allocator(this); 137 RegisterAllocator register_allocator(this);
138 allocator_ = &register_allocator; 138 allocator_ = &register_allocator;
139 ASSERT(frame_ == NULL); 139 ASSERT(frame_ == NULL);
140 frame_ = new VirtualFrame(this); 140 frame_ = new VirtualFrame(this);
141 function_return_.set_code_generator(this); 141 function_return_.Initialize(this, JumpTarget::BIDIRECTIONAL);
142 function_return_is_shadowed_ = false; 142 function_return_is_shadowed_ = false;
143 set_in_spilled_code(false); 143 set_in_spilled_code(false);
144 144
145 // Adjust for function-level loop nesting. 145 // Adjust for function-level loop nesting.
146 loop_nesting_ += fun->loop_nesting(); 146 loop_nesting_ += fun->loop_nesting();
147 147
148 { 148 {
149 CodeGenState state(this); 149 CodeGenState state(this);
150 150
151 // Entry 151 // Entry
(...skipping 1198 matching lines...) Expand 10 before | Expand all | Expand 10 after
1350 Visit(statements->at(i)); 1350 Visit(statements->at(i));
1351 } 1351 }
1352 } 1352 }
1353 1353
1354 1354
1355 void CodeGenerator::VisitBlock(Block* node) { 1355 void CodeGenerator::VisitBlock(Block* node) {
1356 ASSERT(!in_spilled_code()); 1356 ASSERT(!in_spilled_code());
1357 Comment cmnt(masm_, "[ Block"); 1357 Comment cmnt(masm_, "[ Block");
1358 CodeForStatement(node); 1358 CodeForStatement(node);
1359 node->set_break_stack_height(break_stack_height_); 1359 node->set_break_stack_height(break_stack_height_);
1360 node->break_target()->set_code_generator(this); 1360 node->break_target()->Initialize(this);
1361 VisitStatements(node->statements()); 1361 VisitStatements(node->statements());
1362 if (node->break_target()->is_linked()) { 1362 if (node->break_target()->is_linked()) {
1363 node->break_target()->Bind(); 1363 node->break_target()->Bind();
1364 } 1364 }
1365 } 1365 }
1366 1366
1367 1367
1368 void CodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 1368 void CodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
1369 VirtualFrame::SpilledScope spilled_scope(this); 1369 VirtualFrame::SpilledScope spilled_scope(this);
1370 frame_->EmitPush(Immediate(pairs)); 1370 frame_->EmitPush(Immediate(pairs));
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after
1732 __ WriteInternalReference(entry_pos, *case_targets[i]->entry_label()); 1732 __ WriteInternalReference(entry_pos, *case_targets[i]->entry_label());
1733 } 1733 }
1734 } 1734 }
1735 1735
1736 1736
1737 void CodeGenerator::VisitSwitchStatement(SwitchStatement* node) { 1737 void CodeGenerator::VisitSwitchStatement(SwitchStatement* node) {
1738 ASSERT(!in_spilled_code()); 1738 ASSERT(!in_spilled_code());
1739 Comment cmnt(masm_, "[ SwitchStatement"); 1739 Comment cmnt(masm_, "[ SwitchStatement");
1740 CodeForStatement(node); 1740 CodeForStatement(node);
1741 node->set_break_stack_height(break_stack_height_); 1741 node->set_break_stack_height(break_stack_height_);
1742 node->break_target()->set_code_generator(this); 1742 node->break_target()->Initialize(this);
1743 1743
1744 Load(node->tag()); 1744 Load(node->tag());
1745 1745
1746 if (TryGenerateFastCaseSwitchStatement(node)) { 1746 if (TryGenerateFastCaseSwitchStatement(node)) {
1747 return; 1747 return;
1748 } 1748 }
1749 1749
1750 JumpTarget next_test(this); 1750 JumpTarget next_test(this);
1751 JumpTarget fall_through(this); 1751 JumpTarget fall_through(this);
1752 JumpTarget default_entry(this); 1752 JumpTarget default_entry(this);
1753 JumpTarget default_exit(this); 1753 JumpTarget default_exit(this, JumpTarget::BIDIRECTIONAL);
1754 ZoneList<CaseClause*>* cases = node->cases(); 1754 ZoneList<CaseClause*>* cases = node->cases();
1755 int length = cases->length(); 1755 int length = cases->length();
1756 CaseClause* default_clause = NULL; 1756 CaseClause* default_clause = NULL;
1757 1757
1758 for (int i = 0; i < length; i++) { 1758 for (int i = 0; i < length; i++) {
1759 CaseClause* clause = cases->at(i); 1759 CaseClause* clause = cases->at(i);
1760 if (clause->is_default()) { 1760 if (clause->is_default()) {
1761 // Remember the default clause and compile it at the end. 1761 // Remember the default clause and compile it at the end.
1762 default_clause = clause; 1762 default_clause = clause;
1763 continue; 1763 continue;
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1831 node->break_target()->Bind(); 1831 node->break_target()->Bind();
1832 } 1832 }
1833 } 1833 }
1834 1834
1835 1835
1836 void CodeGenerator::VisitLoopStatement(LoopStatement* node) { 1836 void CodeGenerator::VisitLoopStatement(LoopStatement* node) {
1837 ASSERT(!in_spilled_code()); 1837 ASSERT(!in_spilled_code());
1838 Comment cmnt(masm_, "[ LoopStatement"); 1838 Comment cmnt(masm_, "[ LoopStatement");
1839 CodeForStatement(node); 1839 CodeForStatement(node);
1840 node->set_break_stack_height(break_stack_height_); 1840 node->set_break_stack_height(break_stack_height_);
1841 node->break_target()->set_code_generator(this); 1841 node->break_target()->Initialize(this);
1842 node->continue_target()->set_code_generator(this);
1843 1842
1844 // Simple condition analysis. ALWAYS_TRUE and ALWAYS_FALSE represent a 1843 // Simple condition analysis. ALWAYS_TRUE and ALWAYS_FALSE represent a
1845 // known result for the test expression, with no side effects. 1844 // known result for the test expression, with no side effects.
1846 enum { ALWAYS_TRUE, ALWAYS_FALSE, DONT_KNOW } info = DONT_KNOW; 1845 enum { ALWAYS_TRUE, ALWAYS_FALSE, DONT_KNOW } info = DONT_KNOW;
1847 if (node->cond() == NULL) { 1846 if (node->cond() == NULL) {
1848 ASSERT(node->type() == LoopStatement::FOR_LOOP); 1847 ASSERT(node->type() == LoopStatement::FOR_LOOP);
1849 info = ALWAYS_TRUE; 1848 info = ALWAYS_TRUE;
1850 } else { 1849 } else {
1851 Literal* lit = node->cond()->AsLiteral(); 1850 Literal* lit = node->cond()->AsLiteral();
1852 if (lit != NULL) { 1851 if (lit != NULL) {
1853 if (lit->IsTrue()) { 1852 if (lit->IsTrue()) {
1854 info = ALWAYS_TRUE; 1853 info = ALWAYS_TRUE;
1855 } else if (lit->IsFalse()) { 1854 } else if (lit->IsFalse()) {
1856 info = ALWAYS_FALSE; 1855 info = ALWAYS_FALSE;
1857 } 1856 }
1858 } 1857 }
1859 } 1858 }
1860 1859
1861 switch (node->type()) { 1860 switch (node->type()) {
1862 case LoopStatement::DO_LOOP: { 1861 case LoopStatement::DO_LOOP: {
1863 JumpTarget body(this); 1862 JumpTarget body(this, JumpTarget::BIDIRECTIONAL);
1864 IncrementLoopNesting(); 1863 IncrementLoopNesting();
1865 1864
1866 // Label the top of the loop for the backward CFG edge. If the test 1865 // Label the top of the loop for the backward CFG edge. If the test
1867 // is always true we can use the continue target, and if the test is 1866 // is always true we can use the continue target, and if the test is
1868 // always false there is no need. 1867 // always false there is no need.
1869 if (info == ALWAYS_TRUE) { 1868 if (info == ALWAYS_TRUE) {
1869 node->continue_target()->Initialize(this, JumpTarget::BIDIRECTIONAL);
1870 node->continue_target()->Bind(); 1870 node->continue_target()->Bind();
1871 } else if (info == ALWAYS_FALSE) { 1871 } else if (info == ALWAYS_FALSE) {
1872 node->continue_target()->Initialize(this);
1872 // There is no need, we will never jump back. 1873 // There is no need, we will never jump back.
1873 } else { 1874 } else {
1874 ASSERT(info == DONT_KNOW); 1875 ASSERT(info == DONT_KNOW);
1876 node->continue_target()->Initialize(this);
1875 body.Bind(); 1877 body.Bind();
1876 } 1878 }
1877 1879
1878 CheckStack(); // TODO(1222600): ignore if body contains calls. 1880 CheckStack(); // TODO(1222600): ignore if body contains calls.
1879 Visit(node->body()); 1881 Visit(node->body());
1880 1882
1881 // Compile the test. 1883 // Compile the test.
1882 if (info == ALWAYS_TRUE) { 1884 if (info == ALWAYS_TRUE) {
1883 // If control flow can fall off the end of the body, jump back to 1885 // If control flow can fall off the end of the body, jump back to
1884 // the top. 1886 // the top.
(...skipping 22 matching lines...) Expand all
1907 1909
1908 case LoopStatement::WHILE_LOOP: { 1910 case LoopStatement::WHILE_LOOP: {
1909 IncrementLoopNesting(); 1911 IncrementLoopNesting();
1910 1912
1911 // If the test is never true and has no side effects there is no need 1913 // If the test is never true and has no side effects there is no need
1912 // to compile the test or body. 1914 // to compile the test or body.
1913 if (info == ALWAYS_FALSE) break; 1915 if (info == ALWAYS_FALSE) break;
1914 1916
1915 // Label the top of the loop with the continue target for the backward 1917 // Label the top of the loop with the continue target for the backward
1916 // CFG edge. 1918 // CFG edge.
1919 node->continue_target()->Initialize(this, JumpTarget::BIDIRECTIONAL);
1917 node->continue_target()->Bind(); 1920 node->continue_target()->Bind();
1918 1921
1919 // If the test is always true and has no side effects there is no need 1922 // If the test is always true and has no side effects there is no need
1920 // to compile it. We only compile the test when we do not know its 1923 // to compile it. We only compile the test when we do not know its
1921 // outcome or it may have side effects. 1924 // outcome or it may have side effects.
1922 if (info == DONT_KNOW) { 1925 if (info == DONT_KNOW) {
1923 JumpTarget body(this); 1926 JumpTarget body(this);
1924 LoadCondition(node->cond(), NOT_INSIDE_TYPEOF, 1927 LoadCondition(node->cond(), NOT_INSIDE_TYPEOF,
1925 &body, node->break_target(), true); 1928 &body, node->break_target(), true);
1926 if (body.is_linked()) { 1929 if (body.is_linked()) {
1927 body.Bind(); 1930 body.Bind();
1928 } 1931 }
1929 } 1932 }
1930 1933
1931 if (has_valid_frame()) { 1934 if (has_valid_frame()) {
1932 CheckStack(); // TODO(1222600): ignore if body contains calls. 1935 CheckStack(); // TODO(1222600): ignore if body contains calls.
1933 Visit(node->body()); 1936 Visit(node->body());
1934 1937
1935 // If control flow can fall out of the body, jump back to the top. 1938 // If control flow can fall out of the body, jump back to the top.
1936 if (has_valid_frame()) { 1939 if (has_valid_frame()) {
1937 node->continue_target()->Jump(); 1940 node->continue_target()->Jump();
1938 } 1941 }
1939 } 1942 }
1940 break; 1943 break;
1941 } 1944 }
1942 1945
1943 case LoopStatement::FOR_LOOP: { 1946 case LoopStatement::FOR_LOOP: {
1944 JumpTarget loop(this); 1947 JumpTarget loop(this, JumpTarget::BIDIRECTIONAL);
1945 if (node->init() != NULL) { 1948 if (node->init() != NULL) {
1946 Visit(node->init()); 1949 Visit(node->init());
1947 } 1950 }
1948 1951
1949 IncrementLoopNesting(); 1952 IncrementLoopNesting();
1950 // If the test is never true and has no side effects there is no need 1953 // If the test is never true and has no side effects there is no need
1951 // to compile the test or body. 1954 // to compile the test or body.
1952 if (info == ALWAYS_FALSE) break; 1955 if (info == ALWAYS_FALSE) break;
1953 1956
1954 // Label the top of the loop for the backward CFG edge. If there is 1957 // Label the top of the loop for the backward CFG edge. If there is
1955 // no update expression we can use the continue target. 1958 // no update expression we can use the continue target.
1956 if (node->next() == NULL) { 1959 if (node->next() == NULL) {
1960 node->continue_target()->Initialize(this, JumpTarget::BIDIRECTIONAL);
1957 node->continue_target()->Bind(); 1961 node->continue_target()->Bind();
1958 } else { 1962 } else {
1963 node->continue_target()->Initialize(this);
1959 loop.Bind(); 1964 loop.Bind();
1960 } 1965 }
1961 1966
1962 // If the test is always true and has no side effects there is no need 1967 // If the test is always true and has no side effects there is no need
1963 // to compile it. We only compile the test when we do not know its 1968 // to compile it. We only compile the test when we do not know its
1964 // outcome or it has side effects. 1969 // outcome or it has side effects.
1965 if (info == DONT_KNOW) { 1970 if (info == DONT_KNOW) {
1966 JumpTarget body(this); 1971 JumpTarget body(this);
1967 LoadCondition(node->cond(), NOT_INSIDE_TYPEOF, 1972 LoadCondition(node->cond(), NOT_INSIDE_TYPEOF,
1968 &body, node->break_target(), true); 1973 &body, node->break_target(), true);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
2015 VirtualFrame::SpilledScope spilled_scope(this); 2020 VirtualFrame::SpilledScope spilled_scope(this);
2016 Comment cmnt(masm_, "[ ForInStatement"); 2021 Comment cmnt(masm_, "[ ForInStatement");
2017 CodeForStatement(node); 2022 CodeForStatement(node);
2018 2023
2019 // We keep stuff on the stack while the body is executing. 2024 // We keep stuff on the stack while the body is executing.
2020 // Record it, so that a break/continue crossing this statement 2025 // Record it, so that a break/continue crossing this statement
2021 // can restore the stack. 2026 // can restore the stack.
2022 const int kForInStackSize = 5 * kPointerSize; 2027 const int kForInStackSize = 5 * kPointerSize;
2023 break_stack_height_ += kForInStackSize; 2028 break_stack_height_ += kForInStackSize;
2024 node->set_break_stack_height(break_stack_height_); 2029 node->set_break_stack_height(break_stack_height_);
2025 node->break_target()->set_code_generator(this); 2030 node->break_target()->Initialize(this);
2026 node->continue_target()->set_code_generator(this); 2031 node->continue_target()->Initialize(this);
2027 2032
2028 JumpTarget primitive(this); 2033 JumpTarget primitive(this);
2029 JumpTarget jsobject(this); 2034 JumpTarget jsobject(this);
2030 JumpTarget fixed_array(this); 2035 JumpTarget fixed_array(this);
2031 JumpTarget entry(this); 2036 JumpTarget entry(this, JumpTarget::BIDIRECTIONAL);
2032 JumpTarget end_del_check(this); 2037 JumpTarget end_del_check(this);
2033 JumpTarget cleanup(this); 2038 JumpTarget cleanup(this);
2034 JumpTarget exit(this); 2039 JumpTarget exit(this);
2035 2040
2036 // Get the object to enumerate over (converted to JSObject). 2041 // Get the object to enumerate over (converted to JSObject).
2037 LoadAndSpill(node->enumerable()); 2042 LoadAndSpill(node->enumerable());
2038 2043
2039 // Both SpiderMonkey and kjs ignore null and undefined in contrast 2044 // Both SpiderMonkey and kjs ignore null and undefined in contrast
2040 // to the specification. 12.6.4 mandates a call to ToObject. 2045 // to the specification. 12.6.4 mandates a call to ToObject.
2041 frame_->EmitPop(eax); 2046 frame_->EmitPop(eax);
(...skipping 1315 matching lines...) Expand 10 before | Expand all | Expand 10 after
3357 // cons strings where the answer is found in the left hand branch of the 3362 // cons strings where the answer is found in the left hand branch of the
3358 // cons. The slow case will flatten the string, which will ensure that 3363 // cons. The slow case will flatten the string, which will ensure that
3359 // the answer is in the left hand side the next time around. 3364 // the answer is in the left hand side the next time around.
3360 void CodeGenerator::GenerateFastCharCodeAt(ZoneList<Expression*>* args) { 3365 void CodeGenerator::GenerateFastCharCodeAt(ZoneList<Expression*>* args) {
3361 ASSERT(args->length() == 2); 3366 ASSERT(args->length() == 2);
3362 3367
3363 JumpTarget slow_case(this); 3368 JumpTarget slow_case(this);
3364 JumpTarget end(this); 3369 JumpTarget end(this);
3365 JumpTarget not_a_flat_string(this); 3370 JumpTarget not_a_flat_string(this);
3366 JumpTarget not_a_cons_string_either(this); 3371 JumpTarget not_a_cons_string_either(this);
3367 JumpTarget try_again_with_new_string(this); 3372 JumpTarget try_again_with_new_string(this, JumpTarget::BIDIRECTIONAL);
3368 JumpTarget ascii_string(this); 3373 JumpTarget ascii_string(this);
3369 JumpTarget got_char_code(this); 3374 JumpTarget got_char_code(this);
3370 3375
3371 // Load the string into eax and the index into ebx. 3376 // Load the string into eax and the index into ebx.
3372 LoadAndSpill(args->at(0)); 3377 LoadAndSpill(args->at(0));
3373 LoadAndSpill(args->at(1)); 3378 LoadAndSpill(args->at(1));
3374 frame_->EmitPop(ebx); 3379 frame_->EmitPop(ebx);
3375 frame_->EmitPop(eax); 3380 frame_->EmitPop(eax);
3376 // If the receiver is a smi return undefined. 3381 // If the receiver is a smi return undefined.
3377 ASSERT(kSmiTag == 0); 3382 ASSERT(kSmiTag == 0);
(...skipping 2706 matching lines...) Expand 10 before | Expand all | Expand 10 after
6084 6089
6085 // Slow-case: Go through the JavaScript implementation. 6090 // Slow-case: Go through the JavaScript implementation.
6086 __ bind(&slow); 6091 __ bind(&slow);
6087 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); 6092 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION);
6088 } 6093 }
6089 6094
6090 6095
6091 #undef __ 6096 #undef __
6092 6097
6093 } } // namespace v8::internal 6098 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/codegen.cc ('k') | src/jump-target.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698