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

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

Issue 8540005: Revert "Add a level of indirection to exception handler addresses." (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 1 month 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.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 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 ASSERT(!isolate->has_pending_exception()); 279 ASSERT(!isolate->has_pending_exception());
280 return false; 280 return false;
281 } 281 }
282 unsigned table_offset = cgen.EmitStackCheckTable(); 282 unsigned table_offset = cgen.EmitStackCheckTable();
283 283
284 Code::Flags flags = Code::ComputeFlags(Code::FUNCTION); 284 Code::Flags flags = Code::ComputeFlags(Code::FUNCTION);
285 Handle<Code> code = CodeGenerator::MakeCodeEpilogue(&masm, flags, info); 285 Handle<Code> code = CodeGenerator::MakeCodeEpilogue(&masm, flags, info);
286 code->set_optimizable(info->IsOptimizable()); 286 code->set_optimizable(info->IsOptimizable());
287 cgen.PopulateDeoptimizationData(code); 287 cgen.PopulateDeoptimizationData(code);
288 code->set_has_deoptimization_support(info->HasDeoptimizationSupport()); 288 code->set_has_deoptimization_support(info->HasDeoptimizationSupport());
289 code->set_handler_table(*cgen.handler_table());
290 #ifdef ENABLE_DEBUGGER_SUPPORT 289 #ifdef ENABLE_DEBUGGER_SUPPORT
291 code->set_has_debug_break_slots( 290 code->set_has_debug_break_slots(
292 info->isolate()->debugger()->IsDebuggerActive()); 291 info->isolate()->debugger()->IsDebuggerActive());
293 code->set_compiled_optimizable(info->IsOptimizable()); 292 code->set_compiled_optimizable(info->IsOptimizable());
294 #endif // ENABLE_DEBUGGER_SUPPORT 293 #endif // ENABLE_DEBUGGER_SUPPORT
295 code->set_allow_osr_at_loop_nesting_level(0); 294 code->set_allow_osr_at_loop_nesting_level(0);
296 code->set_stack_check_table_offset(table_offset); 295 code->set_stack_check_table_offset(table_offset);
297 CodeGenerator::PrintCode(code, info); 296 CodeGenerator::PrintCode(code, info);
298 info->SetCode(code); // May be an empty handle. 297 info->SetCode(code); // May be an empty handle.
299 #ifdef ENABLE_GDB_JIT_INTERFACE 298 #ifdef ENABLE_GDB_JIT_INTERFACE
(...skipping 780 matching lines...) Expand 10 before | Expand all | Expand 10 after
1080 1079
1081 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 1080 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1082 __ bind(loop_statement.break_label()); 1081 __ bind(loop_statement.break_label());
1083 decrement_loop_depth(); 1082 decrement_loop_depth();
1084 } 1083 }
1085 1084
1086 1085
1087 void FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { 1086 void FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
1088 Comment cmnt(masm_, "[ TryCatchStatement"); 1087 Comment cmnt(masm_, "[ TryCatchStatement");
1089 SetStatementPosition(stmt); 1088 SetStatementPosition(stmt);
1090 // The try block adds a handler to the exception handler chain before 1089 // The try block adds a handler to the exception handler chain
1091 // entering, and removes it again when exiting normally. If an exception 1090 // before entering, and removes it again when exiting normally.
1092 // is thrown during execution of the try block, the handler is consumed 1091 // If an exception is thrown during execution of the try block,
1093 // and control is passed to the catch block with the exception in the 1092 // control is passed to the handler, which also consumes the handler.
1094 // result register. 1093 // At this point, the exception is in a register, and store it in
1094 // the temporary local variable (prints as ".catch-var") before
1095 // executing the catch block. The catch block has been rewritten
1096 // to introduce a new scope to bind the catch variable and to remove
1097 // that scope again afterwards.
1095 1098
1096 Label try_entry, handler_entry, exit; 1099 Label try_handler_setup, done;
1097 __ jmp(&try_entry); 1100 __ Call(&try_handler_setup);
1098 __ bind(&handler_entry); 1101 // Try handler code, exception in result register.
1099 handler_table()->set(stmt->index(), Smi::FromInt(handler_entry.pos())); 1102
1100 // Exception handler code, the exception is in the result register.
1101 // Extend the context before executing the catch block. 1103 // Extend the context before executing the catch block.
1102 { Comment cmnt(masm_, "[ Extend catch context"); 1104 { Comment cmnt(masm_, "[ Extend catch context");
1103 __ Push(stmt->variable()->name()); 1105 __ Push(stmt->variable()->name());
1104 __ push(result_register()); 1106 __ push(result_register());
1105 PushFunctionArgumentForContextAllocation(); 1107 PushFunctionArgumentForContextAllocation();
1106 __ CallRuntime(Runtime::kPushCatchContext, 3); 1108 __ CallRuntime(Runtime::kPushCatchContext, 3);
1107 StoreToFrameField(StandardFrameConstants::kContextOffset, 1109 StoreToFrameField(StandardFrameConstants::kContextOffset,
1108 context_register()); 1110 context_register());
1109 } 1111 }
1110 1112
1111 Scope* saved_scope = scope(); 1113 Scope* saved_scope = scope();
1112 scope_ = stmt->scope(); 1114 scope_ = stmt->scope();
1113 ASSERT(scope_->declarations()->is_empty()); 1115 ASSERT(scope_->declarations()->is_empty());
1114 { WithOrCatch catch_body(this); 1116 { WithOrCatch body(this);
1115 Visit(stmt->catch_block()); 1117 Visit(stmt->catch_block());
1116 } 1118 }
1117 // Restore the context. 1119 // Restore the context.
1118 LoadContextField(context_register(), Context::PREVIOUS_INDEX); 1120 LoadContextField(context_register(), Context::PREVIOUS_INDEX);
1119 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); 1121 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register());
1120 scope_ = saved_scope; 1122 scope_ = saved_scope;
1121 __ jmp(&exit); 1123 __ jmp(&done);
1122 1124
1123 // Try block code. Sets up the exception handler chain. 1125 // Try block code. Sets up the exception handler chain.
1124 __ bind(&try_entry); 1126 __ bind(&try_handler_setup);
1125 __ PushTryHandler(IN_JAVASCRIPT, TRY_CATCH_HANDLER, stmt->index()); 1127 {
1126 { TryCatch try_body(this); 1128 TryCatch try_block(this);
1129 __ PushTryHandler(IN_JAVASCRIPT, TRY_CATCH_HANDLER);
1127 Visit(stmt->try_block()); 1130 Visit(stmt->try_block());
1131 __ PopTryHandler();
1128 } 1132 }
1129 __ PopTryHandler(); 1133 __ bind(&done);
1130 __ bind(&exit);
1131 } 1134 }
1132 1135
1133 1136
1134 void FullCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) { 1137 void FullCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
1135 Comment cmnt(masm_, "[ TryFinallyStatement"); 1138 Comment cmnt(masm_, "[ TryFinallyStatement");
1136 SetStatementPosition(stmt); 1139 SetStatementPosition(stmt);
1137 // Try finally is compiled by setting up a try-handler on the stack while 1140 // Try finally is compiled by setting up a try-handler on the stack while
1138 // executing the try body, and removing it again afterwards. 1141 // executing the try body, and removing it again afterwards.
1139 // 1142 //
1140 // The try-finally construct can enter the finally block in three ways: 1143 // The try-finally construct can enter the finally block in three ways:
1141 // 1. By exiting the try-block normally. This removes the try-handler and 1144 // 1. By exiting the try-block normally. This removes the try-handler and
1142 // calls the finally block code before continuing. 1145 // calls the finally block code before continuing.
1143 // 2. By exiting the try-block with a function-local control flow transfer 1146 // 2. By exiting the try-block with a function-local control flow transfer
1144 // (break/continue/return). The site of the, e.g., break removes the 1147 // (break/continue/return). The site of the, e.g., break removes the
1145 // try handler and calls the finally block code before continuing 1148 // try handler and calls the finally block code before continuing
1146 // its outward control transfer. 1149 // its outward control transfer.
1147 // 3. By exiting the try-block with a thrown exception. 1150 // 3. by exiting the try-block with a thrown exception.
1148 // This can happen in nested function calls. It traverses the try-handler 1151 // This can happen in nested function calls. It traverses the try-handler
1149 // chain and consumes the try-handler entry before jumping to the 1152 // chain and consumes the try-handler entry before jumping to the
1150 // handler code. The handler code then calls the finally-block before 1153 // handler code. The handler code then calls the finally-block before
1151 // rethrowing the exception. 1154 // rethrowing the exception.
1152 // 1155 //
1153 // The finally block must assume a return address on top of the stack 1156 // The finally block must assume a return address on top of the stack
1154 // (or in the link register on ARM chips) and a value (return value or 1157 // (or in the link register on ARM chips) and a value (return value or
1155 // exception) in the result register (rax/eax/r0), both of which must 1158 // exception) in the result register (rax/eax/r0), both of which must
1156 // be preserved. The return address isn't GC-safe, so it should be 1159 // be preserved. The return address isn't GC-safe, so it should be
1157 // cooked before GC. 1160 // cooked before GC.
1158 Label try_entry, handler_entry, finally_entry; 1161 Label finally_entry;
1162 Label try_handler_setup;
1159 1163
1160 // Jump to try-handler setup and try-block code. 1164 // Setup the try-handler chain. Use a call to
1161 __ jmp(&try_entry); 1165 // Jump to try-handler setup and try-block code. Use call to put try-handler
1162 __ bind(&handler_entry); 1166 // address on stack.
1163 handler_table()->set(stmt->index(), Smi::FromInt(handler_entry.pos())); 1167 __ Call(&try_handler_setup);
1164 // Exception handler code. This code is only executed when an exception 1168 // Try handler code. Return address of call is pushed on handler stack.
1165 // is thrown. The exception is in the result register, and must be 1169 {
1166 // preserved by the finally block. Call the finally block and then 1170 // This code is only executed during stack-handler traversal when an
1167 // rethrow the exception if it returns. 1171 // exception is thrown. The exception is in the result register, which
1168 __ Call(&finally_entry); 1172 // is retained by the finally block.
1169 __ push(result_register()); 1173 // Call the finally block and then rethrow the exception if it returns.
1170 __ CallRuntime(Runtime::kReThrow, 1); 1174 __ Call(&finally_entry);
1175 __ push(result_register());
1176 __ CallRuntime(Runtime::kReThrow, 1);
1177 }
1171 1178
1172 // Finally block implementation.
1173 __ bind(&finally_entry); 1179 __ bind(&finally_entry);
1174 EnterFinallyBlock(); 1180 {
1175 { Finally finally_body(this); 1181 // Finally block implementation.
1182 Finally finally_block(this);
1183 EnterFinallyBlock();
1176 Visit(stmt->finally_block()); 1184 Visit(stmt->finally_block());
1185 ExitFinallyBlock(); // Return to the calling code.
1177 } 1186 }
1178 ExitFinallyBlock(); // Return to the calling code.
1179 1187
1180 // Setup try handler. 1188 __ bind(&try_handler_setup);
1181 __ bind(&try_entry); 1189 {
1182 __ PushTryHandler(IN_JAVASCRIPT, TRY_FINALLY_HANDLER, stmt->index()); 1190 // Setup try handler (stack pointer registers).
1183 { TryFinally try_body(this, &finally_entry); 1191 TryFinally try_block(this, &finally_entry);
1192 __ PushTryHandler(IN_JAVASCRIPT, TRY_FINALLY_HANDLER);
1184 Visit(stmt->try_block()); 1193 Visit(stmt->try_block());
1194 __ PopTryHandler();
1185 } 1195 }
1186 __ PopTryHandler();
1187 // Execute the finally block on the way out. Clobber the unpredictable 1196 // Execute the finally block on the way out. Clobber the unpredictable
1188 // value in the result register with one that's safe for GC because the 1197 // value in the accumulator with one that's safe for GC. The finally
1189 // finally block will unconditionally preserve the result register on the 1198 // block will unconditionally preserve the accumulator on the stack.
1190 // stack.
1191 ClearAccumulator(); 1199 ClearAccumulator();
1192 __ Call(&finally_entry); 1200 __ Call(&finally_entry);
1193 } 1201 }
1194 1202
1195 1203
1196 void FullCodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) { 1204 void FullCodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) {
1197 #ifdef ENABLE_DEBUGGER_SUPPORT 1205 #ifdef ENABLE_DEBUGGER_SUPPORT
1198 Comment cmnt(masm_, "[ DebuggerStatement"); 1206 Comment cmnt(masm_, "[ DebuggerStatement");
1199 SetStatementPosition(stmt); 1207 SetStatementPosition(stmt);
1200 1208
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
1301 } 1309 }
1302 1310
1303 return false; 1311 return false;
1304 } 1312 }
1305 1313
1306 1314
1307 #undef __ 1315 #undef __
1308 1316
1309 1317
1310 } } // namespace v8::internal 1318 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/full-codegen.h ('k') | src/heap.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698