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

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

Issue 7618040: Version 3.5.5. (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: Created 9 years, 4 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/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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 17 matching lines...) Expand all
28 #include "v8.h" 28 #include "v8.h"
29 29
30 #include "codegen.h" 30 #include "codegen.h"
31 #include "compiler.h" 31 #include "compiler.h"
32 #include "debug.h" 32 #include "debug.h"
33 #include "full-codegen.h" 33 #include "full-codegen.h"
34 #include "liveedit.h" 34 #include "liveedit.h"
35 #include "macro-assembler.h" 35 #include "macro-assembler.h"
36 #include "prettyprinter.h" 36 #include "prettyprinter.h"
37 #include "scopes.h" 37 #include "scopes.h"
38 #include "scopeinfo.h"
38 #include "stub-cache.h" 39 #include "stub-cache.h"
39 40
40 namespace v8 { 41 namespace v8 {
41 namespace internal { 42 namespace internal {
42 43
43 void BreakableStatementChecker::Check(Statement* stmt) { 44 void BreakableStatementChecker::Check(Statement* stmt) {
44 Visit(stmt); 45 Visit(stmt);
45 } 46 }
46 47
47 48
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 void BreakableStatementChecker::VisitBreakStatement(BreakStatement* stmt) { 84 void BreakableStatementChecker::VisitBreakStatement(BreakStatement* stmt) {
84 } 85 }
85 86
86 87
87 void BreakableStatementChecker::VisitReturnStatement(ReturnStatement* stmt) { 88 void BreakableStatementChecker::VisitReturnStatement(ReturnStatement* stmt) {
88 // Return is breakable if the expression is. 89 // Return is breakable if the expression is.
89 Visit(stmt->expression()); 90 Visit(stmt->expression());
90 } 91 }
91 92
92 93
93 void BreakableStatementChecker::VisitEnterWithContextStatement( 94 void BreakableStatementChecker::VisitWithStatement(WithStatement* stmt) {
94 EnterWithContextStatement* stmt) {
95 Visit(stmt->expression()); 95 Visit(stmt->expression());
96 } 96 }
97 97
98 98
99 void BreakableStatementChecker::VisitExitContextStatement( 99 void BreakableStatementChecker::VisitExitContextStatement(
100 ExitContextStatement* stmt) { 100 ExitContextStatement* stmt) {
101 } 101 }
102 102
103 103
104 void BreakableStatementChecker::VisitSwitchStatement(SwitchStatement* stmt) { 104 void BreakableStatementChecker::VisitSwitchStatement(SwitchStatement* stmt) {
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 #endif 310 #endif
311 return !code.is_null(); 311 return !code.is_null();
312 } 312 }
313 313
314 314
315 unsigned FullCodeGenerator::EmitStackCheckTable() { 315 unsigned FullCodeGenerator::EmitStackCheckTable() {
316 // The stack check table consists of a length (in number of entries) 316 // The stack check table consists of a length (in number of entries)
317 // field, and then a sequence of entries. Each entry is a pair of AST id 317 // field, and then a sequence of entries. Each entry is a pair of AST id
318 // and code-relative pc offset. 318 // and code-relative pc offset.
319 masm()->Align(kIntSize); 319 masm()->Align(kIntSize);
320 masm()->RecordComment("[ Stack check table");
321 unsigned offset = masm()->pc_offset(); 320 unsigned offset = masm()->pc_offset();
322 unsigned length = stack_checks_.length(); 321 unsigned length = stack_checks_.length();
323 __ dd(length); 322 __ dd(length);
324 for (unsigned i = 0; i < length; ++i) { 323 for (unsigned i = 0; i < length; ++i) {
325 __ dd(stack_checks_[i].id); 324 __ dd(stack_checks_[i].id);
326 __ dd(stack_checks_[i].pc_and_state); 325 __ dd(stack_checks_[i].pc_and_state);
327 } 326 }
328 masm()->RecordComment("]");
329 return offset; 327 return offset;
330 } 328 }
331 329
332 330
333 void FullCodeGenerator::PopulateDeoptimizationData(Handle<Code> code) { 331 void FullCodeGenerator::PopulateDeoptimizationData(Handle<Code> code) {
334 // Fill in the deoptimization information. 332 // Fill in the deoptimization information.
335 ASSERT(info_->HasDeoptimizationSupport() || bailout_entries_.is_empty()); 333 ASSERT(info_->HasDeoptimizationSupport() || bailout_entries_.is_empty());
336 if (!info_->HasDeoptimizationSupport()) return; 334 if (!info_->HasDeoptimizationSupport()) return;
337 int length = bailout_entries_.length(); 335 int length = bailout_entries_.length();
338 Handle<DeoptimizationOutputData> data = 336 Handle<DeoptimizationOutputData> data =
(...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after
840 ASSERT(forward_bailout_pending_ == NULL); 838 ASSERT(forward_bailout_pending_ == NULL);
841 } 839 }
842 } 840 }
843 841
844 842
845 void FullCodeGenerator::VisitBlock(Block* stmt) { 843 void FullCodeGenerator::VisitBlock(Block* stmt) {
846 Comment cmnt(masm_, "[ Block"); 844 Comment cmnt(masm_, "[ Block");
847 Breakable nested_statement(this, stmt); 845 Breakable nested_statement(this, stmt);
848 SetStatementPosition(stmt); 846 SetStatementPosition(stmt);
849 847
848 Scope* saved_scope = scope();
849 if (stmt->block_scope() != NULL) {
850 { Comment cmnt(masm_, "[ Extend block context");
851 scope_ = stmt->block_scope();
852 __ Push(scope_->GetSerializedScopeInfo());
853 PushFunctionArgumentForContextAllocation();
854 __ CallRuntime(Runtime::kPushBlockContext, 2);
855 StoreToFrameField(StandardFrameConstants::kContextOffset,
856 context_register());
857 }
858 { Comment cmnt(masm_, "[ Declarations");
859 VisitDeclarations(scope_->declarations());
860 }
861 }
850 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); 862 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS);
851 VisitStatements(stmt->statements()); 863 VisitStatements(stmt->statements());
864 scope_ = saved_scope;
852 __ bind(nested_statement.break_target()); 865 __ bind(nested_statement.break_target());
853 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 866 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
854 } 867 }
855 868
856 869
857 void FullCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) { 870 void FullCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) {
858 Comment cmnt(masm_, "[ ExpressionStatement"); 871 Comment cmnt(masm_, "[ ExpressionStatement");
859 SetStatementPosition(stmt); 872 SetStatementPosition(stmt);
860 VisitForEffect(stmt->expression()); 873 VisitForEffect(stmt->expression());
861 } 874 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
893 __ bind(&done); 906 __ bind(&done);
894 PrepareForBailoutForId(stmt->IfId(), NO_REGISTERS); 907 PrepareForBailoutForId(stmt->IfId(), NO_REGISTERS);
895 } 908 }
896 909
897 910
898 void FullCodeGenerator::VisitContinueStatement(ContinueStatement* stmt) { 911 void FullCodeGenerator::VisitContinueStatement(ContinueStatement* stmt) {
899 Comment cmnt(masm_, "[ ContinueStatement"); 912 Comment cmnt(masm_, "[ ContinueStatement");
900 SetStatementPosition(stmt); 913 SetStatementPosition(stmt);
901 NestedStatement* current = nesting_stack_; 914 NestedStatement* current = nesting_stack_;
902 int stack_depth = 0; 915 int stack_depth = 0;
916 int context_length = 0;
903 // When continuing, we clobber the unpredictable value in the accumulator 917 // When continuing, we clobber the unpredictable value in the accumulator
904 // with one that's safe for GC. If we hit an exit from the try block of 918 // with one that's safe for GC. If we hit an exit from the try block of
905 // try...finally on our way out, we will unconditionally preserve the 919 // try...finally on our way out, we will unconditionally preserve the
906 // accumulator on the stack. 920 // accumulator on the stack.
907 ClearAccumulator(); 921 ClearAccumulator();
908 while (!current->IsContinueTarget(stmt->target())) { 922 while (!current->IsContinueTarget(stmt->target())) {
909 stack_depth = current->Exit(stack_depth); 923 current = current->Exit(&stack_depth, &context_length);
910 current = current->outer();
911 } 924 }
912 __ Drop(stack_depth); 925 __ Drop(stack_depth);
926 if (context_length > 0) {
927 while (context_length > 0) {
928 LoadContextField(context_register(), Context::PREVIOUS_INDEX);
929 --context_length;
930 }
931 StoreToFrameField(StandardFrameConstants::kContextOffset,
932 context_register());
933 }
913 934
914 Iteration* loop = current->AsIteration(); 935 Iteration* loop = current->AsIteration();
915 __ jmp(loop->continue_target()); 936 __ jmp(loop->continue_target());
916 } 937 }
917 938
918 939
919 void FullCodeGenerator::VisitBreakStatement(BreakStatement* stmt) { 940 void FullCodeGenerator::VisitBreakStatement(BreakStatement* stmt) {
920 Comment cmnt(masm_, "[ BreakStatement"); 941 Comment cmnt(masm_, "[ BreakStatement");
921 SetStatementPosition(stmt); 942 SetStatementPosition(stmt);
922 NestedStatement* current = nesting_stack_; 943 NestedStatement* current = nesting_stack_;
923 int stack_depth = 0; 944 int stack_depth = 0;
945 int context_length = 0;
924 // When breaking, we clobber the unpredictable value in the accumulator 946 // When breaking, we clobber the unpredictable value in the accumulator
925 // with one that's safe for GC. If we hit an exit from the try block of 947 // with one that's safe for GC. If we hit an exit from the try block of
926 // try...finally on our way out, we will unconditionally preserve the 948 // try...finally on our way out, we will unconditionally preserve the
927 // accumulator on the stack. 949 // accumulator on the stack.
928 ClearAccumulator(); 950 ClearAccumulator();
929 while (!current->IsBreakTarget(stmt->target())) { 951 while (!current->IsBreakTarget(stmt->target())) {
930 stack_depth = current->Exit(stack_depth); 952 current = current->Exit(&stack_depth, &context_length);
931 current = current->outer();
932 } 953 }
933 __ Drop(stack_depth); 954 __ Drop(stack_depth);
955 if (context_length > 0) {
956 while (context_length > 0) {
957 LoadContextField(context_register(), Context::PREVIOUS_INDEX);
958 --context_length;
959 }
960 StoreToFrameField(StandardFrameConstants::kContextOffset,
961 context_register());
962 }
934 963
935 Breakable* target = current->AsBreakable(); 964 Breakable* target = current->AsBreakable();
936 __ jmp(target->break_target()); 965 __ jmp(target->break_target());
937 } 966 }
938 967
939 968
940 void FullCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { 969 void FullCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
941 Comment cmnt(masm_, "[ ReturnStatement"); 970 Comment cmnt(masm_, "[ ReturnStatement");
942 SetStatementPosition(stmt); 971 SetStatementPosition(stmt);
943 Expression* expr = stmt->expression(); 972 Expression* expr = stmt->expression();
944 VisitForAccumulatorValue(expr); 973 VisitForAccumulatorValue(expr);
945 974
946 // Exit all nested statements. 975 // Exit all nested statements.
947 NestedStatement* current = nesting_stack_; 976 NestedStatement* current = nesting_stack_;
948 int stack_depth = 0; 977 int stack_depth = 0;
978 int context_length = 0;
949 while (current != NULL) { 979 while (current != NULL) {
950 stack_depth = current->Exit(stack_depth); 980 current = current->Exit(&stack_depth, &context_length);
951 current = current->outer();
952 } 981 }
953 __ Drop(stack_depth); 982 __ Drop(stack_depth);
954 983
955 EmitReturnSequence(); 984 EmitReturnSequence();
956 } 985 }
957 986
958 987
959 void FullCodeGenerator::VisitEnterWithContextStatement( 988 void FullCodeGenerator::VisitWithStatement(WithStatement* stmt) {
960 EnterWithContextStatement* stmt) { 989 Comment cmnt(masm_, "[ WithStatement");
961 Comment cmnt(masm_, "[ EnterWithContextStatement");
962 SetStatementPosition(stmt); 990 SetStatementPosition(stmt);
963 991
964 VisitForStackValue(stmt->expression()); 992 VisitForStackValue(stmt->expression());
965 PushFunctionArgumentForContextAllocation(); 993 PushFunctionArgumentForContextAllocation();
966 __ CallRuntime(Runtime::kPushWithContext, 2); 994 __ CallRuntime(Runtime::kPushWithContext, 2);
967 decrement_stack_height(); 995 decrement_stack_height();
968 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); 996 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register());
997
998 { WithOrCatch body(this);
999 Visit(stmt->statement());
1000 }
1001
1002 // Pop context.
1003 LoadContextField(context_register(), Context::PREVIOUS_INDEX);
1004 // Update local stack frame context field.
1005 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register());
969 } 1006 }
970 1007
971 1008
972 void FullCodeGenerator::VisitExitContextStatement(ExitContextStatement* stmt) { 1009 void FullCodeGenerator::VisitExitContextStatement(ExitContextStatement* stmt) {
973 Comment cmnt(masm_, "[ ExitContextStatement"); 1010 Comment cmnt(masm_, "[ ExitContextStatement");
974 SetStatementPosition(stmt); 1011 SetStatementPosition(stmt);
975 1012
976 // Pop context. 1013 // Pop context.
977 LoadContextField(context_register(), Context::PREVIOUS_INDEX); 1014 LoadContextField(context_register(), Context::PREVIOUS_INDEX);
978 // Update local stack frame context field. 1015 // Update local stack frame context field.
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
1117 __ push(result_register()); 1154 __ push(result_register());
1118 PushFunctionArgumentForContextAllocation(); 1155 PushFunctionArgumentForContextAllocation();
1119 __ CallRuntime(Runtime::kPushCatchContext, 3); 1156 __ CallRuntime(Runtime::kPushCatchContext, 3);
1120 StoreToFrameField(StandardFrameConstants::kContextOffset, 1157 StoreToFrameField(StandardFrameConstants::kContextOffset,
1121 context_register()); 1158 context_register());
1122 } 1159 }
1123 1160
1124 Scope* saved_scope = scope(); 1161 Scope* saved_scope = scope();
1125 scope_ = stmt->scope(); 1162 scope_ = stmt->scope();
1126 ASSERT(scope_->declarations()->is_empty()); 1163 ASSERT(scope_->declarations()->is_empty());
1127 Visit(stmt->catch_block()); 1164 { WithOrCatch body(this);
1165 Visit(stmt->catch_block());
1166 }
1128 scope_ = saved_scope; 1167 scope_ = saved_scope;
1129 __ jmp(&done); 1168 __ jmp(&done);
1130 1169
1131 // Try block code. Sets up the exception handler chain. 1170 // Try block code. Sets up the exception handler chain.
1132 __ bind(&try_handler_setup); 1171 __ bind(&try_handler_setup);
1133 { 1172 {
1134 TryCatch try_block(this, &catch_entry); 1173 TryCatch try_block(this, &catch_entry);
1135 __ PushTryHandler(IN_JAVASCRIPT, TRY_CATCH_HANDLER); 1174 __ PushTryHandler(IN_JAVASCRIPT, TRY_CATCH_HANDLER);
1136 increment_stack_height(StackHandlerConstants::kSize / kPointerSize); 1175 increment_stack_height(StackHandlerConstants::kSize / kPointerSize);
1137 Visit(stmt->try_block()); 1176 Visit(stmt->try_block());
(...skipping 25 matching lines...) Expand all
1163 // 1202 //
1164 // The finally block must assume a return address on top of the stack 1203 // The finally block must assume a return address on top of the stack
1165 // (or in the link register on ARM chips) and a value (return value or 1204 // (or in the link register on ARM chips) and a value (return value or
1166 // exception) in the result register (rax/eax/r0), both of which must 1205 // exception) in the result register (rax/eax/r0), both of which must
1167 // be preserved. The return address isn't GC-safe, so it should be 1206 // be preserved. The return address isn't GC-safe, so it should be
1168 // cooked before GC. 1207 // cooked before GC.
1169 Label finally_entry; 1208 Label finally_entry;
1170 Label try_handler_setup; 1209 Label try_handler_setup;
1171 const int original_stack_height = stack_height(); 1210 const int original_stack_height = stack_height();
1172 const int finally_block_stack_height = original_stack_height + 2; 1211 const int finally_block_stack_height = original_stack_height + 2;
1173 const int try_block_stack_height = original_stack_height + 4; 1212 const int try_block_stack_height = original_stack_height + 5;
1174 STATIC_ASSERT(StackHandlerConstants::kSize / kPointerSize == 4); 1213 STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize);
1175 1214
1176 // Setup the try-handler chain. Use a call to 1215 // Setup the try-handler chain. Use a call to
1177 // Jump to try-handler setup and try-block code. Use call to put try-handler 1216 // Jump to try-handler setup and try-block code. Use call to put try-handler
1178 // address on stack. 1217 // address on stack.
1179 __ Call(&try_handler_setup); 1218 __ Call(&try_handler_setup);
1180 // Try handler code. Return address of call is pushed on handler stack. 1219 // Try handler code. Return address of call is pushed on handler stack.
1181 { 1220 {
1182 // This code is only executed during stack-handler traversal when an 1221 // This code is only executed during stack-handler traversal when an
1183 // exception is thrown. The execption is in the result register, which 1222 // exception is thrown. The execption is in the result register, which
1184 // is retained by the finally block. 1223 // is retained by the finally block.
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
1293 Comment cmnt(masm_, "[ Throw"); 1332 Comment cmnt(masm_, "[ Throw");
1294 // Throw has no effect on the stack height or the current expression context. 1333 // Throw has no effect on the stack height or the current expression context.
1295 // Usually the expression context is null, because throw is a statement. 1334 // Usually the expression context is null, because throw is a statement.
1296 VisitForStackValue(expr->exception()); 1335 VisitForStackValue(expr->exception());
1297 __ CallRuntime(Runtime::kThrow, 1); 1336 __ CallRuntime(Runtime::kThrow, 1);
1298 decrement_stack_height(); 1337 decrement_stack_height();
1299 // Never returns here. 1338 // Never returns here.
1300 } 1339 }
1301 1340
1302 1341
1303 int FullCodeGenerator::TryFinally::Exit(int stack_depth) { 1342 FullCodeGenerator::NestedStatement* FullCodeGenerator::TryFinally::Exit(
1343 int* stack_depth,
1344 int* context_length) {
1304 // The macros used here must preserve the result register. 1345 // The macros used here must preserve the result register.
1305 __ Drop(stack_depth); 1346 __ Drop(*stack_depth);
1306 __ PopTryHandler(); 1347 __ PopTryHandler();
1348 *stack_depth = 0;
1349
1350 Register context = FullCodeGenerator::context_register();
1351 while (*context_length > 0) {
1352 codegen_->LoadContextField(context, Context::PREVIOUS_INDEX);
1353 --(*context_length);
1354 }
1355
1307 __ Call(finally_entry_); 1356 __ Call(finally_entry_);
1308 return 0; 1357 return previous_;
1309 } 1358 }
1310 1359
1311 1360
1312 int FullCodeGenerator::TryCatch::Exit(int stack_depth) { 1361 FullCodeGenerator::NestedStatement* FullCodeGenerator::TryCatch::Exit(
1362 int* stack_depth,
1363 int* context_length) {
1313 // The macros used here must preserve the result register. 1364 // The macros used here must preserve the result register.
1314 __ Drop(stack_depth); 1365 __ Drop(*stack_depth);
1315 __ PopTryHandler(); 1366 __ PopTryHandler();
1316 return 0; 1367 *stack_depth = 0;
1368 return previous_;
1317 } 1369 }
1318 1370
1319 1371
1320 bool FullCodeGenerator::TryLiteralCompare(CompareOperation* compare, 1372 bool FullCodeGenerator::TryLiteralCompare(CompareOperation* compare,
1321 Label* if_true, 1373 Label* if_true,
1322 Label* if_false, 1374 Label* if_false,
1323 Label* fall_through) { 1375 Label* fall_through) {
1324 Expression *expr; 1376 Expression *expr;
1325 Handle<String> check; 1377 Handle<String> check;
1326 if (compare->IsLiteralCompareTypeof(&expr, &check)) { 1378 if (compare->IsLiteralCompareTypeof(&expr, &check)) {
1327 EmitLiteralCompareTypeof(expr, check, if_true, if_false, fall_through); 1379 EmitLiteralCompareTypeof(expr, check, if_true, if_false, fall_through);
1328 return true; 1380 return true;
1329 } 1381 }
1330 1382
1331 if (compare->IsLiteralCompareUndefined(&expr)) { 1383 if (compare->IsLiteralCompareUndefined(&expr)) {
1332 EmitLiteralCompareUndefined(expr, if_true, if_false, fall_through); 1384 EmitLiteralCompareUndefined(expr, if_true, if_false, fall_through);
1333 return true; 1385 return true;
1334 } 1386 }
1335 1387
1336 return false; 1388 return false;
1337 } 1389 }
1338 1390
1339 1391
1340 #undef __ 1392 #undef __
1341 1393
1342 1394
1343 } } // namespace v8::internal 1395 } } // 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