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

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

Issue 192513002: Checking for stack height equality between full codegen and hydrogen. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebase Created 6 years, 7 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/hydrogen.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 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 "v8.h" 5 #include "v8.h"
6 6
7 #include "codegen.h" 7 #include "codegen.h"
8 #include "compiler.h" 8 #include "compiler.h"
9 #include "debug.h" 9 #include "debug.h"
10 #include "full-codegen.h" 10 #include "full-codegen.h"
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after
374 void FullCodeGenerator::PopulateDeoptimizationData(Handle<Code> code) { 374 void FullCodeGenerator::PopulateDeoptimizationData(Handle<Code> code) {
375 // Fill in the deoptimization information. 375 // Fill in the deoptimization information.
376 ASSERT(info_->HasDeoptimizationSupport() || bailout_entries_.is_empty()); 376 ASSERT(info_->HasDeoptimizationSupport() || bailout_entries_.is_empty());
377 if (!info_->HasDeoptimizationSupport()) return; 377 if (!info_->HasDeoptimizationSupport()) return;
378 int length = bailout_entries_.length(); 378 int length = bailout_entries_.length();
379 Handle<DeoptimizationOutputData> data = 379 Handle<DeoptimizationOutputData> data =
380 DeoptimizationOutputData::New(isolate(), length, TENURED); 380 DeoptimizationOutputData::New(isolate(), length, TENURED);
381 for (int i = 0; i < length; i++) { 381 for (int i = 0; i < length; i++) {
382 data->SetAstId(i, bailout_entries_[i].id); 382 data->SetAstId(i, bailout_entries_[i].id);
383 data->SetPcAndState(i, Smi::FromInt(bailout_entries_[i].pc_and_state)); 383 data->SetPcAndState(i, Smi::FromInt(bailout_entries_[i].pc_and_state));
384 #if defined(COMPARE_OPT_STACK_HEIGHT)
385 data->SetStackHeight(i, Smi::FromInt(bailout_entries_[i].stack_height));
386 #endif
384 } 387 }
385 code->set_deoptimization_data(*data); 388 code->set_deoptimization_data(*data);
386 } 389 }
387 390
388 391
389 void FullCodeGenerator::PopulateTypeFeedbackInfo(Handle<Code> code) { 392 void FullCodeGenerator::PopulateTypeFeedbackInfo(Handle<Code> code) {
390 Handle<TypeFeedbackInfo> info = isolate()->factory()->NewTypeFeedbackInfo(); 393 Handle<TypeFeedbackInfo> info = isolate()->factory()->NewTypeFeedbackInfo();
391 info->set_ic_total_count(ic_total_count_); 394 info->set_ic_total_count(ic_total_count_);
392 ASSERT(!isolate()->heap()->InNewSpace(*info)); 395 ASSERT(!isolate()->heap()->InNewSpace(*info));
393 code->set_type_feedback_info(*info); 396 code->set_type_feedback_info(*info);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
441 // was called. 444 // was called.
442 ASSERT(!call->return_is_recorded_); 445 ASSERT(!call->return_is_recorded_);
443 call->return_is_recorded_ = true; 446 call->return_is_recorded_ = true;
444 #endif 447 #endif
445 } 448 }
446 449
447 450
448 void FullCodeGenerator::PrepareForBailoutForId(BailoutId id, State state) { 451 void FullCodeGenerator::PrepareForBailoutForId(BailoutId id, State state) {
449 // There's no need to prepare this code for bailouts from already optimized 452 // There's no need to prepare this code for bailouts from already optimized
450 // code or code that can't be optimized. 453 // code or code that can't be optimized.
451 if (!info_->HasDeoptimizationSupport()) return; 454 if (!info_->HasDeoptimizationSupport()) {
455 // We still need to insert the check to make sure that we generate exactly
456 // the same code
457 CheckStackHeight();
458 return;
459 }
452 unsigned pc_and_state = 460 unsigned pc_and_state =
453 StateField::encode(state) | PcField::encode(masm_->pc_offset()); 461 StateField::encode(state) | PcField::encode(masm_->pc_offset());
454 ASSERT(Smi::IsValid(pc_and_state)); 462 ASSERT(Smi::IsValid(pc_and_state));
455 #ifdef DEBUG 463 #ifdef DEBUG
456 for (int i = 0; i < bailout_entries_.length(); ++i) { 464 for (int i = 0; i < bailout_entries_.length(); ++i) {
457 ASSERT(bailout_entries_[i].id != id); 465 ASSERT(bailout_entries_[i].id != id);
458 } 466 }
459 #endif 467 #endif
460 BailoutEntry entry = { id, pc_and_state }; 468 // If the we store the top of the stack register, pretend it is on the stack
469 int stack_height = stack_height_.get() + (state == TOS_REG ? 1 : 0);
470 BailoutEntry entry = { id, pc_and_state, stack_height };
461 bailout_entries_.Add(entry, zone()); 471 bailout_entries_.Add(entry, zone());
472 CheckStackHeight();
462 } 473 }
463 474
464 475
465 void FullCodeGenerator::RecordBackEdge(BailoutId ast_id) { 476 void FullCodeGenerator::RecordBackEdge(BailoutId ast_id) {
466 // The pc offset does not need to be encoded and packed together with a state. 477 // The pc offset does not need to be encoded and packed together with a state.
467 ASSERT(masm_->pc_offset() > 0); 478 ASSERT(masm_->pc_offset() > 0);
468 ASSERT(loop_depth() > 0); 479 ASSERT(loop_depth() > 0);
469 uint8_t depth = Min(loop_depth(), Code::kMaxLoopNestingMarker); 480 uint8_t depth = Min(loop_depth(), Code::kMaxLoopNestingMarker);
470 BackEdgeEntry entry = 481 BackEdgeEntry entry =
471 { ast_id, static_cast<unsigned>(masm_->pc_offset()), depth }; 482 { ast_id, static_cast<unsigned>(masm_->pc_offset()), depth };
(...skipping 13 matching lines...) Expand all
485 void FullCodeGenerator::EffectContext::Plug(Register reg) const { 496 void FullCodeGenerator::EffectContext::Plug(Register reg) const {
486 } 497 }
487 498
488 499
489 void FullCodeGenerator::AccumulatorValueContext::Plug(Register reg) const { 500 void FullCodeGenerator::AccumulatorValueContext::Plug(Register reg) const {
490 __ Move(result_register(), reg); 501 __ Move(result_register(), reg);
491 } 502 }
492 503
493 504
494 void FullCodeGenerator::StackValueContext::Plug(Register reg) const { 505 void FullCodeGenerator::StackValueContext::Plug(Register reg) const {
495 __ Push(reg); 506 codegen()->AsmPush(reg);
496 } 507 }
497 508
498 509
499 void FullCodeGenerator::TestContext::Plug(Register reg) const { 510 void FullCodeGenerator::TestContext::Plug(Register reg) const {
500 // For simplicity we always test the accumulator register. 511 // For simplicity we always test the accumulator register.
501 __ Move(result_register(), reg); 512 __ Move(result_register(), reg);
502 codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL); 513 codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL);
503 codegen()->DoTest(this); 514 codegen()->DoTest(this);
504 } 515 }
505 516
506 517
507 void FullCodeGenerator::EffectContext::PlugTOS() const { 518 void FullCodeGenerator::EffectContext::PlugTOS() const {
508 __ Drop(1); 519 codegen()->AsmDrop(1);
509 } 520 }
510 521
511 522
512 void FullCodeGenerator::AccumulatorValueContext::PlugTOS() const { 523 void FullCodeGenerator::AccumulatorValueContext::PlugTOS() const {
513 __ Pop(result_register()); 524 codegen()->AsmPop(result_register());
514 } 525 }
515 526
516 527
517 void FullCodeGenerator::StackValueContext::PlugTOS() const { 528 void FullCodeGenerator::StackValueContext::PlugTOS() const {
518 } 529 }
519 530
520 531
521 void FullCodeGenerator::TestContext::PlugTOS() const { 532 void FullCodeGenerator::TestContext::PlugTOS() const {
522 // For simplicity we always test the accumulator register. 533 // For simplicity we always test the accumulator register.
523 __ Pop(result_register()); 534 codegen()->AsmPop(result_register());
524 codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL); 535 codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL);
525 codegen()->DoTest(this); 536 codegen()->DoTest(this);
526 } 537 }
527 538
528 539
529 void FullCodeGenerator::EffectContext::PrepareTest( 540 void FullCodeGenerator::EffectContext::PrepareTest(
530 Label* materialize_true, 541 Label* materialize_true,
531 Label* materialize_false, 542 Label* materialize_false,
532 Label** if_true, 543 Label** if_true,
533 Label** if_false, 544 Label** if_false,
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
590 if (module != NULL) { 601 if (module != NULL) {
591 Comment cmnt(masm_, "[ Link nested modules"); 602 Comment cmnt(masm_, "[ Link nested modules");
592 Scope* scope = module->body()->scope(); 603 Scope* scope = module->body()->scope();
593 Interface* interface = scope->interface(); 604 Interface* interface = scope->interface();
594 ASSERT(interface->IsModule() && interface->IsFrozen()); 605 ASSERT(interface->IsModule() && interface->IsFrozen());
595 606
596 interface->Allocate(scope->module_var()->index()); 607 interface->Allocate(scope->module_var()->index());
597 608
598 // Set up module context. 609 // Set up module context.
599 ASSERT(scope->interface()->Index() >= 0); 610 ASSERT(scope->interface()->Index() >= 0);
600 __ Push(Smi::FromInt(scope->interface()->Index())); 611 AsmPushSmi(Smi::FromInt(scope->interface()->Index()));
601 __ Push(scope->GetScopeInfo()); 612 AsmPushHandle(scope->GetScopeInfo());
602 __ CallRuntime(Runtime::kHiddenPushModuleContext, 2); 613 AsmCallRuntime(Runtime::kHiddenPushModuleContext, 2);
603 StoreToFrameField(StandardFrameConstants::kContextOffset, 614 StoreToFrameField(StandardFrameConstants::kContextOffset,
604 context_register()); 615 context_register());
605 616
606 AllocateModules(scope->declarations()); 617 AllocateModules(scope->declarations());
607 618
608 // Pop module context. 619 // Pop module context.
609 LoadContextField(context_register(), Context::PREVIOUS_INDEX); 620 LoadContextField(context_register(), Context::PREVIOUS_INDEX);
610 // Update local stack frame context field. 621 // Update local stack frame context field.
611 StoreToFrameField(StandardFrameConstants::kContextOffset, 622 StoreToFrameField(StandardFrameConstants::kContextOffset,
612 context_register()); 623 context_register());
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
681 Handle<FixedArray> saved_modules = modules_; 692 Handle<FixedArray> saved_modules = modules_;
682 int saved_module_index = module_index_; 693 int saved_module_index = module_index_;
683 ZoneList<Handle<Object> >* saved_globals = globals_; 694 ZoneList<Handle<Object> >* saved_globals = globals_;
684 ZoneList<Handle<Object> > inner_globals(10, zone()); 695 ZoneList<Handle<Object> > inner_globals(10, zone());
685 globals_ = &inner_globals; 696 globals_ = &inner_globals;
686 697
687 if (scope_->num_modules() != 0) { 698 if (scope_->num_modules() != 0) {
688 // This is a scope hosting modules. Allocate a descriptor array to pass 699 // This is a scope hosting modules. Allocate a descriptor array to pass
689 // to the runtime for initialization. 700 // to the runtime for initialization.
690 Comment cmnt(masm_, "[ Allocate modules"); 701 Comment cmnt(masm_, "[ Allocate modules");
702
691 ASSERT(scope_->is_global_scope()); 703 ASSERT(scope_->is_global_scope());
692 modules_ = 704 modules_ =
693 isolate()->factory()->NewFixedArray(scope_->num_modules(), TENURED); 705 isolate()->factory()->NewFixedArray(scope_->num_modules(), TENURED);
694 module_index_ = 0; 706 module_index_ = 0;
695 707
696 // Generate code for allocating all modules, including nested ones. 708 // Generate code for allocating all modules, including nested ones.
697 // The allocated contexts are stored in internal variables in this scope. 709 // The allocated contexts are stored in internal variables in this scope.
698 AllocateModules(declarations); 710 AllocateModules(declarations);
699 } 711 }
700 712
(...skipping 29 matching lines...) Expand all
730 742
731 Comment cmnt(masm_, "[ ModuleLiteral"); 743 Comment cmnt(masm_, "[ ModuleLiteral");
732 SetStatementPosition(block); 744 SetStatementPosition(block);
733 745
734 ASSERT(!modules_.is_null()); 746 ASSERT(!modules_.is_null());
735 ASSERT(module_index_ < modules_->length()); 747 ASSERT(module_index_ < modules_->length());
736 int index = module_index_++; 748 int index = module_index_++;
737 749
738 // Set up module context. 750 // Set up module context.
739 ASSERT(interface->Index() >= 0); 751 ASSERT(interface->Index() >= 0);
740 __ Push(Smi::FromInt(interface->Index())); 752 AsmPushSmi(Smi::FromInt(interface->Index()));
741 __ Push(Smi::FromInt(0)); 753 AsmPushSmi(Smi::FromInt(0));
742 __ CallRuntime(Runtime::kHiddenPushModuleContext, 2); 754 AsmCallRuntime(Runtime::kHiddenPushModuleContext, 2);
743 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); 755 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register());
744 756
745 { 757 {
746 Comment cmnt(masm_, "[ Declarations"); 758 Comment cmnt(masm_, "[ Declarations");
747 VisitDeclarations(scope_->declarations()); 759 VisitDeclarations(scope_->declarations());
748 } 760 }
749 761
750 // Populate the module description. 762 // Populate the module description.
751 Handle<ModuleInfo> description = 763 Handle<ModuleInfo> description =
752 ModuleInfo::Create(isolate(), interface, scope_); 764 ModuleInfo::Create(isolate(), interface, scope_);
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
963 Label done; 975 Label done;
964 976
965 if (context()->IsTest()) { 977 if (context()->IsTest()) {
966 Label eval_right; 978 Label eval_right;
967 const TestContext* test = TestContext::cast(context()); 979 const TestContext* test = TestContext::cast(context());
968 if (is_logical_and) { 980 if (is_logical_and) {
969 VisitForControl(left, &eval_right, test->false_label(), &eval_right); 981 VisitForControl(left, &eval_right, test->false_label(), &eval_right);
970 } else { 982 } else {
971 VisitForControl(left, test->true_label(), &eval_right, &eval_right); 983 VisitForControl(left, test->true_label(), &eval_right, &eval_right);
972 } 984 }
985 __ bind(&eval_right);
973 PrepareForBailoutForId(right_id, NO_REGISTERS); 986 PrepareForBailoutForId(right_id, NO_REGISTERS);
974 __ bind(&eval_right);
975
976 } else if (context()->IsAccumulatorValue()) { 987 } else if (context()->IsAccumulatorValue()) {
977 VisitForAccumulatorValue(left); 988 VisitForAccumulatorValue(left);
978 // We want the value in the accumulator for the test, and on the stack in 989 // We want the value in the accumulator for the test, and on the stack in
979 // case we need it. 990 // case we need it.
980 __ Push(result_register()); 991 AsmPush(result_register());
981 Label discard, restore; 992 Label discard, restore;
982 if (is_logical_and) { 993 if (is_logical_and) {
983 DoTest(left, &discard, &restore, &restore); 994 DoTest(left, &discard, &restore, &restore);
984 } else { 995 } else {
985 DoTest(left, &restore, &discard, &restore); 996 DoTest(left, &restore, &discard, &restore);
986 } 997 }
998 StackHeightWrapper branch_stack_height = CurrentStackHeight();
987 __ bind(&restore); 999 __ bind(&restore);
988 __ Pop(result_register()); 1000 AsmPop(result_register());
989 __ jmp(&done); 1001 __ jmp(&done);
990 __ bind(&discard); 1002 __ bind(&discard);
991 __ Drop(1); 1003 SetStackHeight(branch_stack_height);
1004 AsmDrop(1);
992 PrepareForBailoutForId(right_id, NO_REGISTERS); 1005 PrepareForBailoutForId(right_id, NO_REGISTERS);
993
994 } else if (context()->IsStackValue()) { 1006 } else if (context()->IsStackValue()) {
995 VisitForAccumulatorValue(left); 1007 VisitForAccumulatorValue(left);
996 // We want the value in the accumulator for the test, and on the stack in 1008 // We want the value in the accumulator for the test, and on the stack in
997 // case we need it. 1009 // case we need it.
998 __ Push(result_register()); 1010 AsmPush(result_register());
999 Label discard; 1011 Label discard;
1000 if (is_logical_and) { 1012 if (is_logical_and) {
1001 DoTest(left, &discard, &done, &discard); 1013 DoTest(left, &discard, &done, &discard);
1002 } else { 1014 } else {
1003 DoTest(left, &done, &discard, &discard); 1015 DoTest(left, &done, &discard, &discard);
1004 } 1016 }
1005 __ bind(&discard); 1017 __ bind(&discard);
1006 __ Drop(1); 1018 AsmDrop(1);
1007 PrepareForBailoutForId(right_id, NO_REGISTERS); 1019 PrepareForBailoutForId(right_id, NO_REGISTERS);
1008
1009 } else { 1020 } else {
1010 ASSERT(context()->IsEffect()); 1021 ASSERT(context()->IsEffect());
1011 Label eval_right; 1022 Label eval_right;
1012 if (is_logical_and) { 1023 if (is_logical_and) {
1013 VisitForControl(left, &eval_right, &done, &eval_right); 1024 VisitForControl(left, &eval_right, &done, &eval_right);
1014 } else { 1025 } else {
1015 VisitForControl(left, &done, &eval_right, &eval_right); 1026 VisitForControl(left, &done, &eval_right, &eval_right);
1016 } 1027 }
1028 __ bind(&eval_right);
1017 PrepareForBailoutForId(right_id, NO_REGISTERS); 1029 PrepareForBailoutForId(right_id, NO_REGISTERS);
1018 __ bind(&eval_right);
1019 } 1030 }
1020 1031
1021 VisitInDuplicateContext(right); 1032 VisitInDuplicateContext(right);
1022 __ bind(&done); 1033 __ bind(&done);
1023 } 1034 }
1024 1035
1025 1036
1026 void FullCodeGenerator::VisitArithmeticExpression(BinaryOperation* expr) { 1037 void FullCodeGenerator::VisitArithmeticExpression(BinaryOperation* expr) {
1027 Token::Value op = expr->op(); 1038 Token::Value op = expr->op();
1028 Comment cmnt(masm_, "[ ArithmeticExpression"); 1039 Comment cmnt(masm_, "[ ArithmeticExpression");
(...skipping 20 matching lines...) Expand all
1049 Comment cmnt(masm_, "[ Block"); 1060 Comment cmnt(masm_, "[ Block");
1050 NestedBlock nested_block(this, stmt); 1061 NestedBlock nested_block(this, stmt);
1051 SetStatementPosition(stmt); 1062 SetStatementPosition(stmt);
1052 1063
1053 Scope* saved_scope = scope(); 1064 Scope* saved_scope = scope();
1054 // Push a block context when entering a block with block scoped variables. 1065 // Push a block context when entering a block with block scoped variables.
1055 if (stmt->scope() != NULL) { 1066 if (stmt->scope() != NULL) {
1056 scope_ = stmt->scope(); 1067 scope_ = stmt->scope();
1057 ASSERT(!scope_->is_module_scope()); 1068 ASSERT(!scope_->is_module_scope());
1058 { Comment cmnt(masm_, "[ Extend block context"); 1069 { Comment cmnt(masm_, "[ Extend block context");
1059 __ Push(scope_->GetScopeInfo()); 1070 AsmPushHandle(scope_->GetScopeInfo());
1060 PushFunctionArgumentForContextAllocation(); 1071 PushFunctionArgumentForContextAllocation();
1061 __ CallRuntime(Runtime::kHiddenPushBlockContext, 2); 1072 AsmCallRuntime(Runtime::kHiddenPushBlockContext, 2);
1062 1073
1063 // Replace the context stored in the frame. 1074 // Replace the context stored in the frame.
1064 StoreToFrameField(StandardFrameConstants::kContextOffset, 1075 StoreToFrameField(StandardFrameConstants::kContextOffset,
1065 context_register()); 1076 context_register());
1066 } 1077 }
1067 { Comment cmnt(masm_, "[ Declarations"); 1078 { Comment cmnt(masm_, "[ Declarations");
1068 VisitDeclarations(scope_->declarations()); 1079 VisitDeclarations(scope_->declarations());
1069 } 1080 }
1070 } 1081 }
1071 1082
1072 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); 1083 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS);
1073 VisitStatements(stmt->statements()); 1084 VisitStatements(stmt->statements());
1074 scope_ = saved_scope; 1085 scope_ = saved_scope;
1075 __ bind(nested_block.break_label()); 1086 __ bind(nested_block.break_label());
1076 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 1087 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1077 1088
1078 // Pop block context if necessary. 1089 // Pop block context if necessary.
1079 if (stmt->scope() != NULL) { 1090 if (stmt->scope() != NULL) {
1080 LoadContextField(context_register(), Context::PREVIOUS_INDEX); 1091 LoadContextField(context_register(), Context::PREVIOUS_INDEX);
1081 // Update local stack frame context field. 1092 // Update local stack frame context field.
1082 StoreToFrameField(StandardFrameConstants::kContextOffset, 1093 StoreToFrameField(StandardFrameConstants::kContextOffset,
1083 context_register()); 1094 context_register());
1084 } 1095 }
1085 } 1096 }
1086 1097
1087 1098
1088 void FullCodeGenerator::VisitModuleStatement(ModuleStatement* stmt) { 1099 void FullCodeGenerator::VisitModuleStatement(ModuleStatement* stmt) {
1089 Comment cmnt(masm_, "[ Module context"); 1100 Comment cmnt(masm_, "[ Module context");
1090 1101
1091 __ Push(Smi::FromInt(stmt->proxy()->interface()->Index())); 1102 AsmPushSmi(Smi::FromInt(stmt->proxy()->interface()->Index()));
1092 __ Push(Smi::FromInt(0)); 1103 AsmPushSmi(Smi::FromInt(0));
1093 __ CallRuntime(Runtime::kHiddenPushModuleContext, 2); 1104 AsmCallRuntime(Runtime::kHiddenPushModuleContext, 2);
1094 StoreToFrameField( 1105 StoreToFrameField(
1095 StandardFrameConstants::kContextOffset, context_register()); 1106 StandardFrameConstants::kContextOffset, context_register());
1096 1107
1097 Scope* saved_scope = scope_; 1108 Scope* saved_scope = scope_;
1098 scope_ = stmt->body()->scope(); 1109 scope_ = stmt->body()->scope();
1099 VisitStatements(stmt->body()->statements()); 1110 VisitStatements(stmt->body()->statements());
1100 scope_ = saved_scope; 1111 scope_ = saved_scope;
1101 LoadContextField(context_register(), Context::PREVIOUS_INDEX); 1112 LoadContextField(context_register(), Context::PREVIOUS_INDEX);
1102 // Update local stack frame context field. 1113 // Update local stack frame context field.
1103 StoreToFrameField(StandardFrameConstants::kContextOffset, 1114 StoreToFrameField(StandardFrameConstants::kContextOffset,
(...skipping 14 matching lines...) Expand all
1118 } 1129 }
1119 1130
1120 1131
1121 void FullCodeGenerator::VisitIfStatement(IfStatement* stmt) { 1132 void FullCodeGenerator::VisitIfStatement(IfStatement* stmt) {
1122 Comment cmnt(masm_, "[ IfStatement"); 1133 Comment cmnt(masm_, "[ IfStatement");
1123 SetStatementPosition(stmt); 1134 SetStatementPosition(stmt);
1124 Label then_part, else_part, done; 1135 Label then_part, else_part, done;
1125 1136
1126 if (stmt->HasElseStatement()) { 1137 if (stmt->HasElseStatement()) {
1127 VisitForControl(stmt->condition(), &then_part, &else_part, &then_part); 1138 VisitForControl(stmt->condition(), &then_part, &else_part, &then_part);
1139 StackHeightWrapper if_stack_height = CurrentStackHeight();
1140 __ bind(&then_part);
1128 PrepareForBailoutForId(stmt->ThenId(), NO_REGISTERS); 1141 PrepareForBailoutForId(stmt->ThenId(), NO_REGISTERS);
1129 __ bind(&then_part);
1130 Visit(stmt->then_statement()); 1142 Visit(stmt->then_statement());
1131 __ jmp(&done); 1143 __ jmp(&done);
1132 1144
1145 __ bind(&else_part);
1146 SetStackHeight(if_stack_height);
1133 PrepareForBailoutForId(stmt->ElseId(), NO_REGISTERS); 1147 PrepareForBailoutForId(stmt->ElseId(), NO_REGISTERS);
1134 __ bind(&else_part);
1135 Visit(stmt->else_statement()); 1148 Visit(stmt->else_statement());
1136 } else { 1149 } else {
1137 VisitForControl(stmt->condition(), &then_part, &done, &then_part); 1150 VisitForControl(stmt->condition(), &then_part, &done, &then_part);
1151 __ bind(&then_part);
1138 PrepareForBailoutForId(stmt->ThenId(), NO_REGISTERS); 1152 PrepareForBailoutForId(stmt->ThenId(), NO_REGISTERS);
1139 __ bind(&then_part);
1140 Visit(stmt->then_statement()); 1153 Visit(stmt->then_statement());
1141 1154
1142 PrepareForBailoutForId(stmt->ElseId(), NO_REGISTERS); 1155 PrepareForBailoutForId(stmt->ElseId(), NO_REGISTERS);
1143 } 1156 }
1144 __ bind(&done); 1157 __ bind(&done);
1145 PrepareForBailoutForId(stmt->IfId(), NO_REGISTERS); 1158 PrepareForBailoutForId(stmt->IfId(), NO_REGISTERS);
1146 } 1159 }
1147 1160
1148 1161
1149 void FullCodeGenerator::VisitContinueStatement(ContinueStatement* stmt) { 1162 void FullCodeGenerator::VisitContinueStatement(ContinueStatement* stmt) {
1150 Comment cmnt(masm_, "[ ContinueStatement"); 1163 Comment cmnt(masm_, "[ ContinueStatement");
1151 SetStatementPosition(stmt); 1164 SetStatementPosition(stmt);
1152 NestedStatement* current = nesting_stack_; 1165 NestedStatement* current = nesting_stack_;
1166 StackHeightWrapper original_stack_height = CurrentStackHeight();
1153 int stack_depth = 0; 1167 int stack_depth = 0;
1154 int context_length = 0; 1168 int context_length = 0;
1155 // When continuing, we clobber the unpredictable value in the accumulator 1169 // When continuing, we clobber the unpredictable value in the accumulator
1156 // with one that's safe for GC. If we hit an exit from the try block of 1170 // with one that's safe for GC. If we hit an exit from the try block of
1157 // try...finally on our way out, we will unconditionally preserve the 1171 // try...finally on our way out, we will unconditionally preserve the
1158 // accumulator on the stack. 1172 // accumulator on the stack.
1159 ClearAccumulator(); 1173 ClearAccumulator();
1160 while (!current->IsContinueTarget(stmt->target())) { 1174 while (!current->IsContinueTarget(stmt->target())) {
1161 current = current->Exit(&stack_depth, &context_length); 1175 current = current->Exit(&stack_depth, &context_length);
1162 } 1176 }
1163 __ Drop(stack_depth); 1177 AsmDrop(stack_depth);
1164 if (context_length > 0) { 1178 if (context_length > 0) {
1165 while (context_length > 0) { 1179 while (context_length > 0) {
1166 LoadContextField(context_register(), Context::PREVIOUS_INDEX); 1180 LoadContextField(context_register(), Context::PREVIOUS_INDEX);
1167 --context_length; 1181 --context_length;
1168 } 1182 }
1169 StoreToFrameField(StandardFrameConstants::kContextOffset, 1183 StoreToFrameField(StandardFrameConstants::kContextOffset,
1170 context_register()); 1184 context_register());
1171 } 1185 }
1172 1186
1173 __ jmp(current->AsIteration()->continue_label()); 1187 __ jmp(current->AsIteration()->continue_label());
1188 SetStackHeight(original_stack_height);
1174 } 1189 }
1175 1190
1176 1191
1177 void FullCodeGenerator::VisitBreakStatement(BreakStatement* stmt) { 1192 void FullCodeGenerator::VisitBreakStatement(BreakStatement* stmt) {
1178 Comment cmnt(masm_, "[ BreakStatement"); 1193 Comment cmnt(masm_, "[ BreakStatement");
1179 SetStatementPosition(stmt); 1194 SetStatementPosition(stmt);
1180 NestedStatement* current = nesting_stack_; 1195 NestedStatement* current = nesting_stack_;
1196 StackHeightWrapper original_stack_height = CurrentStackHeight();
1181 int stack_depth = 0; 1197 int stack_depth = 0;
1182 int context_length = 0; 1198 int context_length = 0;
1183 // When breaking, we clobber the unpredictable value in the accumulator 1199 // When breaking, we clobber the unpredictable value in the accumulator
1184 // with one that's safe for GC. If we hit an exit from the try block of 1200 // with one that's safe for GC. If we hit an exit from the try block of
1185 // try...finally on our way out, we will unconditionally preserve the 1201 // try...finally on our way out, we will unconditionally preserve the
1186 // accumulator on the stack. 1202 // accumulator on the stack.
1187 ClearAccumulator(); 1203 ClearAccumulator();
1188 while (!current->IsBreakTarget(stmt->target())) { 1204 while (!current->IsBreakTarget(stmt->target())) {
1189 current = current->Exit(&stack_depth, &context_length); 1205 current = current->Exit(&stack_depth, &context_length);
1190 } 1206 }
1191 __ Drop(stack_depth); 1207 AsmDrop(stack_depth);
1192 if (context_length > 0) { 1208 if (context_length > 0) {
1193 while (context_length > 0) { 1209 while (context_length > 0) {
1194 LoadContextField(context_register(), Context::PREVIOUS_INDEX); 1210 LoadContextField(context_register(), Context::PREVIOUS_INDEX);
1195 --context_length; 1211 --context_length;
1196 } 1212 }
1197 StoreToFrameField(StandardFrameConstants::kContextOffset, 1213 StoreToFrameField(StandardFrameConstants::kContextOffset,
1198 context_register()); 1214 context_register());
1199 } 1215 }
1200 1216
1201 __ jmp(current->AsBreakable()->break_label()); 1217 __ jmp(current->AsBreakable()->break_label());
1218 SetStackHeight(original_stack_height);
1202 } 1219 }
1203 1220
1204 1221
1205 void FullCodeGenerator::EmitUnwindBeforeReturn() { 1222 void FullCodeGenerator::EmitUnwindBeforeReturn() {
1206 NestedStatement* current = nesting_stack_; 1223 NestedStatement* current = nesting_stack_;
1207 int stack_depth = 0; 1224 int stack_depth = 0;
1208 int context_length = 0; 1225 int context_length = 0;
1209 while (current != NULL) { 1226 while (current != NULL) {
1210 current = current->Exit(&stack_depth, &context_length); 1227 current = current->Exit(&stack_depth, &context_length);
1211 } 1228 }
1212 __ Drop(stack_depth); 1229 AsmDrop(stack_depth);
1213 } 1230 }
1214 1231
1215 1232
1216 void FullCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { 1233 void FullCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
1217 Comment cmnt(masm_, "[ ReturnStatement"); 1234 Comment cmnt(masm_, "[ ReturnStatement");
1218 SetStatementPosition(stmt); 1235 SetStatementPosition(stmt);
1219 Expression* expr = stmt->expression(); 1236 Expression* expr = stmt->expression();
1220 VisitForAccumulatorValue(expr); 1237 VisitForAccumulatorValue(expr);
1238 StackHeightWrapper previous_stack_height = CurrentStackHeight();
1221 EmitUnwindBeforeReturn(); 1239 EmitUnwindBeforeReturn();
1222 EmitReturnSequence(); 1240 EmitReturnSequence();
1241 // Reset the expected stack height
1242 SetStackHeight(previous_stack_height);
1223 } 1243 }
1224 1244
1225 1245
1226 void FullCodeGenerator::VisitWithStatement(WithStatement* stmt) { 1246 void FullCodeGenerator::VisitWithStatement(WithStatement* stmt) {
1227 Comment cmnt(masm_, "[ WithStatement"); 1247 Comment cmnt(masm_, "[ WithStatement");
1228 SetStatementPosition(stmt); 1248 SetStatementPosition(stmt);
1229 1249
1230 VisitForStackValue(stmt->expression()); 1250 VisitForStackValue(stmt->expression());
1231 PushFunctionArgumentForContextAllocation(); 1251 PushFunctionArgumentForContextAllocation();
1232 __ CallRuntime(Runtime::kHiddenPushWithContext, 2); 1252 AsmCallRuntime(Runtime::kHiddenPushWithContext, 2);
1233 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); 1253 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register());
1234 1254
1235 Scope* saved_scope = scope(); 1255 Scope* saved_scope = scope();
1236 scope_ = stmt->scope(); 1256 scope_ = stmt->scope();
1237 { WithOrCatch body(this); 1257 { WithOrCatch body(this);
1238 Visit(stmt->statement()); 1258 Visit(stmt->statement());
1239 } 1259 }
1240 scope_ = saved_scope; 1260 scope_ = saved_scope;
1241 1261
1242 // Pop context. 1262 // Pop context.
(...skipping 18 matching lines...) Expand all
1261 // possible to break on the condition. 1281 // possible to break on the condition.
1262 __ bind(loop_statement.continue_label()); 1282 __ bind(loop_statement.continue_label());
1263 PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS); 1283 PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS);
1264 SetExpressionPosition(stmt->cond()); 1284 SetExpressionPosition(stmt->cond());
1265 VisitForControl(stmt->cond(), 1285 VisitForControl(stmt->cond(),
1266 &book_keeping, 1286 &book_keeping,
1267 loop_statement.break_label(), 1287 loop_statement.break_label(),
1268 &book_keeping); 1288 &book_keeping);
1269 1289
1270 // Check stack before looping. 1290 // Check stack before looping.
1291 __ bind(&book_keeping);
1271 PrepareForBailoutForId(stmt->BackEdgeId(), NO_REGISTERS); 1292 PrepareForBailoutForId(stmt->BackEdgeId(), NO_REGISTERS);
1272 __ bind(&book_keeping);
1273 EmitBackEdgeBookkeeping(stmt, &body); 1293 EmitBackEdgeBookkeeping(stmt, &body);
1274 __ jmp(&body); 1294 __ jmp(&body);
1275 1295
1296 __ bind(loop_statement.break_label());
1276 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 1297 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1277 __ bind(loop_statement.break_label());
1278 decrement_loop_depth(); 1298 decrement_loop_depth();
1279 } 1299 }
1280 1300
1281 1301
1282 void FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) { 1302 void FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
1283 Comment cmnt(masm_, "[ WhileStatement"); 1303 Comment cmnt(masm_, "[ WhileStatement");
1284 Label test, body; 1304 Label test, body;
1285 1305
1286 Iteration loop_statement(this, stmt); 1306 Iteration loop_statement(this, stmt);
1287 increment_loop_depth(); 1307 increment_loop_depth();
1288 1308
1289 // Emit the test at the bottom of the loop. 1309 // Emit the test at the bottom of the loop.
1290 __ jmp(&test); 1310 __ jmp(&test);
1291 1311
1312 __ bind(&body);
1292 PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); 1313 PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS);
1293 __ bind(&body);
1294 Visit(stmt->body()); 1314 Visit(stmt->body());
1295 1315
1296 // Emit the statement position here as this is where the while 1316 // Emit the statement position here as this is where the while
1297 // statement code starts. 1317 // statement code starts.
1298 __ bind(loop_statement.continue_label()); 1318 __ bind(loop_statement.continue_label());
1299 SetStatementPosition(stmt); 1319 SetStatementPosition(stmt);
1300 1320
1301 // Check stack before looping. 1321 // Check stack before looping.
1302 EmitBackEdgeBookkeeping(stmt, &body); 1322 EmitBackEdgeBookkeeping(stmt, &body);
1303 1323
1304 __ bind(&test); 1324 __ bind(&test);
1305 VisitForControl(stmt->cond(), 1325 VisitForControl(stmt->cond(),
1306 &body, 1326 &body,
1307 loop_statement.break_label(), 1327 loop_statement.break_label(),
1308 loop_statement.break_label()); 1328 loop_statement.break_label());
1309 1329
1330 __ bind(loop_statement.break_label());
1310 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 1331 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1311 __ bind(loop_statement.break_label());
1312 decrement_loop_depth(); 1332 decrement_loop_depth();
1313 } 1333 }
1314 1334
1315 1335
1316 void FullCodeGenerator::VisitForStatement(ForStatement* stmt) { 1336 void FullCodeGenerator::VisitForStatement(ForStatement* stmt) {
1317 Comment cmnt(masm_, "[ ForStatement"); 1337 Comment cmnt(masm_, "[ ForStatement");
1318 Label test, body; 1338 Label test, body;
1319 1339
1320 Iteration loop_statement(this, stmt); 1340 Iteration loop_statement(this, stmt);
1321 1341
1322 // Set statement position for a break slot before entering the for-body. 1342 // Set statement position for a break slot before entering the for-body.
1323 SetStatementPosition(stmt); 1343 SetStatementPosition(stmt);
1324 1344
1325 if (stmt->init() != NULL) { 1345 if (stmt->init() != NULL) {
1326 Visit(stmt->init()); 1346 Visit(stmt->init());
1327 } 1347 }
1328 1348
1329 increment_loop_depth(); 1349 increment_loop_depth();
1330 // Emit the test at the bottom of the loop (even if empty). 1350 // Emit the test at the bottom of the loop (even if empty).
1331 __ jmp(&test); 1351 __ jmp(&test);
1332 1352
1353 __ bind(&body);
1333 PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); 1354 PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS);
1334 __ bind(&body);
1335 Visit(stmt->body()); 1355 Visit(stmt->body());
1336 1356
1357 __ bind(loop_statement.continue_label());
1337 PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS); 1358 PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS);
1338 __ bind(loop_statement.continue_label());
1339 if (stmt->next() != NULL) { 1359 if (stmt->next() != NULL) {
1340 Visit(stmt->next()); 1360 Visit(stmt->next());
1341 } 1361 }
1342 1362
1343 // Emit the statement position here as this is where the for 1363 // Emit the statement position here as this is where the for
1344 // statement code starts. 1364 // statement code starts.
1345 SetStatementPosition(stmt); 1365 SetStatementPosition(stmt);
1346 1366
1347 // Check stack before looping. 1367 // Check stack before looping.
1348 EmitBackEdgeBookkeeping(stmt, &body); 1368 EmitBackEdgeBookkeeping(stmt, &body);
1349 1369
1350 __ bind(&test); 1370 __ bind(&test);
1351 if (stmt->cond() != NULL) { 1371 if (stmt->cond() != NULL) {
1352 VisitForControl(stmt->cond(), 1372 VisitForControl(stmt->cond(),
1353 &body, 1373 &body,
1354 loop_statement.break_label(), 1374 loop_statement.break_label(),
1355 loop_statement.break_label()); 1375 loop_statement.break_label());
1356 } else { 1376 } else {
1357 __ jmp(&body); 1377 __ jmp(&body);
1358 } 1378 }
1359 1379
1380 __ bind(loop_statement.break_label());
1360 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 1381 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1361 __ bind(loop_statement.break_label());
1362 decrement_loop_depth(); 1382 decrement_loop_depth();
1363 } 1383 }
1364 1384
1365 1385
1366 void FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { 1386 void FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
1367 Comment cmnt(masm_, "[ TryCatchStatement"); 1387 Comment cmnt(masm_, "[ TryCatchStatement");
1368 SetStatementPosition(stmt); 1388 SetStatementPosition(stmt);
1369 // The try block adds a handler to the exception handler chain before 1389 // The try block adds a handler to the exception handler chain before
1370 // entering, and removes it again when exiting normally. If an exception 1390 // entering, and removes it again when exiting normally. If an exception
1371 // is thrown during execution of the try block, the handler is consumed 1391 // is thrown during execution of the try block, the handler is consumed
1372 // and control is passed to the catch block with the exception in the 1392 // and control is passed to the catch block with the exception in the
1373 // result register. 1393 // result register.
1374 1394
1375 Label try_entry, handler_entry, exit; 1395 Label try_entry, handler_entry, exit;
1376 __ jmp(&try_entry); 1396 __ jmp(&try_entry);
1377 __ bind(&handler_entry); 1397 __ bind(&handler_entry);
1378 handler_table()->set(stmt->index(), Smi::FromInt(handler_entry.pos())); 1398 handler_table()->set(stmt->index(), Smi::FromInt(handler_entry.pos()));
1379 // Exception handler code, the exception is in the result register. 1399 // Exception handler code, the exception is in the result register.
1380 // Extend the context before executing the catch block. 1400 // Extend the context before executing the catch block.
1381 { Comment cmnt(masm_, "[ Extend catch context"); 1401 { Comment cmnt(masm_, "[ Extend catch context");
1382 __ Push(stmt->variable()->name()); 1402 AsmPushHandle(stmt->variable()->name());
1383 __ Push(result_register()); 1403 AsmPush(result_register());
1384 PushFunctionArgumentForContextAllocation(); 1404 PushFunctionArgumentForContextAllocation();
1385 __ CallRuntime(Runtime::kHiddenPushCatchContext, 3); 1405 AsmCallRuntime(Runtime::kHiddenPushCatchContext, 3);
1386 StoreToFrameField(StandardFrameConstants::kContextOffset, 1406 StoreToFrameField(StandardFrameConstants::kContextOffset,
1387 context_register()); 1407 context_register());
1388 } 1408 }
1389 1409
1390 Scope* saved_scope = scope(); 1410 Scope* saved_scope = scope();
1391 scope_ = stmt->scope(); 1411 scope_ = stmt->scope();
1392 ASSERT(scope_->declarations()->is_empty()); 1412 ASSERT(scope_->declarations()->is_empty());
1393 { WithOrCatch catch_body(this); 1413 { WithOrCatch catch_body(this);
1394 Visit(stmt->catch_block()); 1414 Visit(stmt->catch_block());
1395 } 1415 }
1396 // Restore the context. 1416 // Restore the context.
1397 LoadContextField(context_register(), Context::PREVIOUS_INDEX); 1417 LoadContextField(context_register(), Context::PREVIOUS_INDEX);
1398 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); 1418 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register());
1399 scope_ = saved_scope; 1419 scope_ = saved_scope;
1400 __ jmp(&exit); 1420 __ jmp(&exit);
1401 1421
1402 // Try block code. Sets up the exception handler chain. 1422 // Try block code. Sets up the exception handler chain.
1403 __ bind(&try_entry); 1423 __ bind(&try_entry);
1404 __ PushTryHandler(StackHandler::CATCH, stmt->index()); 1424 AsmPushTryHandler(StackHandler::CATCH, stmt->index());
1405 { TryCatch try_body(this); 1425 { TryCatch try_body(this);
1406 Visit(stmt->try_block()); 1426 Visit(stmt->try_block());
1407 } 1427 }
1408 __ PopTryHandler(); 1428 AsmPopTryHandler();
1409 __ bind(&exit); 1429 __ bind(&exit);
1410 } 1430 }
1411 1431
1412 1432
1413 void FullCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) { 1433 void FullCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
1414 Comment cmnt(masm_, "[ TryFinallyStatement"); 1434 Comment cmnt(masm_, "[ TryFinallyStatement");
1415 SetStatementPosition(stmt); 1435 SetStatementPosition(stmt);
1416 // Try finally is compiled by setting up a try-handler on the stack while 1436 // Try finally is compiled by setting up a try-handler on the stack while
1417 // executing the try body, and removing it again afterwards. 1437 // executing the try body, and removing it again afterwards.
1418 // 1438 //
(...skipping 19 matching lines...) Expand all
1438 1458
1439 // Jump to try-handler setup and try-block code. 1459 // Jump to try-handler setup and try-block code.
1440 __ jmp(&try_entry); 1460 __ jmp(&try_entry);
1441 __ bind(&handler_entry); 1461 __ bind(&handler_entry);
1442 handler_table()->set(stmt->index(), Smi::FromInt(handler_entry.pos())); 1462 handler_table()->set(stmt->index(), Smi::FromInt(handler_entry.pos()));
1443 // Exception handler code. This code is only executed when an exception 1463 // Exception handler code. This code is only executed when an exception
1444 // is thrown. The exception is in the result register, and must be 1464 // is thrown. The exception is in the result register, and must be
1445 // preserved by the finally block. Call the finally block and then 1465 // preserved by the finally block. Call the finally block and then
1446 // rethrow the exception if it returns. 1466 // rethrow the exception if it returns.
1447 __ Call(&finally_entry); 1467 __ Call(&finally_entry);
1448 __ Push(result_register()); 1468 AsmPush(result_register());
1449 __ CallRuntime(Runtime::kHiddenReThrow, 1); 1469 AsmCallRuntime(Runtime::kHiddenReThrow, 1);
1450 1470
1451 // Finally block implementation. 1471 // Finally block implementation.
1452 __ bind(&finally_entry); 1472 __ bind(&finally_entry);
1473 // The return address is on the stack -> update the height
1474 UpdateStackHeight(1);
1453 EnterFinallyBlock(); 1475 EnterFinallyBlock();
1454 { Finally finally_body(this); 1476 { Finally finally_body(this);
1455 Visit(stmt->finally_block()); 1477 Visit(stmt->finally_block());
1456 } 1478 }
1457 ExitFinallyBlock(); // Return to the calling code. 1479 ExitFinallyBlock(); // Return to the calling code.
1458 1480
1459 // Set up try handler. 1481 // Set up try handler.
1460 __ bind(&try_entry); 1482 __ bind(&try_entry);
1461 __ PushTryHandler(StackHandler::FINALLY, stmt->index()); 1483 AsmPushTryHandler(StackHandler::FINALLY, stmt->index());
1462 { TryFinally try_body(this, &finally_entry); 1484 { TryFinally try_body(this, &finally_entry);
1463 Visit(stmt->try_block()); 1485 Visit(stmt->try_block());
1464 } 1486 }
1465 __ PopTryHandler(); 1487 AsmPopTryHandler();
1466 // Execute the finally block on the way out. Clobber the unpredictable 1488 // Execute the finally block on the way out. Clobber the unpredictable
1467 // value in the result register with one that's safe for GC because the 1489 // value in the result register with one that's safe for GC because the
1468 // finally block will unconditionally preserve the result register on the 1490 // finally block will unconditionally preserve the result register on the
1469 // stack. 1491 // stack.
1470 ClearAccumulator(); 1492 ClearAccumulator();
1471 __ Call(&finally_entry); 1493 __ Call(&finally_entry);
1472 } 1494 }
1473 1495
1474 1496
1475 void FullCodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) { 1497 void FullCodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) {
1476 Comment cmnt(masm_, "[ DebuggerStatement"); 1498 Comment cmnt(masm_, "[ DebuggerStatement");
1477 SetStatementPosition(stmt); 1499 SetStatementPosition(stmt);
1478 1500
1479 __ DebugBreak(); 1501 __ DebugBreak();
1480 // Ignore the return value. 1502 // Ignore the return value.
1481 } 1503 }
1482 1504
1483 1505
1484 void FullCodeGenerator::VisitCaseClause(CaseClause* clause) { 1506 void FullCodeGenerator::VisitCaseClause(CaseClause* clause) {
1485 UNREACHABLE(); 1507 UNREACHABLE();
1486 } 1508 }
1487 1509
1488 1510
1489 void FullCodeGenerator::VisitConditional(Conditional* expr) { 1511 void FullCodeGenerator::VisitConditional(Conditional* expr) {
1490 Comment cmnt(masm_, "[ Conditional"); 1512 Comment cmnt(masm_, "[ Conditional");
1491 Label true_case, false_case, done; 1513 Label true_case, false_case, done;
1492 VisitForControl(expr->condition(), &true_case, &false_case, &true_case); 1514 VisitForControl(expr->condition(), &true_case, &false_case, &true_case);
1515 StackHeightWrapper if_stack_height = CurrentStackHeight();
1493 1516
1517 __ bind(&true_case);
1494 PrepareForBailoutForId(expr->ThenId(), NO_REGISTERS); 1518 PrepareForBailoutForId(expr->ThenId(), NO_REGISTERS);
1495 __ bind(&true_case);
1496 SetExpressionPosition(expr->then_expression()); 1519 SetExpressionPosition(expr->then_expression());
1497 if (context()->IsTest()) { 1520 if (context()->IsTest()) {
1498 const TestContext* for_test = TestContext::cast(context()); 1521 const TestContext* for_test = TestContext::cast(context());
1499 VisitForControl(expr->then_expression(), 1522 VisitForControl(expr->then_expression(),
1500 for_test->true_label(), 1523 for_test->true_label(),
1501 for_test->false_label(), 1524 for_test->false_label(),
1502 NULL); 1525 NULL);
1503 } else { 1526 } else {
1504 VisitInDuplicateContext(expr->then_expression()); 1527 VisitInDuplicateContext(expr->then_expression());
1505 __ jmp(&done); 1528 __ jmp(&done);
1506 } 1529 }
1507 1530
1531 __ bind(&false_case);
1532 SetStackHeight(if_stack_height);
1508 PrepareForBailoutForId(expr->ElseId(), NO_REGISTERS); 1533 PrepareForBailoutForId(expr->ElseId(), NO_REGISTERS);
1509 __ bind(&false_case);
1510 SetExpressionPosition(expr->else_expression()); 1534 SetExpressionPosition(expr->else_expression());
1511 VisitInDuplicateContext(expr->else_expression()); 1535 VisitInDuplicateContext(expr->else_expression());
1512 // If control flow falls through Visit, merge it with true case here. 1536 // If control flow falls through Visit, merge it with true case here.
1513 if (!context()->IsTest()) { 1537 if (!context()->IsTest()) {
1514 __ bind(&done); 1538 __ bind(&done);
1515 } 1539 }
1516 } 1540 }
1517 1541
1518 1542
1519 void FullCodeGenerator::VisitLiteral(Literal* expr) { 1543 void FullCodeGenerator::VisitLiteral(Literal* expr) {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1565 int parameters = fun->shared()->formal_parameter_count(); 1589 int parameters = fun->shared()->formal_parameter_count();
1566 shared->set_formal_parameter_count(parameters); 1590 shared->set_formal_parameter_count(parameters);
1567 1591
1568 EmitNewClosure(shared, false); 1592 EmitNewClosure(shared, false);
1569 } 1593 }
1570 1594
1571 1595
1572 void FullCodeGenerator::VisitThrow(Throw* expr) { 1596 void FullCodeGenerator::VisitThrow(Throw* expr) {
1573 Comment cmnt(masm_, "[ Throw"); 1597 Comment cmnt(masm_, "[ Throw");
1574 VisitForStackValue(expr->exception()); 1598 VisitForStackValue(expr->exception());
1575 __ CallRuntime(Runtime::kHiddenThrow, 1); 1599 AsmCallRuntime(Runtime::kHiddenThrow, 1);
1576 // Never returns here. 1600 // Never returns here. Update stack height so that we do not confuse the
1601 // stack height checker.
1602 if (context() != NULL && !context()->IsEffect()) {
1603 UpdateStackHeight(1);
1604 }
1577 } 1605 }
1578 1606
1579 1607
1580 FullCodeGenerator::NestedStatement* FullCodeGenerator::TryCatch::Exit( 1608 FullCodeGenerator::NestedStatement* FullCodeGenerator::TryCatch::Exit(
1581 int* stack_depth, 1609 int* stack_depth,
1582 int* context_length) { 1610 int* context_length) {
1583 // The macros used here must preserve the result register. 1611 // The macros used here must preserve the result register.
1584 __ Drop(*stack_depth); 1612 codegen()->AsmDrop(*stack_depth);
1585 __ PopTryHandler(); 1613 codegen()->AsmPopTryHandler();
1586 *stack_depth = 0; 1614 *stack_depth = 0;
1587 return previous_; 1615 return previous_;
1588 } 1616 }
1589 1617
1590 1618
1591 bool FullCodeGenerator::TryLiteralCompare(CompareOperation* expr) { 1619 bool FullCodeGenerator::TryLiteralCompare(CompareOperation* expr) {
1592 Expression* sub_expr; 1620 Expression* sub_expr;
1593 Handle<String> check; 1621 Handle<String> check;
1594 if (expr->IsLiteralCompareTypeof(&sub_expr, &check)) { 1622 if (expr->IsLiteralCompareTypeof(&sub_expr, &check)) {
1595 EmitLiteralCompareTypeof(expr, sub_expr, check); 1623 EmitLiteralCompareTypeof(expr, sub_expr, check);
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
1697 } 1725 }
1698 return true; 1726 return true;
1699 } 1727 }
1700 #endif // DEBUG 1728 #endif // DEBUG
1701 1729
1702 1730
1703 #undef __ 1731 #undef __
1704 1732
1705 1733
1706 } } // namespace v8::internal 1734 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/full-codegen.h ('k') | src/hydrogen.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698