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

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

Issue 6062002: Merge 6006:6095 from bleeding_edge to experimental/gc branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 10 years 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/full-codegen.h ('k') | src/heap.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 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 653 matching lines...) Expand 10 before | Expand all | Expand 10 after
664 const FullCodeGenerator::InlineFunctionGenerator 664 const FullCodeGenerator::InlineFunctionGenerator
665 FullCodeGenerator::kInlineFunctionGenerators[] = { 665 FullCodeGenerator::kInlineFunctionGenerators[] = {
666 INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS) 666 INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS)
667 INLINE_RUNTIME_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS) 667 INLINE_RUNTIME_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS)
668 }; 668 };
669 #undef INLINE_FUNCTION_GENERATOR_ADDRESS 669 #undef INLINE_FUNCTION_GENERATOR_ADDRESS
670 670
671 671
672 FullCodeGenerator::InlineFunctionGenerator 672 FullCodeGenerator::InlineFunctionGenerator
673 FullCodeGenerator::FindInlineFunctionGenerator(Runtime::FunctionId id) { 673 FullCodeGenerator::FindInlineFunctionGenerator(Runtime::FunctionId id) {
674 return kInlineFunctionGenerators[ 674 int lookup_index =
675 static_cast<int>(id) - static_cast<int>(Runtime::kFirstInlineFunction)]; 675 static_cast<int>(id) - static_cast<int>(Runtime::kFirstInlineFunction);
676 ASSERT(lookup_index >= 0);
677 ASSERT(static_cast<size_t>(lookup_index) <
678 ARRAY_SIZE(kInlineFunctionGenerators));
679 return kInlineFunctionGenerators[lookup_index];
676 } 680 }
677 681
678 682
679 void FullCodeGenerator::EmitInlineRuntimeCall(CallRuntime* node) { 683 void FullCodeGenerator::EmitInlineRuntimeCall(CallRuntime* node) {
680 ZoneList<Expression*>* args = node->arguments(); 684 ZoneList<Expression*>* args = node->arguments();
681 Handle<String> name = node->name(); 685 Handle<String> name = node->name();
682 Runtime::Function* function = node->function(); 686 Runtime::Function* function = node->function();
683 ASSERT(function != NULL); 687 ASSERT(function != NULL);
684 ASSERT(function->intrinsic_type == Runtime::INLINE); 688 ASSERT(function->intrinsic_type == Runtime::INLINE);
685 InlineFunctionGenerator generator = 689 InlineFunctionGenerator generator =
686 FindInlineFunctionGenerator(function->function_id); 690 FindInlineFunctionGenerator(function->function_id);
687 ASSERT(generator != NULL);
688 ((*this).*(generator))(args); 691 ((*this).*(generator))(args);
689 } 692 }
690 693
691 694
692 void FullCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { 695 void FullCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
693 Comment cmnt(masm_, "[ BinaryOperation"); 696 Comment cmnt(masm_, "[ BinaryOperation");
694 Token::Value op = expr->op(); 697 Token::Value op = expr->op();
695 Expression* left = expr->left(); 698 Expression* left = expr->left();
696 Expression* right = expr->right(); 699 Expression* right = expr->right();
697 700
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
754 UNREACHABLE(); 757 UNREACHABLE();
755 } 758 }
756 } 759 }
757 760
758 761
759 void FullCodeGenerator::EmitLogicalOperation(BinaryOperation* expr) { 762 void FullCodeGenerator::EmitLogicalOperation(BinaryOperation* expr) {
760 Label eval_right, done; 763 Label eval_right, done;
761 764
762 context()->EmitLogicalLeft(expr, &eval_right, &done); 765 context()->EmitLogicalLeft(expr, &eval_right, &done);
763 766
767 PrepareForBailoutForId(expr->RightId(), NO_REGISTERS);
764 __ bind(&eval_right); 768 __ bind(&eval_right);
765 if (context()->IsTest()) ForwardBailoutToChild(expr); 769 if (context()->IsTest()) ForwardBailoutToChild(expr);
766 context()->HandleExpression(expr->right()); 770 context()->HandleExpression(expr->right());
767 771
768 __ bind(&done); 772 __ bind(&done);
769 } 773 }
770 774
771 775
772 void FullCodeGenerator::EffectContext::EmitLogicalLeft(BinaryOperation* expr, 776 void FullCodeGenerator::EffectContext::EmitLogicalLeft(BinaryOperation* expr,
773 Label* eval_right, 777 Label* eval_right,
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
918 } 922 }
919 923
920 924
921 void FullCodeGenerator::VisitIfStatement(IfStatement* stmt) { 925 void FullCodeGenerator::VisitIfStatement(IfStatement* stmt) {
922 Comment cmnt(masm_, "[ IfStatement"); 926 Comment cmnt(masm_, "[ IfStatement");
923 SetStatementPosition(stmt); 927 SetStatementPosition(stmt);
924 Label then_part, else_part, done; 928 Label then_part, else_part, done;
925 929
926 if (stmt->HasElseStatement()) { 930 if (stmt->HasElseStatement()) {
927 VisitForControl(stmt->condition(), &then_part, &else_part, &then_part); 931 VisitForControl(stmt->condition(), &then_part, &else_part, &then_part);
932 PrepareForBailoutForId(stmt->ThenId(), NO_REGISTERS);
928 __ bind(&then_part); 933 __ bind(&then_part);
929 Visit(stmt->then_statement()); 934 Visit(stmt->then_statement());
930 __ jmp(&done); 935 __ jmp(&done);
931 936
937 PrepareForBailoutForId(stmt->ElseId(), NO_REGISTERS);
932 __ bind(&else_part); 938 __ bind(&else_part);
933 Visit(stmt->else_statement()); 939 Visit(stmt->else_statement());
934 } else { 940 } else {
935 VisitForControl(stmt->condition(), &then_part, &done, &then_part); 941 VisitForControl(stmt->condition(), &then_part, &done, &then_part);
942 PrepareForBailoutForId(stmt->ThenId(), NO_REGISTERS);
936 __ bind(&then_part); 943 __ bind(&then_part);
937 Visit(stmt->then_statement()); 944 Visit(stmt->then_statement());
945
946 PrepareForBailoutForId(stmt->ElseId(), NO_REGISTERS);
938 } 947 }
939 __ bind(&done); 948 __ bind(&done);
940 PrepareForBailoutForId(stmt->id(), NO_REGISTERS); 949 PrepareForBailoutForId(stmt->id(), NO_REGISTERS);
941 } 950 }
942 951
943 952
944 void FullCodeGenerator::VisitContinueStatement(ContinueStatement* stmt) { 953 void FullCodeGenerator::VisitContinueStatement(ContinueStatement* stmt) {
945 Comment cmnt(masm_, "[ ContinueStatement"); 954 Comment cmnt(masm_, "[ ContinueStatement");
946 SetStatementPosition(stmt); 955 SetStatementPosition(stmt);
947 NestedStatement* current = nesting_stack_; 956 NestedStatement* current = nesting_stack_;
948 int stack_depth = 0; 957 int stack_depth = 0;
958 // When continuing, we clobber the unpredictable value in the accumulator
959 // with one that's safe for GC. If we hit an exit from the try block of
960 // try...finally on our way out, we will unconditionally preserve the
961 // accumulator on the stack.
962 ClearAccumulator();
949 while (!current->IsContinueTarget(stmt->target())) { 963 while (!current->IsContinueTarget(stmt->target())) {
950 stack_depth = current->Exit(stack_depth); 964 stack_depth = current->Exit(stack_depth);
951 current = current->outer(); 965 current = current->outer();
952 } 966 }
953 __ Drop(stack_depth); 967 __ Drop(stack_depth);
954 968
955 Iteration* loop = current->AsIteration(); 969 Iteration* loop = current->AsIteration();
956 __ jmp(loop->continue_target()); 970 __ jmp(loop->continue_target());
957 } 971 }
958 972
959 973
960 void FullCodeGenerator::VisitBreakStatement(BreakStatement* stmt) { 974 void FullCodeGenerator::VisitBreakStatement(BreakStatement* stmt) {
961 Comment cmnt(masm_, "[ BreakStatement"); 975 Comment cmnt(masm_, "[ BreakStatement");
962 SetStatementPosition(stmt); 976 SetStatementPosition(stmt);
963 NestedStatement* current = nesting_stack_; 977 NestedStatement* current = nesting_stack_;
964 int stack_depth = 0; 978 int stack_depth = 0;
979 // When breaking, we clobber the unpredictable value in the accumulator
980 // with one that's safe for GC. If we hit an exit from the try block of
981 // try...finally on our way out, we will unconditionally preserve the
982 // accumulator on the stack.
983 ClearAccumulator();
965 while (!current->IsBreakTarget(stmt->target())) { 984 while (!current->IsBreakTarget(stmt->target())) {
966 stack_depth = current->Exit(stack_depth); 985 stack_depth = current->Exit(stack_depth);
967 current = current->outer(); 986 current = current->outer();
968 } 987 }
969 __ Drop(stack_depth); 988 __ Drop(stack_depth);
970 989
971 Breakable* target = current->AsBreakable(); 990 Breakable* target = current->AsBreakable();
972 __ jmp(target->break_target()); 991 __ jmp(target->break_target());
973 } 992 }
974 993
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1036 // possible to break on the condition. 1055 // possible to break on the condition.
1037 __ bind(loop_statement.continue_target()); 1056 __ bind(loop_statement.continue_target());
1038 PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS); 1057 PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS);
1039 SetExpressionPosition(stmt->cond(), stmt->condition_position()); 1058 SetExpressionPosition(stmt->cond(), stmt->condition_position());
1040 VisitForControl(stmt->cond(), 1059 VisitForControl(stmt->cond(),
1041 &stack_check, 1060 &stack_check,
1042 loop_statement.break_target(), 1061 loop_statement.break_target(),
1043 &stack_check); 1062 &stack_check);
1044 1063
1045 // Check stack before looping. 1064 // Check stack before looping.
1065 PrepareForBailoutForId(stmt->BackEdgeId(), NO_REGISTERS);
1046 __ bind(&stack_check); 1066 __ bind(&stack_check);
1047 EmitStackCheck(stmt); 1067 EmitStackCheck(stmt);
1048 __ jmp(&body); 1068 __ jmp(&body);
1049 1069
1070 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1050 __ bind(loop_statement.break_target()); 1071 __ bind(loop_statement.break_target());
1051 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1052 decrement_loop_depth(); 1072 decrement_loop_depth();
1053 } 1073 }
1054 1074
1055 1075
1056 void FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) { 1076 void FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
1057 Comment cmnt(masm_, "[ WhileStatement"); 1077 Comment cmnt(masm_, "[ WhileStatement");
1058 Label test, body; 1078 Label test, body;
1059 1079
1060 Iteration loop_statement(this, stmt); 1080 Iteration loop_statement(this, stmt);
1061 increment_loop_depth(); 1081 increment_loop_depth();
1062 1082
1063 // Emit the test at the bottom of the loop. 1083 // Emit the test at the bottom of the loop.
1064 __ jmp(&test); 1084 __ jmp(&test);
1065 1085
1086 PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS);
1066 __ bind(&body); 1087 __ bind(&body);
1067 Visit(stmt->body()); 1088 Visit(stmt->body());
1068 1089
1069 // Emit the statement position here as this is where the while 1090 // Emit the statement position here as this is where the while
1070 // statement code starts. 1091 // statement code starts.
1071 __ bind(loop_statement.continue_target()); 1092 __ bind(loop_statement.continue_target());
1072 SetStatementPosition(stmt); 1093 SetStatementPosition(stmt);
1073 1094
1074 // Check stack before looping. 1095 // Check stack before looping.
1075 EmitStackCheck(stmt); 1096 EmitStackCheck(stmt);
1076 1097
1077 __ bind(&test); 1098 __ bind(&test);
1078 VisitForControl(stmt->cond(), 1099 VisitForControl(stmt->cond(),
1079 &body, 1100 &body,
1080 loop_statement.break_target(), 1101 loop_statement.break_target(),
1081 loop_statement.break_target()); 1102 loop_statement.break_target());
1082 1103
1104 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1083 __ bind(loop_statement.break_target()); 1105 __ bind(loop_statement.break_target());
1084 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1085 decrement_loop_depth(); 1106 decrement_loop_depth();
1086 } 1107 }
1087 1108
1088 1109
1089 void FullCodeGenerator::VisitForStatement(ForStatement* stmt) { 1110 void FullCodeGenerator::VisitForStatement(ForStatement* stmt) {
1090 Comment cmnt(masm_, "[ ForStatement"); 1111 Comment cmnt(masm_, "[ ForStatement");
1091 Label test, body; 1112 Label test, body;
1092 1113
1093 Iteration loop_statement(this, stmt); 1114 Iteration loop_statement(this, stmt);
1094 if (stmt->init() != NULL) { 1115 if (stmt->init() != NULL) {
1095 Visit(stmt->init()); 1116 Visit(stmt->init());
1096 } 1117 }
1097 1118
1098 increment_loop_depth(); 1119 increment_loop_depth();
1099 // Emit the test at the bottom of the loop (even if empty). 1120 // Emit the test at the bottom of the loop (even if empty).
1100 __ jmp(&test); 1121 __ jmp(&test);
1101 1122
1123 PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS);
1102 __ bind(&body); 1124 __ bind(&body);
1103 Visit(stmt->body()); 1125 Visit(stmt->body());
1104 1126
1127 PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS);
1105 __ bind(loop_statement.continue_target()); 1128 __ bind(loop_statement.continue_target());
1106 PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS);
1107
1108 SetStatementPosition(stmt); 1129 SetStatementPosition(stmt);
1109 if (stmt->next() != NULL) { 1130 if (stmt->next() != NULL) {
1110 Visit(stmt->next()); 1131 Visit(stmt->next());
1111 } 1132 }
1112 1133
1113 // Emit the statement position here as this is where the for 1134 // Emit the statement position here as this is where the for
1114 // statement code starts. 1135 // statement code starts.
1115 SetStatementPosition(stmt); 1136 SetStatementPosition(stmt);
1116 1137
1117 // Check stack before looping. 1138 // Check stack before looping.
1118 EmitStackCheck(stmt); 1139 EmitStackCheck(stmt);
1119 1140
1120 __ bind(&test); 1141 __ bind(&test);
1121 if (stmt->cond() != NULL) { 1142 if (stmt->cond() != NULL) {
1122 VisitForControl(stmt->cond(), 1143 VisitForControl(stmt->cond(),
1123 &body, 1144 &body,
1124 loop_statement.break_target(), 1145 loop_statement.break_target(),
1125 loop_statement.break_target()); 1146 loop_statement.break_target());
1126 } else { 1147 } else {
1127 __ jmp(&body); 1148 __ jmp(&body);
1128 } 1149 }
1129 1150
1151 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1130 __ bind(loop_statement.break_target()); 1152 __ bind(loop_statement.break_target());
1131 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1132 decrement_loop_depth(); 1153 decrement_loop_depth();
1133 } 1154 }
1134 1155
1135 1156
1136 void FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { 1157 void FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
1137 Comment cmnt(masm_, "[ TryCatchStatement"); 1158 Comment cmnt(masm_, "[ TryCatchStatement");
1138 SetStatementPosition(stmt); 1159 SetStatementPosition(stmt);
1139 // The try block adds a handler to the exception handler chain 1160 // The try block adds a handler to the exception handler chain
1140 // before entering, and removes it again when exiting normally. 1161 // before entering, and removes it again when exiting normally.
1141 // If an exception is thrown during execution of the try block, 1162 // If an exception is thrown during execution of the try block,
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1228 } 1249 }
1229 1250
1230 __ bind(&try_handler_setup); 1251 __ bind(&try_handler_setup);
1231 { 1252 {
1232 // Setup try handler (stack pointer registers). 1253 // Setup try handler (stack pointer registers).
1233 TryFinally try_block(this, &finally_entry); 1254 TryFinally try_block(this, &finally_entry);
1234 __ PushTryHandler(IN_JAVASCRIPT, TRY_FINALLY_HANDLER); 1255 __ PushTryHandler(IN_JAVASCRIPT, TRY_FINALLY_HANDLER);
1235 Visit(stmt->try_block()); 1256 Visit(stmt->try_block());
1236 __ PopTryHandler(); 1257 __ PopTryHandler();
1237 } 1258 }
1238 // Execute the finally block on the way out. 1259 // Execute the finally block on the way out. Clobber the unpredictable
1260 // value in the accumulator with one that's safe for GC. The finally
1261 // block will unconditionally preserve the accumulator on the stack.
1262 ClearAccumulator();
1239 __ Call(&finally_entry); 1263 __ Call(&finally_entry);
1240 } 1264 }
1241 1265
1242 1266
1243 void FullCodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) { 1267 void FullCodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) {
1244 #ifdef ENABLE_DEBUGGER_SUPPORT 1268 #ifdef ENABLE_DEBUGGER_SUPPORT
1245 Comment cmnt(masm_, "[ DebuggerStatement"); 1269 Comment cmnt(masm_, "[ DebuggerStatement");
1246 SetStatementPosition(stmt); 1270 SetStatementPosition(stmt);
1247 1271
1248 __ DebugBreak(); 1272 __ DebugBreak();
1249 // Ignore the return value. 1273 // Ignore the return value.
1250 #endif 1274 #endif
1251 } 1275 }
1252 1276
1253 1277
1254 void FullCodeGenerator::VisitConditional(Conditional* expr) { 1278 void FullCodeGenerator::VisitConditional(Conditional* expr) {
1255 Comment cmnt(masm_, "[ Conditional"); 1279 Comment cmnt(masm_, "[ Conditional");
1256 Label true_case, false_case, done; 1280 Label true_case, false_case, done;
1257 VisitForControl(expr->condition(), &true_case, &false_case, &true_case); 1281 VisitForControl(expr->condition(), &true_case, &false_case, &true_case);
1258 1282
1283 PrepareForBailoutForId(expr->ThenId(), NO_REGISTERS);
1259 __ bind(&true_case); 1284 __ bind(&true_case);
1260 SetExpressionPosition(expr->then_expression(), 1285 SetExpressionPosition(expr->then_expression(),
1261 expr->then_expression_position()); 1286 expr->then_expression_position());
1262 if (context()->IsTest()) { 1287 if (context()->IsTest()) {
1263 const TestContext* for_test = TestContext::cast(context()); 1288 const TestContext* for_test = TestContext::cast(context());
1264 VisitForControl(expr->then_expression(), 1289 VisitForControl(expr->then_expression(),
1265 for_test->true_label(), 1290 for_test->true_label(),
1266 for_test->false_label(), 1291 for_test->false_label(),
1267 NULL); 1292 NULL);
1268 } else { 1293 } else {
1269 context()->HandleExpression(expr->then_expression()); 1294 context()->HandleExpression(expr->then_expression());
1270 __ jmp(&done); 1295 __ jmp(&done);
1271 } 1296 }
1272 1297
1298 PrepareForBailoutForId(expr->ElseId(), NO_REGISTERS);
1273 __ bind(&false_case); 1299 __ bind(&false_case);
1274 if (context()->IsTest()) ForwardBailoutToChild(expr); 1300 if (context()->IsTest()) ForwardBailoutToChild(expr);
1275 SetExpressionPosition(expr->else_expression(), 1301 SetExpressionPosition(expr->else_expression(),
1276 expr->else_expression_position()); 1302 expr->else_expression_position());
1277 context()->HandleExpression(expr->else_expression()); 1303 context()->HandleExpression(expr->else_expression());
1278 // If control flow falls through Visit, merge it with true case here. 1304 // If control flow falls through Visit, merge it with true case here.
1279 if (!context()->IsTest()) { 1305 if (!context()->IsTest()) {
1280 __ bind(&done); 1306 __ bind(&done);
1281 } 1307 }
1282 } 1308 }
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1348 __ Drop(stack_depth); 1374 __ Drop(stack_depth);
1349 __ PopTryHandler(); 1375 __ PopTryHandler();
1350 return 0; 1376 return 0;
1351 } 1377 }
1352 1378
1353 1379
1354 #undef __ 1380 #undef __
1355 1381
1356 1382
1357 } } // namespace v8::internal 1383 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/full-codegen.h ('k') | src/heap.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698