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

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

Issue 7778013: NewGC: Merge bleeding edge up to 9009. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 years, 3 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/handles.cc » ('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());
852 __ bind(nested_statement.break_target()); 864 scope_ = saved_scope;
865 __ bind(nested_statement.break_label());
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 }
862 875
(...skipping 30 matching lines...) Expand all
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 __ jmp(current->AsIteration()->continue_label());
915 __ jmp(loop->continue_target());
916 } 936 }
917 937
918 938
919 void FullCodeGenerator::VisitBreakStatement(BreakStatement* stmt) { 939 void FullCodeGenerator::VisitBreakStatement(BreakStatement* stmt) {
920 Comment cmnt(masm_, "[ BreakStatement"); 940 Comment cmnt(masm_, "[ BreakStatement");
921 SetStatementPosition(stmt); 941 SetStatementPosition(stmt);
922 NestedStatement* current = nesting_stack_; 942 NestedStatement* current = nesting_stack_;
923 int stack_depth = 0; 943 int stack_depth = 0;
944 int context_length = 0;
924 // When breaking, we clobber the unpredictable value in the accumulator 945 // 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 946 // 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 947 // try...finally on our way out, we will unconditionally preserve the
927 // accumulator on the stack. 948 // accumulator on the stack.
928 ClearAccumulator(); 949 ClearAccumulator();
929 while (!current->IsBreakTarget(stmt->target())) { 950 while (!current->IsBreakTarget(stmt->target())) {
930 stack_depth = current->Exit(stack_depth); 951 current = current->Exit(&stack_depth, &context_length);
931 current = current->outer();
932 } 952 }
933 __ Drop(stack_depth); 953 __ Drop(stack_depth);
954 if (context_length > 0) {
955 while (context_length > 0) {
956 LoadContextField(context_register(), Context::PREVIOUS_INDEX);
957 --context_length;
958 }
959 StoreToFrameField(StandardFrameConstants::kContextOffset,
960 context_register());
961 }
934 962
935 Breakable* target = current->AsBreakable(); 963 __ jmp(current->AsBreakable()->break_label());
936 __ jmp(target->break_target());
937 } 964 }
938 965
939 966
940 void FullCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { 967 void FullCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
941 Comment cmnt(masm_, "[ ReturnStatement"); 968 Comment cmnt(masm_, "[ ReturnStatement");
942 SetStatementPosition(stmt); 969 SetStatementPosition(stmt);
943 Expression* expr = stmt->expression(); 970 Expression* expr = stmt->expression();
944 VisitForAccumulatorValue(expr); 971 VisitForAccumulatorValue(expr);
945 972
946 // Exit all nested statements. 973 // Exit all nested statements.
947 NestedStatement* current = nesting_stack_; 974 NestedStatement* current = nesting_stack_;
948 int stack_depth = 0; 975 int stack_depth = 0;
976 int context_length = 0;
949 while (current != NULL) { 977 while (current != NULL) {
950 stack_depth = current->Exit(stack_depth); 978 current = current->Exit(&stack_depth, &context_length);
951 current = current->outer();
952 } 979 }
953 __ Drop(stack_depth); 980 __ Drop(stack_depth);
954 981
955 EmitReturnSequence(); 982 EmitReturnSequence();
956 } 983 }
957 984
958 985
959 void FullCodeGenerator::VisitEnterWithContextStatement( 986 void FullCodeGenerator::VisitWithStatement(WithStatement* stmt) {
960 EnterWithContextStatement* stmt) { 987 Comment cmnt(masm_, "[ WithStatement");
961 Comment cmnt(masm_, "[ EnterWithContextStatement");
962 SetStatementPosition(stmt); 988 SetStatementPosition(stmt);
963 989
964 VisitForStackValue(stmt->expression()); 990 VisitForStackValue(stmt->expression());
965 PushFunctionArgumentForContextAllocation(); 991 PushFunctionArgumentForContextAllocation();
966 __ CallRuntime(Runtime::kPushWithContext, 2); 992 __ CallRuntime(Runtime::kPushWithContext, 2);
967 decrement_stack_height(); 993 decrement_stack_height();
968 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); 994 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register());
995
996 { WithOrCatch body(this);
997 Visit(stmt->statement());
998 }
999
1000 // Pop context.
1001 LoadContextField(context_register(), Context::PREVIOUS_INDEX);
1002 // Update local stack frame context field.
1003 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register());
969 } 1004 }
970 1005
971 1006
972 void FullCodeGenerator::VisitExitContextStatement(ExitContextStatement* stmt) { 1007 void FullCodeGenerator::VisitExitContextStatement(ExitContextStatement* stmt) {
973 Comment cmnt(masm_, "[ ExitContextStatement"); 1008 Comment cmnt(masm_, "[ ExitContextStatement");
974 SetStatementPosition(stmt); 1009 SetStatementPosition(stmt);
975 1010
976 // Pop context. 1011 // Pop context.
977 LoadContextField(context_register(), Context::PREVIOUS_INDEX); 1012 LoadContextField(context_register(), Context::PREVIOUS_INDEX);
978 // Update local stack frame context field. 1013 // Update local stack frame context field.
979 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); 1014 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register());
980 } 1015 }
981 1016
982 1017
983 void FullCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) { 1018 void FullCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) {
984 Comment cmnt(masm_, "[ DoWhileStatement"); 1019 Comment cmnt(masm_, "[ DoWhileStatement");
985 SetStatementPosition(stmt); 1020 SetStatementPosition(stmt);
986 Label body, stack_check; 1021 Label body, stack_check;
987 1022
988 Iteration loop_statement(this, stmt); 1023 Iteration loop_statement(this, stmt);
989 increment_loop_depth(); 1024 increment_loop_depth();
990 1025
991 __ bind(&body); 1026 __ bind(&body);
992 Visit(stmt->body()); 1027 Visit(stmt->body());
993 1028
994 // Record the position of the do while condition and make sure it is 1029 // Record the position of the do while condition and make sure it is
995 // possible to break on the condition. 1030 // possible to break on the condition.
996 __ bind(loop_statement.continue_target()); 1031 __ bind(loop_statement.continue_label());
997 PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS); 1032 PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS);
998 SetExpressionPosition(stmt->cond(), stmt->condition_position()); 1033 SetExpressionPosition(stmt->cond(), stmt->condition_position());
999 VisitForControl(stmt->cond(), 1034 VisitForControl(stmt->cond(),
1000 &stack_check, 1035 &stack_check,
1001 loop_statement.break_target(), 1036 loop_statement.break_label(),
1002 &stack_check); 1037 &stack_check);
1003 1038
1004 // Check stack before looping. 1039 // Check stack before looping.
1005 PrepareForBailoutForId(stmt->BackEdgeId(), NO_REGISTERS); 1040 PrepareForBailoutForId(stmt->BackEdgeId(), NO_REGISTERS);
1006 __ bind(&stack_check); 1041 __ bind(&stack_check);
1007 EmitStackCheck(stmt); 1042 EmitStackCheck(stmt);
1008 __ jmp(&body); 1043 __ jmp(&body);
1009 1044
1010 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 1045 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1011 __ bind(loop_statement.break_target()); 1046 __ bind(loop_statement.break_label());
1012 decrement_loop_depth(); 1047 decrement_loop_depth();
1013 } 1048 }
1014 1049
1015 1050
1016 void FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) { 1051 void FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
1017 Comment cmnt(masm_, "[ WhileStatement"); 1052 Comment cmnt(masm_, "[ WhileStatement");
1018 Label test, body; 1053 Label test, body;
1019 1054
1020 Iteration loop_statement(this, stmt); 1055 Iteration loop_statement(this, stmt);
1021 increment_loop_depth(); 1056 increment_loop_depth();
1022 1057
1023 // Emit the test at the bottom of the loop. 1058 // Emit the test at the bottom of the loop.
1024 __ jmp(&test); 1059 __ jmp(&test);
1025 1060
1026 PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); 1061 PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS);
1027 __ bind(&body); 1062 __ bind(&body);
1028 Visit(stmt->body()); 1063 Visit(stmt->body());
1029 1064
1030 // Emit the statement position here as this is where the while 1065 // Emit the statement position here as this is where the while
1031 // statement code starts. 1066 // statement code starts.
1032 __ bind(loop_statement.continue_target()); 1067 __ bind(loop_statement.continue_label());
1033 SetStatementPosition(stmt); 1068 SetStatementPosition(stmt);
1034 1069
1035 // Check stack before looping. 1070 // Check stack before looping.
1036 EmitStackCheck(stmt); 1071 EmitStackCheck(stmt);
1037 1072
1038 __ bind(&test); 1073 __ bind(&test);
1039 VisitForControl(stmt->cond(), 1074 VisitForControl(stmt->cond(),
1040 &body, 1075 &body,
1041 loop_statement.break_target(), 1076 loop_statement.break_label(),
1042 loop_statement.break_target()); 1077 loop_statement.break_label());
1043 1078
1044 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 1079 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1045 __ bind(loop_statement.break_target()); 1080 __ bind(loop_statement.break_label());
1046 decrement_loop_depth(); 1081 decrement_loop_depth();
1047 } 1082 }
1048 1083
1049 1084
1050 void FullCodeGenerator::VisitForStatement(ForStatement* stmt) { 1085 void FullCodeGenerator::VisitForStatement(ForStatement* stmt) {
1051 Comment cmnt(masm_, "[ ForStatement"); 1086 Comment cmnt(masm_, "[ ForStatement");
1052 Label test, body; 1087 Label test, body;
1053 1088
1054 Iteration loop_statement(this, stmt); 1089 Iteration loop_statement(this, stmt);
1055 if (stmt->init() != NULL) { 1090 if (stmt->init() != NULL) {
1056 Visit(stmt->init()); 1091 Visit(stmt->init());
1057 } 1092 }
1058 1093
1059 increment_loop_depth(); 1094 increment_loop_depth();
1060 // Emit the test at the bottom of the loop (even if empty). 1095 // Emit the test at the bottom of the loop (even if empty).
1061 __ jmp(&test); 1096 __ jmp(&test);
1062 1097
1063 PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); 1098 PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS);
1064 __ bind(&body); 1099 __ bind(&body);
1065 Visit(stmt->body()); 1100 Visit(stmt->body());
1066 1101
1067 PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS); 1102 PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS);
1068 __ bind(loop_statement.continue_target()); 1103 __ bind(loop_statement.continue_label());
1069 SetStatementPosition(stmt); 1104 SetStatementPosition(stmt);
1070 if (stmt->next() != NULL) { 1105 if (stmt->next() != NULL) {
1071 Visit(stmt->next()); 1106 Visit(stmt->next());
1072 } 1107 }
1073 1108
1074 // Emit the statement position here as this is where the for 1109 // Emit the statement position here as this is where the for
1075 // statement code starts. 1110 // statement code starts.
1076 SetStatementPosition(stmt); 1111 SetStatementPosition(stmt);
1077 1112
1078 // Check stack before looping. 1113 // Check stack before looping.
1079 EmitStackCheck(stmt); 1114 EmitStackCheck(stmt);
1080 1115
1081 __ bind(&test); 1116 __ bind(&test);
1082 if (stmt->cond() != NULL) { 1117 if (stmt->cond() != NULL) {
1083 VisitForControl(stmt->cond(), 1118 VisitForControl(stmt->cond(),
1084 &body, 1119 &body,
1085 loop_statement.break_target(), 1120 loop_statement.break_label(),
1086 loop_statement.break_target()); 1121 loop_statement.break_label());
1087 } else { 1122 } else {
1088 __ jmp(&body); 1123 __ jmp(&body);
1089 } 1124 }
1090 1125
1091 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 1126 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1092 __ bind(loop_statement.break_target()); 1127 __ bind(loop_statement.break_label());
1093 decrement_loop_depth(); 1128 decrement_loop_depth();
1094 } 1129 }
1095 1130
1096 1131
1097 void FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { 1132 void FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
1098 Comment cmnt(masm_, "[ TryCatchStatement"); 1133 Comment cmnt(masm_, "[ TryCatchStatement");
1099 SetStatementPosition(stmt); 1134 SetStatementPosition(stmt);
1100 // The try block adds a handler to the exception handler chain 1135 // The try block adds a handler to the exception handler chain
1101 // before entering, and removes it again when exiting normally. 1136 // before entering, and removes it again when exiting normally.
1102 // If an exception is thrown during execution of the try block, 1137 // If an exception is thrown during execution of the try block,
1103 // control is passed to the handler, which also consumes the handler. 1138 // control is passed to the handler, which also consumes the handler.
1104 // At this point, the exception is in a register, and store it in 1139 // At this point, the exception is in a register, and store it in
1105 // the temporary local variable (prints as ".catch-var") before 1140 // the temporary local variable (prints as ".catch-var") before
1106 // executing the catch block. The catch block has been rewritten 1141 // executing the catch block. The catch block has been rewritten
1107 // to introduce a new scope to bind the catch variable and to remove 1142 // to introduce a new scope to bind the catch variable and to remove
1108 // that scope again afterwards. 1143 // that scope again afterwards.
1109 1144
1110 Label try_handler_setup, catch_entry, done; 1145 Label try_handler_setup, done;
1111 __ Call(&try_handler_setup); 1146 __ Call(&try_handler_setup);
1112 // Try handler code, exception in result register. 1147 // Try handler code, exception in result register.
1113 1148
1114 // Extend the context before executing the catch block. 1149 // Extend the context before executing the catch block.
1115 { Comment cmnt(masm_, "[ Extend catch context"); 1150 { Comment cmnt(masm_, "[ Extend catch context");
1116 __ Push(stmt->variable()->name()); 1151 __ Push(stmt->variable()->name());
1117 __ push(result_register()); 1152 __ push(result_register());
1118 PushFunctionArgumentForContextAllocation(); 1153 PushFunctionArgumentForContextAllocation();
1119 __ CallRuntime(Runtime::kPushCatchContext, 3); 1154 __ CallRuntime(Runtime::kPushCatchContext, 3);
1120 StoreToFrameField(StandardFrameConstants::kContextOffset, 1155 StoreToFrameField(StandardFrameConstants::kContextOffset,
1121 context_register()); 1156 context_register());
1122 } 1157 }
1123 1158
1124 Scope* saved_scope = scope(); 1159 Scope* saved_scope = scope();
1125 scope_ = stmt->scope(); 1160 scope_ = stmt->scope();
1126 ASSERT(scope_->declarations()->is_empty()); 1161 ASSERT(scope_->declarations()->is_empty());
1127 Visit(stmt->catch_block()); 1162 { WithOrCatch body(this);
1163 Visit(stmt->catch_block());
1164 }
1128 scope_ = saved_scope; 1165 scope_ = saved_scope;
1129 __ jmp(&done); 1166 __ jmp(&done);
1130 1167
1131 // Try block code. Sets up the exception handler chain. 1168 // Try block code. Sets up the exception handler chain.
1132 __ bind(&try_handler_setup); 1169 __ bind(&try_handler_setup);
1133 { 1170 {
1134 TryCatch try_block(this, &catch_entry); 1171 const int delta = StackHandlerConstants::kSize / kPointerSize;
1172 TryCatch try_block(this);
1135 __ PushTryHandler(IN_JAVASCRIPT, TRY_CATCH_HANDLER); 1173 __ PushTryHandler(IN_JAVASCRIPT, TRY_CATCH_HANDLER);
1136 increment_stack_height(StackHandlerConstants::kSize / kPointerSize); 1174 increment_stack_height(delta);
1137 Visit(stmt->try_block()); 1175 Visit(stmt->try_block());
1138 __ PopTryHandler(); 1176 __ PopTryHandler();
1139 decrement_stack_height(StackHandlerConstants::kSize / kPointerSize); 1177 decrement_stack_height(delta);
1140 } 1178 }
1141 __ bind(&done); 1179 __ bind(&done);
1142 } 1180 }
1143 1181
1144 1182
1145 void FullCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) { 1183 void FullCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
1146 Comment cmnt(masm_, "[ TryFinallyStatement"); 1184 Comment cmnt(masm_, "[ TryFinallyStatement");
1147 SetStatementPosition(stmt); 1185 SetStatementPosition(stmt);
1148 // Try finally is compiled by setting up a try-handler on the stack while 1186 // Try finally is compiled by setting up a try-handler on the stack while
1149 // executing the try body, and removing it again afterwards. 1187 // executing the try body, and removing it again afterwards.
(...skipping 12 matching lines...) Expand all
1162 // rethrowing the exception. 1200 // rethrowing the exception.
1163 // 1201 //
1164 // The finally block must assume a return address on top of the stack 1202 // 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 1203 // (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 1204 // 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 1205 // be preserved. The return address isn't GC-safe, so it should be
1168 // cooked before GC. 1206 // cooked before GC.
1169 Label finally_entry; 1207 Label finally_entry;
1170 Label try_handler_setup; 1208 Label try_handler_setup;
1171 const int original_stack_height = stack_height(); 1209 const int original_stack_height = stack_height();
1172 const int finally_block_stack_height = original_stack_height + 2;
1173 const int try_block_stack_height = original_stack_height + 4;
1174 STATIC_ASSERT(StackHandlerConstants::kSize / kPointerSize == 4);
1175 1210
1176 // Setup the try-handler chain. Use a call to 1211 // 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 1212 // Jump to try-handler setup and try-block code. Use call to put try-handler
1178 // address on stack. 1213 // address on stack.
1179 __ Call(&try_handler_setup); 1214 __ Call(&try_handler_setup);
1180 // Try handler code. Return address of call is pushed on handler stack. 1215 // Try handler code. Return address of call is pushed on handler stack.
1181 { 1216 {
1182 // This code is only executed during stack-handler traversal when an 1217 // This code is only executed during stack-handler traversal when an
1183 // exception is thrown. The execption is in the result register, which 1218 // exception is thrown. The exception is in the result register, which
1184 // is retained by the finally block. 1219 // is retained by the finally block.
1185 // Call the finally block and then rethrow the exception. 1220 // Call the finally block and then rethrow the exception if it returns.
1186 __ Call(&finally_entry); 1221 __ Call(&finally_entry);
1187 __ push(result_register()); 1222 __ push(result_register());
1188 __ CallRuntime(Runtime::kReThrow, 1); 1223 __ CallRuntime(Runtime::kReThrow, 1);
1189 } 1224 }
1190 1225
1191 __ bind(&finally_entry); 1226 __ bind(&finally_entry);
1192 { 1227 {
1193 // Finally block implementation. 1228 // Finally block implementation.
1194 Finally finally_block(this); 1229 Finally finally_block(this);
1195 EnterFinallyBlock(); 1230 EnterFinallyBlock();
1196 set_stack_height(finally_block_stack_height); 1231 set_stack_height(original_stack_height + Finally::kElementCount);
1197 Visit(stmt->finally_block()); 1232 Visit(stmt->finally_block());
1198 ExitFinallyBlock(); // Return to the calling code. 1233 ExitFinallyBlock(); // Return to the calling code.
1199 } 1234 }
1200 1235
1201 __ bind(&try_handler_setup); 1236 __ bind(&try_handler_setup);
1202 { 1237 {
1203 // Setup try handler (stack pointer registers). 1238 // Setup try handler (stack pointer registers).
1239 const int delta = StackHandlerConstants::kSize / kPointerSize;
1204 TryFinally try_block(this, &finally_entry); 1240 TryFinally try_block(this, &finally_entry);
1205 __ PushTryHandler(IN_JAVASCRIPT, TRY_FINALLY_HANDLER); 1241 __ PushTryHandler(IN_JAVASCRIPT, TRY_FINALLY_HANDLER);
1206 set_stack_height(try_block_stack_height); 1242 set_stack_height(original_stack_height + delta);
1207 Visit(stmt->try_block()); 1243 Visit(stmt->try_block());
1208 __ PopTryHandler(); 1244 __ PopTryHandler();
1209 set_stack_height(original_stack_height); 1245 set_stack_height(original_stack_height);
1210 } 1246 }
1211 // Execute the finally block on the way out. Clobber the unpredictable 1247 // Execute the finally block on the way out. Clobber the unpredictable
1212 // value in the accumulator with one that's safe for GC. The finally 1248 // value in the accumulator with one that's safe for GC. The finally
1213 // block will unconditionally preserve the accumulator on the stack. 1249 // block will unconditionally preserve the accumulator on the stack.
1214 ClearAccumulator(); 1250 ClearAccumulator();
1215 __ Call(&finally_entry); 1251 __ Call(&finally_entry);
1216 } 1252 }
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
1293 Comment cmnt(masm_, "[ Throw"); 1329 Comment cmnt(masm_, "[ Throw");
1294 // Throw has no effect on the stack height or the current expression context. 1330 // 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. 1331 // Usually the expression context is null, because throw is a statement.
1296 VisitForStackValue(expr->exception()); 1332 VisitForStackValue(expr->exception());
1297 __ CallRuntime(Runtime::kThrow, 1); 1333 __ CallRuntime(Runtime::kThrow, 1);
1298 decrement_stack_height(); 1334 decrement_stack_height();
1299 // Never returns here. 1335 // Never returns here.
1300 } 1336 }
1301 1337
1302 1338
1303 int FullCodeGenerator::TryFinally::Exit(int stack_depth) { 1339 FullCodeGenerator::NestedStatement* FullCodeGenerator::TryFinally::Exit(
1340 int* stack_depth,
1341 int* context_length) {
1304 // The macros used here must preserve the result register. 1342 // The macros used here must preserve the result register.
1305 __ Drop(stack_depth); 1343 __ Drop(*stack_depth);
1306 __ PopTryHandler(); 1344 __ PopTryHandler();
1345 *stack_depth = 0;
1346
1347 Register context = FullCodeGenerator::context_register();
1348 while (*context_length > 0) {
1349 codegen_->LoadContextField(context, Context::PREVIOUS_INDEX);
1350 --(*context_length);
1351 }
1352
1307 __ Call(finally_entry_); 1353 __ Call(finally_entry_);
1308 return 0; 1354 return previous_;
1309 } 1355 }
1310 1356
1311 1357
1312 int FullCodeGenerator::TryCatch::Exit(int stack_depth) { 1358 FullCodeGenerator::NestedStatement* FullCodeGenerator::TryCatch::Exit(
1359 int* stack_depth,
1360 int* context_length) {
1313 // The macros used here must preserve the result register. 1361 // The macros used here must preserve the result register.
1314 __ Drop(stack_depth); 1362 __ Drop(*stack_depth);
1315 __ PopTryHandler(); 1363 __ PopTryHandler();
1316 return 0; 1364 *stack_depth = 0;
1365 return previous_;
1317 } 1366 }
1318 1367
1319 1368
1320 bool FullCodeGenerator::TryLiteralCompare(CompareOperation* compare, 1369 bool FullCodeGenerator::TryLiteralCompare(CompareOperation* compare,
1321 Label* if_true, 1370 Label* if_true,
1322 Label* if_false, 1371 Label* if_false,
1323 Label* fall_through) { 1372 Label* fall_through) {
1324 Expression *expr; 1373 Expression *expr;
1325 Handle<String> check; 1374 Handle<String> check;
1326 if (compare->IsLiteralCompareTypeof(&expr, &check)) { 1375 if (compare->IsLiteralCompareTypeof(&expr, &check)) {
1327 EmitLiteralCompareTypeof(expr, check, if_true, if_false, fall_through); 1376 EmitLiteralCompareTypeof(expr, check, if_true, if_false, fall_through);
1328 return true; 1377 return true;
1329 } 1378 }
1330 1379
1331 if (compare->IsLiteralCompareUndefined(&expr)) { 1380 if (compare->IsLiteralCompareUndefined(&expr)) {
1332 EmitLiteralCompareUndefined(expr, if_true, if_false, fall_through); 1381 EmitLiteralCompareUndefined(expr, if_true, if_false, fall_through);
1333 return true; 1382 return true;
1334 } 1383 }
1335 1384
1336 return false; 1385 return false;
1337 } 1386 }
1338 1387
1339 1388
1340 #undef __ 1389 #undef __
1341 1390
1342 1391
1343 } } // namespace v8::internal 1392 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/full-codegen.h ('k') | src/handles.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698