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

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

Issue 2521233002: [fullcodegen] Remove exception handling support. (Closed)
Patch Set: Rebased. Created 4 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
« no previous file with comments | « src/full-codegen/full-codegen.h ('k') | src/full-codegen/ia32/full-codegen-ia32.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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/full-codegen/full-codegen.h" 5 #include "src/full-codegen/full-codegen.h"
6 6
7 #include "src/ast/ast-numbering.h" 7 #include "src/ast/ast-numbering.h"
8 #include "src/ast/ast.h" 8 #include "src/ast/ast.h"
9 #include "src/ast/prettyprinter.h" 9 #include "src/ast/prettyprinter.h"
10 #include "src/ast/scopes.h" 10 #include "src/ast/scopes.h"
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 nesting_stack_(NULL), 55 nesting_stack_(NULL),
56 loop_depth_(0), 56 loop_depth_(0),
57 operand_stack_depth_(0), 57 operand_stack_depth_(0),
58 globals_(NULL), 58 globals_(NULL),
59 context_(NULL), 59 context_(NULL),
60 bailout_entries_(info->HasDeoptimizationSupport() 60 bailout_entries_(info->HasDeoptimizationSupport()
61 ? info->literal()->ast_node_count() 61 ? info->literal()->ast_node_count()
62 : 0, 62 : 0,
63 info->zone()), 63 info->zone()),
64 back_edges_(2, info->zone()), 64 back_edges_(2, info->zone()),
65 handler_table_(info->zone()),
66 source_position_table_builder_(info->zone(), 65 source_position_table_builder_(info->zone(),
67 info->SourcePositionRecordingMode()), 66 info->SourcePositionRecordingMode()),
68 ic_total_count_(0) { 67 ic_total_count_(0) {
69 DCHECK(!info->IsStub()); 68 DCHECK(!info->IsStub());
70 Initialize(stack_limit); 69 Initialize(stack_limit);
71 } 70 }
72 71
73 // static 72 // static
74 CompilationJob* FullCodeGenerator::NewCompilationJob(CompilationInfo* info) { 73 CompilationJob* FullCodeGenerator::NewCompilationJob(CompilationInfo* info) {
75 return new FullCodegenCompilationJob(info); 74 return new FullCodegenCompilationJob(info);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 if (cgen.HasStackOverflow()) { 107 if (cgen.HasStackOverflow()) {
109 DCHECK(!isolate->has_pending_exception()); 108 DCHECK(!isolate->has_pending_exception());
110 return false; 109 return false;
111 } 110 }
112 unsigned table_offset = cgen.EmitBackEdgeTable(); 111 unsigned table_offset = cgen.EmitBackEdgeTable();
113 112
114 Handle<Code> code = 113 Handle<Code> code =
115 CodeGenerator::MakeCodeEpilogue(&masm, nullptr, info, masm.CodeObject()); 114 CodeGenerator::MakeCodeEpilogue(&masm, nullptr, info, masm.CodeObject());
116 cgen.PopulateDeoptimizationData(code); 115 cgen.PopulateDeoptimizationData(code);
117 cgen.PopulateTypeFeedbackInfo(code); 116 cgen.PopulateTypeFeedbackInfo(code);
118 cgen.PopulateHandlerTable(code);
119 code->set_has_deoptimization_support(info->HasDeoptimizationSupport()); 117 code->set_has_deoptimization_support(info->HasDeoptimizationSupport());
120 code->set_has_reloc_info_for_serialization(info->will_serialize()); 118 code->set_has_reloc_info_for_serialization(info->will_serialize());
121 code->set_allow_osr_at_loop_nesting_level(0); 119 code->set_allow_osr_at_loop_nesting_level(0);
122 code->set_profiler_ticks(0); 120 code->set_profiler_ticks(0);
123 code->set_back_edge_table_offset(table_offset); 121 code->set_back_edge_table_offset(table_offset);
124 Handle<ByteArray> source_positions = 122 Handle<ByteArray> source_positions =
125 cgen.source_position_table_builder_.ToSourcePositionTable( 123 cgen.source_position_table_builder_.ToSourcePositionTable(
126 isolate, Handle<AbstractCode>::cast(code)); 124 isolate, Handle<AbstractCode>::cast(code));
127 code->set_source_position_table(*source_positions); 125 code->set_source_position_table(*source_positions);
128 CodeGenerator::PrintCode(code, info); 126 CodeGenerator::PrintCode(code, info);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 167
170 168
171 void FullCodeGenerator::PopulateTypeFeedbackInfo(Handle<Code> code) { 169 void FullCodeGenerator::PopulateTypeFeedbackInfo(Handle<Code> code) {
172 Handle<TypeFeedbackInfo> info = isolate()->factory()->NewTypeFeedbackInfo(); 170 Handle<TypeFeedbackInfo> info = isolate()->factory()->NewTypeFeedbackInfo();
173 info->set_ic_total_count(ic_total_count_); 171 info->set_ic_total_count(ic_total_count_);
174 DCHECK(!isolate()->heap()->InNewSpace(*info)); 172 DCHECK(!isolate()->heap()->InNewSpace(*info));
175 code->set_type_feedback_info(*info); 173 code->set_type_feedback_info(*info);
176 } 174 }
177 175
178 176
179 void FullCodeGenerator::PopulateHandlerTable(Handle<Code> code) {
180 int handler_table_size = static_cast<int>(handler_table_.size());
181 Handle<HandlerTable> table =
182 Handle<HandlerTable>::cast(isolate()->factory()->NewFixedArray(
183 HandlerTable::LengthForRange(handler_table_size), TENURED));
184 for (int i = 0; i < handler_table_size; ++i) {
185 table->SetRangeStart(i, handler_table_[i].range_start);
186 table->SetRangeEnd(i, handler_table_[i].range_end);
187 table->SetRangeHandler(i, handler_table_[i].handler_offset,
188 handler_table_[i].catch_prediction);
189 table->SetRangeData(i, handler_table_[i].stack_depth);
190 }
191 code->set_handler_table(*table);
192 }
193
194
195 int FullCodeGenerator::NewHandlerTableEntry() {
196 int index = static_cast<int>(handler_table_.size());
197 HandlerTableEntry entry = {0, 0, 0, 0, HandlerTable::UNCAUGHT};
198 handler_table_.push_back(entry);
199 return index;
200 }
201
202
203 bool FullCodeGenerator::MustCreateObjectLiteralWithRuntime( 177 bool FullCodeGenerator::MustCreateObjectLiteralWithRuntime(
204 ObjectLiteral* expr) const { 178 ObjectLiteral* expr) const {
205 return masm()->serializer_enabled() || 179 return masm()->serializer_enabled() ||
206 !FastCloneShallowObjectStub::IsSupported(expr); 180 !FastCloneShallowObjectStub::IsSupported(expr);
207 } 181 }
208 182
209 183
210 bool FullCodeGenerator::MustCreateArrayLiteralWithRuntime( 184 bool FullCodeGenerator::MustCreateArrayLiteralWithRuntime(
211 ArrayLiteral* expr) const { 185 ArrayLiteral* expr) const {
212 return expr->depth() > 1 || 186 return expr->depth() > 1 ||
(...skipping 769 matching lines...) Expand 10 before | Expand all | Expand 10 after
982 PrepareForBailoutForId(stmt->ElseId(), BailoutState::NO_REGISTERS); 956 PrepareForBailoutForId(stmt->ElseId(), BailoutState::NO_REGISTERS);
983 } 957 }
984 __ bind(&done); 958 __ bind(&done);
985 PrepareForBailoutForId(stmt->IfId(), BailoutState::NO_REGISTERS); 959 PrepareForBailoutForId(stmt->IfId(), BailoutState::NO_REGISTERS);
986 } 960 }
987 961
988 void FullCodeGenerator::EmitContinue(Statement* target) { 962 void FullCodeGenerator::EmitContinue(Statement* target) {
989 NestedStatement* current = nesting_stack_; 963 NestedStatement* current = nesting_stack_;
990 int context_length = 0; 964 int context_length = 0;
991 // When continuing, we clobber the unpredictable value in the accumulator 965 // When continuing, we clobber the unpredictable value in the accumulator
992 // with one that's safe for GC. If we hit an exit from the try block of 966 // with one that's safe for GC.
993 // try...finally on our way out, we will unconditionally preserve the
994 // accumulator on the stack.
995 ClearAccumulator(); 967 ClearAccumulator();
996 while (!current->IsContinueTarget(target)) { 968 while (!current->IsContinueTarget(target)) {
997 if (HasStackOverflow()) return; 969 if (HasStackOverflow()) return;
998 if (current->IsTryFinally()) {
999 Comment cmnt(masm(), "[ Deferred continue through finally");
1000 current->Exit(&context_length);
1001 DCHECK_EQ(-1, context_length);
1002 current->AsTryFinally()->deferred_commands()->RecordContinue(target);
1003 return;
1004 }
1005 current = current->Exit(&context_length); 970 current = current->Exit(&context_length);
1006 } 971 }
1007 int stack_depth = current->GetStackDepthAtTarget(); 972 int stack_depth = current->GetStackDepthAtTarget();
1008 int stack_drop = operand_stack_depth_ - stack_depth; 973 int stack_drop = operand_stack_depth_ - stack_depth;
1009 DCHECK_GE(stack_drop, 0); 974 DCHECK_GE(stack_drop, 0);
1010 __ Drop(stack_drop); 975 __ Drop(stack_drop);
1011 if (context_length > 0) { 976 if (context_length > 0) {
1012 while (context_length > 0) { 977 while (context_length > 0) {
1013 LoadContextField(context_register(), Context::PREVIOUS_INDEX); 978 LoadContextField(context_register(), Context::PREVIOUS_INDEX);
1014 --context_length; 979 --context_length;
1015 } 980 }
1016 StoreToFrameField(StandardFrameConstants::kContextOffset, 981 StoreToFrameField(StandardFrameConstants::kContextOffset,
1017 context_register()); 982 context_register());
1018 } 983 }
1019 984
1020 __ jmp(current->AsIteration()->continue_label()); 985 __ jmp(current->AsIteration()->continue_label());
1021 } 986 }
1022 987
1023 void FullCodeGenerator::VisitContinueStatement(ContinueStatement* stmt) { 988 void FullCodeGenerator::VisitContinueStatement(ContinueStatement* stmt) {
1024 Comment cmnt(masm_, "[ ContinueStatement"); 989 Comment cmnt(masm_, "[ ContinueStatement");
1025 SetStatementPosition(stmt); 990 SetStatementPosition(stmt);
1026 EmitContinue(stmt->target()); 991 EmitContinue(stmt->target());
1027 } 992 }
1028 993
1029 void FullCodeGenerator::EmitBreak(Statement* target) { 994 void FullCodeGenerator::EmitBreak(Statement* target) {
1030 NestedStatement* current = nesting_stack_; 995 NestedStatement* current = nesting_stack_;
1031 int context_length = 0; 996 int context_length = 0;
1032 // When breaking, we clobber the unpredictable value in the accumulator 997 // When breaking, we clobber the unpredictable value in the accumulator
1033 // with one that's safe for GC. If we hit an exit from the try block of 998 // with one that's safe for GC.
1034 // try...finally on our way out, we will unconditionally preserve the
1035 // accumulator on the stack.
1036 ClearAccumulator(); 999 ClearAccumulator();
1037 while (!current->IsBreakTarget(target)) { 1000 while (!current->IsBreakTarget(target)) {
1038 if (HasStackOverflow()) return; 1001 if (HasStackOverflow()) return;
1039 if (current->IsTryFinally()) {
1040 Comment cmnt(masm(), "[ Deferred break through finally");
1041 current->Exit(&context_length);
1042 DCHECK_EQ(-1, context_length);
1043 current->AsTryFinally()->deferred_commands()->RecordBreak(target);
1044 return;
1045 }
1046 current = current->Exit(&context_length); 1002 current = current->Exit(&context_length);
1047 } 1003 }
1048 int stack_depth = current->GetStackDepthAtTarget(); 1004 int stack_depth = current->GetStackDepthAtTarget();
1049 int stack_drop = operand_stack_depth_ - stack_depth; 1005 int stack_drop = operand_stack_depth_ - stack_depth;
1050 DCHECK_GE(stack_drop, 0); 1006 DCHECK_GE(stack_drop, 0);
1051 __ Drop(stack_drop); 1007 __ Drop(stack_drop);
1052 if (context_length > 0) { 1008 if (context_length > 0) {
1053 while (context_length > 0) { 1009 while (context_length > 0) {
1054 LoadContextField(context_register(), Context::PREVIOUS_INDEX); 1010 LoadContextField(context_register(), Context::PREVIOUS_INDEX);
1055 --context_length; 1011 --context_length;
1056 } 1012 }
1057 StoreToFrameField(StandardFrameConstants::kContextOffset, 1013 StoreToFrameField(StandardFrameConstants::kContextOffset,
1058 context_register()); 1014 context_register());
1059 } 1015 }
1060 1016
1061 __ jmp(current->AsBreakable()->break_label()); 1017 __ jmp(current->AsBreakable()->break_label());
1062 } 1018 }
1063 1019
1064 void FullCodeGenerator::VisitBreakStatement(BreakStatement* stmt) { 1020 void FullCodeGenerator::VisitBreakStatement(BreakStatement* stmt) {
1065 Comment cmnt(masm_, "[ BreakStatement"); 1021 Comment cmnt(masm_, "[ BreakStatement");
1066 SetStatementPosition(stmt); 1022 SetStatementPosition(stmt);
1067 EmitBreak(stmt->target()); 1023 EmitBreak(stmt->target());
1068 } 1024 }
1069 1025
1070 void FullCodeGenerator::EmitUnwindAndReturn() { 1026 void FullCodeGenerator::EmitUnwindAndReturn() {
1071 NestedStatement* current = nesting_stack_; 1027 NestedStatement* current = nesting_stack_;
1072 int context_length = 0; 1028 int context_length = 0;
1073 while (current != NULL) { 1029 while (current != NULL) {
1074 if (HasStackOverflow()) return; 1030 if (HasStackOverflow()) return;
1075 if (current->IsTryFinally()) {
1076 Comment cmnt(masm(), "[ Deferred return through finally");
1077 current->Exit(&context_length);
1078 DCHECK_EQ(-1, context_length);
1079 current->AsTryFinally()->deferred_commands()->RecordReturn();
1080 return;
1081 }
1082 current = current->Exit(&context_length); 1031 current = current->Exit(&context_length);
1083 } 1032 }
1084 EmitReturnSequence(); 1033 EmitReturnSequence();
1085 } 1034 }
1086 1035
1087 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info, 1036 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
1088 bool pretenure) { 1037 bool pretenure) {
1089 // If we're running with the --always-opt or the --prepare-always-opt 1038 // If we're running with the --always-opt or the --prepare-always-opt
1090 // flag, we need to use the runtime function so that the new function 1039 // flag, we need to use the runtime function so that the new function
1091 // we are creating here gets a chance to have its code optimized and 1040 // we are creating here gets a chance to have its code optimized and
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
1353 decrement_loop_depth(); 1302 decrement_loop_depth();
1354 } 1303 }
1355 1304
1356 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) { 1305 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) {
1357 LoadFromFrameField(JavaScriptFrameConstants::kFunctionOffset, 1306 LoadFromFrameField(JavaScriptFrameConstants::kFunctionOffset,
1358 result_register()); 1307 result_register());
1359 context()->Plug(result_register()); 1308 context()->Plug(result_register());
1360 } 1309 }
1361 1310
1362 void FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { 1311 void FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
1363 Comment cmnt(masm_, "[ TryCatchStatement"); 1312 // Exception handling is not supported.
1364 SetStatementPosition(stmt, SKIP_BREAK); 1313 UNREACHABLE();
1365
1366 // The try block adds a handler to the exception handler chain before
1367 // entering, and removes it again when exiting normally. If an exception
1368 // is thrown during execution of the try block, the handler is consumed
1369 // and control is passed to the catch block with the exception in the
1370 // result register.
1371
1372 Label try_entry, handler_entry, exit;
1373 __ jmp(&try_entry);
1374 __ bind(&handler_entry);
1375 if (stmt->clear_pending_message()) ClearPendingMessage();
1376
1377 // Exception handler code, the exception is in the result register.
1378 // Extend the context before executing the catch block.
1379 { Comment cmnt(masm_, "[ Extend catch context");
1380 PushOperand(stmt->variable()->name());
1381 PushOperand(result_register());
1382 PushOperand(stmt->scope()->scope_info());
1383 PushFunctionArgumentForContextAllocation();
1384 CallRuntimeWithOperands(Runtime::kPushCatchContext);
1385 StoreToFrameField(StandardFrameConstants::kContextOffset,
1386 context_register());
1387 }
1388
1389 Scope* saved_scope = scope();
1390 scope_ = stmt->scope();
1391 DCHECK(scope_->declarations()->is_empty());
1392 { WithOrCatch catch_body(this);
1393 Visit(stmt->catch_block());
1394 }
1395 // Restore the context.
1396 LoadContextField(context_register(), Context::PREVIOUS_INDEX);
1397 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register());
1398 scope_ = saved_scope;
1399 __ jmp(&exit);
1400
1401 // Try block code. Sets up the exception handler chain.
1402 __ bind(&try_entry);
1403
1404 int handler_index = NewHandlerTableEntry();
1405 EnterTryBlock(handler_index, &handler_entry, stmt->catch_prediction());
1406 {
1407 Comment cmnt_try(masm(), "[ Try block");
1408 Visit(stmt->try_block());
1409 }
1410 ExitTryBlock(handler_index);
1411 __ bind(&exit);
1412 } 1314 }
1413 1315
1414 1316
1415 void FullCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) { 1317 void FullCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
1416 Comment cmnt(masm_, "[ TryFinallyStatement"); 1318 // Exception handling is not supported.
1417 SetStatementPosition(stmt, SKIP_BREAK); 1319 UNREACHABLE();
1418
1419 // Try finally is compiled by setting up a try-handler on the stack while
1420 // executing the try body, and removing it again afterwards.
1421 //
1422 // The try-finally construct can enter the finally block in three ways:
1423 // 1. By exiting the try-block normally. This exits the try block,
1424 // pushes the continuation token and falls through to the finally
1425 // block.
1426 // 2. By exiting the try-block with a function-local control flow transfer
1427 // (break/continue/return). The site of the, e.g., break exits the
1428 // try block, pushes the continuation token and jumps to the
1429 // finally block. After the finally block executes, the execution
1430 // continues based on the continuation token to a block that
1431 // continues with the control flow transfer.
1432 // 3. By exiting the try-block with a thrown exception. In the handler,
1433 // we push the exception and continuation token and jump to the
1434 // finally block (which will again dispatch based on the token once
1435 // it is finished).
1436
1437 Label try_entry, handler_entry, finally_entry;
1438 DeferredCommands deferred(this, &finally_entry);
1439
1440 // Jump to try-handler setup and try-block code.
1441 __ jmp(&try_entry);
1442 __ bind(&handler_entry);
1443
1444 // Exception handler code. This code is only executed when an exception
1445 // is thrown. Record the continuation and jump to the finally block.
1446 {
1447 Comment cmnt_handler(masm(), "[ Finally handler");
1448 deferred.RecordThrow();
1449 }
1450
1451 // Set up try handler.
1452 __ bind(&try_entry);
1453 int handler_index = NewHandlerTableEntry();
1454 EnterTryBlock(handler_index, &handler_entry, stmt->catch_prediction());
1455 {
1456 Comment cmnt_try(masm(), "[ Try block");
1457 TryFinally try_body(this, &deferred);
1458 Visit(stmt->try_block());
1459 }
1460 ExitTryBlock(handler_index);
1461 // Execute the finally block on the way out. Clobber the unpredictable
1462 // value in the result register with one that's safe for GC because the
1463 // finally block will unconditionally preserve the result register on the
1464 // stack.
1465 ClearAccumulator();
1466 deferred.EmitFallThrough();
1467 // Fall through to the finally block.
1468
1469 // Finally block implementation.
1470 __ bind(&finally_entry);
1471 {
1472 Comment cmnt_finally(masm(), "[ Finally block");
1473 OperandStackDepthIncrement(2); // Token and accumulator are on stack.
1474 EnterFinallyBlock();
1475 Visit(stmt->finally_block());
1476 ExitFinallyBlock();
1477 OperandStackDepthDecrement(2); // Token and accumulator were on stack.
1478 }
1479
1480 {
1481 Comment cmnt_deferred(masm(), "[ Post-finally dispatch");
1482 deferred.EmitCommands(); // Return to the calling code.
1483 }
1484 } 1320 }
1485 1321
1486 1322
1487 void FullCodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) { 1323 void FullCodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) {
1488 Comment cmnt(masm_, "[ DebuggerStatement"); 1324 Comment cmnt(masm_, "[ DebuggerStatement");
1489 SetStatementPosition(stmt); 1325 SetStatementPosition(stmt);
1490 1326
1491 __ DebugBreak(); 1327 __ DebugBreak();
1492 // Ignore the return value. 1328 // Ignore the return value.
1493 1329
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
1623 VisitForStackValue(expr->exception()); 1459 VisitForStackValue(expr->exception());
1624 SetExpressionPosition(expr); 1460 SetExpressionPosition(expr);
1625 CallRuntimeWithOperands(Runtime::kThrow); 1461 CallRuntimeWithOperands(Runtime::kThrow);
1626 // Never returns here. 1462 // Never returns here.
1627 1463
1628 // Even though this expression doesn't produce a value, we need to simulate 1464 // Even though this expression doesn't produce a value, we need to simulate
1629 // plugging of the value context to ensure stack depth tracking is in sync. 1465 // plugging of the value context to ensure stack depth tracking is in sync.
1630 if (context()->IsStackValue()) OperandStackDepthIncrement(1); 1466 if (context()->IsStackValue()) OperandStackDepthIncrement(1);
1631 } 1467 }
1632 1468
1633 void FullCodeGenerator::EnterTryBlock(
1634 int handler_index, Label* handler,
1635 HandlerTable::CatchPrediction catch_prediction) {
1636 HandlerTableEntry* entry = &handler_table_[handler_index];
1637 entry->range_start = masm()->pc_offset();
1638 entry->handler_offset = handler->pos();
1639 entry->stack_depth = operand_stack_depth_;
1640 entry->catch_prediction = catch_prediction;
1641
1642 // We are using the operand stack depth, check for accuracy.
1643 EmitOperandStackDepthCheck();
1644
1645 // Push context onto operand stack.
1646 STATIC_ASSERT(TryBlockConstant::kElementCount == 1);
1647 PushOperand(context_register());
1648 }
1649
1650
1651 void FullCodeGenerator::ExitTryBlock(int handler_index) {
1652 HandlerTableEntry* entry = &handler_table_[handler_index];
1653 entry->range_end = masm()->pc_offset();
1654
1655 // Drop context from operand stack.
1656 DropOperands(TryBlockConstant::kElementCount);
1657 }
1658
1659 1469
1660 void FullCodeGenerator::VisitCall(Call* expr) { 1470 void FullCodeGenerator::VisitCall(Call* expr) {
1661 #ifdef DEBUG 1471 #ifdef DEBUG
1662 // We want to verify that RecordJSReturnSite gets called on all paths 1472 // We want to verify that RecordJSReturnSite gets called on all paths
1663 // through this function. Avoid early returns. 1473 // through this function. Avoid early returns.
1664 expr->return_is_recorded_ = false; 1474 expr->return_is_recorded_ = false;
1665 #endif 1475 #endif
1666 1476
1667 Comment cmnt(masm_, (expr->tail_call_mode() == TailCallMode::kAllow) 1477 Comment cmnt(masm_, (expr->tail_call_mode() == TailCallMode::kAllow)
1668 ? "[ TailCall" 1478 ? "[ TailCall"
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
1769 1579
1770 void FullCodeGenerator::VisitEmptyParentheses(EmptyParentheses* expr) { 1580 void FullCodeGenerator::VisitEmptyParentheses(EmptyParentheses* expr) {
1771 UNREACHABLE(); 1581 UNREACHABLE();
1772 } 1582 }
1773 1583
1774 1584
1775 void FullCodeGenerator::VisitRewritableExpression(RewritableExpression* expr) { 1585 void FullCodeGenerator::VisitRewritableExpression(RewritableExpression* expr) {
1776 Visit(expr->expression()); 1586 Visit(expr->expression());
1777 } 1587 }
1778 1588
1779 FullCodeGenerator::NestedStatement* FullCodeGenerator::TryFinally::Exit(
1780 int* context_length) {
1781 // The macros used here must preserve the result register.
1782
1783 // Calculate how many operands to drop to get down to handler block.
1784 int stack_drop = codegen_->operand_stack_depth_ - GetStackDepthAtTarget();
1785 DCHECK_GE(stack_drop, 0);
1786
1787 // Because the handler block contains the context of the finally
1788 // code, we can restore it directly from there for the finally code
1789 // rather than iteratively unwinding contexts via their previous
1790 // links.
1791 if (*context_length > 0) {
1792 __ Drop(stack_drop); // Down to the handler block.
1793 // Restore the context to its dedicated register and the stack.
1794 STATIC_ASSERT(TryBlockConstant::kElementCount == 1);
1795 __ Pop(codegen_->context_register());
1796 codegen_->StoreToFrameField(StandardFrameConstants::kContextOffset,
1797 codegen_->context_register());
1798 } else {
1799 // Down to the handler block and also drop context.
1800 __ Drop(stack_drop + TryBlockConstant::kElementCount);
1801 }
1802
1803 // The caller will ignore outputs.
1804 *context_length = -1;
1805 return previous_;
1806 }
1807
1808 void FullCodeGenerator::DeferredCommands::RecordBreak(Statement* target) {
1809 TokenId token = dispenser_.GetBreakContinueToken();
1810 commands_.push_back({kBreak, token, target});
1811 EmitJumpToFinally(token);
1812 }
1813
1814 void FullCodeGenerator::DeferredCommands::RecordContinue(Statement* target) {
1815 TokenId token = dispenser_.GetBreakContinueToken();
1816 commands_.push_back({kContinue, token, target});
1817 EmitJumpToFinally(token);
1818 }
1819
1820 void FullCodeGenerator::DeferredCommands::RecordReturn() {
1821 if (return_token_ == TokenDispenserForFinally::kInvalidToken) {
1822 return_token_ = TokenDispenserForFinally::kReturnToken;
1823 commands_.push_back({kReturn, return_token_, nullptr});
1824 }
1825 EmitJumpToFinally(return_token_);
1826 }
1827
1828 void FullCodeGenerator::DeferredCommands::RecordThrow() {
1829 if (throw_token_ == TokenDispenserForFinally::kInvalidToken) {
1830 throw_token_ = TokenDispenserForFinally::kThrowToken;
1831 commands_.push_back({kThrow, throw_token_, nullptr});
1832 }
1833 EmitJumpToFinally(throw_token_);
1834 }
1835
1836 void FullCodeGenerator::DeferredCommands::EmitFallThrough() {
1837 __ Push(Smi::FromInt(TokenDispenserForFinally::kFallThroughToken));
1838 __ Push(result_register());
1839 }
1840
1841 void FullCodeGenerator::DeferredCommands::EmitJumpToFinally(TokenId token) {
1842 __ Push(Smi::FromInt(token));
1843 __ Push(result_register());
1844 __ jmp(finally_entry_);
1845 }
1846 1589
1847 bool FullCodeGenerator::TryLiteralCompare(CompareOperation* expr) { 1590 bool FullCodeGenerator::TryLiteralCompare(CompareOperation* expr) {
1848 Expression* sub_expr; 1591 Expression* sub_expr;
1849 Handle<String> check; 1592 Handle<String> check;
1850 if (expr->IsLiteralCompareTypeof(&sub_expr, &check)) { 1593 if (expr->IsLiteralCompareTypeof(&sub_expr, &check)) {
1851 SetExpressionPosition(expr); 1594 SetExpressionPosition(expr);
1852 EmitLiteralCompareTypeof(expr, sub_expr, check); 1595 EmitLiteralCompareTypeof(expr, sub_expr, check);
1853 return true; 1596 return true;
1854 } 1597 }
1855 1598
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
1995 return info_->has_simple_parameters(); 1738 return info_->has_simple_parameters();
1996 } 1739 }
1997 1740
1998 FunctionLiteral* FullCodeGenerator::literal() const { return info_->literal(); } 1741 FunctionLiteral* FullCodeGenerator::literal() const { return info_->literal(); }
1999 1742
2000 #undef __ 1743 #undef __
2001 1744
2002 1745
2003 } // namespace internal 1746 } // namespace internal
2004 } // namespace v8 1747 } // namespace v8
OLDNEW
« no previous file with comments | « src/full-codegen/full-codegen.h ('k') | src/full-codegen/ia32/full-codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698