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

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

Issue 6529055: [Isolates] Merge crankshaft (r5922 from bleeding_edge). (Closed)
Patch Set: Win32 port Created 9 years, 10 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
« no previous file with comments | « src/full-codegen.h ('k') | src/global-handles.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2009 the V8 project authors. All rights reserved. 1 // Copyright 2010 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
11 // with the distribution. 11 // with the distribution.
(...skipping 10 matching lines...) Expand all
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #include "v8.h" 28 #include "v8.h"
29 29
30 #include "codegen-inl.h" 30 #include "codegen-inl.h"
31 #include "compiler.h" 31 #include "compiler.h"
32 #include "debug.h"
32 #include "full-codegen.h" 33 #include "full-codegen.h"
34 #include "liveedit.h"
33 #include "macro-assembler.h" 35 #include "macro-assembler.h"
36 #include "prettyprinter.h"
34 #include "scopes.h" 37 #include "scopes.h"
35 #include "stub-cache.h" 38 #include "stub-cache.h"
36 #include "debug.h"
37 #include "liveedit.h"
38 39
39 namespace v8 { 40 namespace v8 {
40 namespace internal { 41 namespace internal {
41 42
42 void BreakableStatementChecker::Check(Statement* stmt) { 43 void BreakableStatementChecker::Check(Statement* stmt) {
43 Visit(stmt); 44 Visit(stmt);
44 } 45 }
45 46
46 47
47 void BreakableStatementChecker::Check(Expression* expr) { 48 void BreakableStatementChecker::Check(Expression* expr) {
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 160
160 void BreakableStatementChecker::VisitSharedFunctionInfoLiteral( 161 void BreakableStatementChecker::VisitSharedFunctionInfoLiteral(
161 SharedFunctionInfoLiteral* expr) { 162 SharedFunctionInfoLiteral* expr) {
162 } 163 }
163 164
164 165
165 void BreakableStatementChecker::VisitConditional(Conditional* expr) { 166 void BreakableStatementChecker::VisitConditional(Conditional* expr) {
166 } 167 }
167 168
168 169
169 void BreakableStatementChecker::VisitSlot(Slot* expr) {
170 }
171
172
173 void BreakableStatementChecker::VisitVariableProxy(VariableProxy* expr) { 170 void BreakableStatementChecker::VisitVariableProxy(VariableProxy* expr) {
174 } 171 }
175 172
176 173
177 void BreakableStatementChecker::VisitLiteral(Literal* expr) { 174 void BreakableStatementChecker::VisitLiteral(Literal* expr) {
178 } 175 }
179 176
180 177
181 void BreakableStatementChecker::VisitRegExpLiteral(RegExpLiteral* expr) { 178 void BreakableStatementChecker::VisitRegExpLiteral(RegExpLiteral* expr) {
182 } 179 }
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 273
277 274
278 #define __ ACCESS_MASM(masm()) 275 #define __ ACCESS_MASM(masm())
279 276
280 bool FullCodeGenerator::MakeCode(CompilationInfo* info) { 277 bool FullCodeGenerator::MakeCode(CompilationInfo* info) {
281 Handle<Script> script = info->script(); 278 Handle<Script> script = info->script();
282 if (!script->IsUndefined() && !script->source()->IsUndefined()) { 279 if (!script->IsUndefined() && !script->source()->IsUndefined()) {
283 int len = String::cast(script->source())->length(); 280 int len = String::cast(script->source())->length();
284 COUNTERS->total_full_codegen_source_size()->Increment(len); 281 COUNTERS->total_full_codegen_source_size()->Increment(len);
285 } 282 }
283 if (FLAG_trace_codegen) {
284 PrintF("Full Compiler - ");
285 }
286 CodeGenerator::MakeCodePrologue(info); 286 CodeGenerator::MakeCodePrologue(info);
287 const int kInitialBufferSize = 4 * KB; 287 const int kInitialBufferSize = 4 * KB;
288 MacroAssembler masm(NULL, kInitialBufferSize); 288 MacroAssembler masm(NULL, kInitialBufferSize);
289 289
290 FullCodeGenerator cgen(&masm); 290 FullCodeGenerator cgen(&masm);
291 cgen.Generate(info); 291 cgen.Generate(info);
292 if (cgen.HasStackOverflow()) { 292 if (cgen.HasStackOverflow()) {
293 ASSERT(!Isolate::Current()->has_pending_exception()); 293 ASSERT(!Isolate::Current()->has_pending_exception());
294 return false; 294 return false;
295 } 295 }
296 unsigned table_offset = cgen.EmitStackCheckTable();
296 297
297 Code::Flags flags = Code::ComputeFlags(Code::FUNCTION, NOT_IN_LOOP); 298 Code::Flags flags = Code::ComputeFlags(Code::FUNCTION, NOT_IN_LOOP);
298 Handle<Code> code = CodeGenerator::MakeCodeEpilogue(&masm, flags, info); 299 Handle<Code> code = CodeGenerator::MakeCodeEpilogue(&masm, flags, info);
300 code->set_optimizable(info->IsOptimizable());
301 cgen.PopulateDeoptimizationData(code);
302 code->set_has_deoptimization_support(info->HasDeoptimizationSupport());
303 code->set_allow_osr_at_loop_nesting_level(0);
304 code->set_stack_check_table_start(table_offset);
305 CodeGenerator::PrintCode(code, info);
299 info->SetCode(code); // may be an empty handle. 306 info->SetCode(code); // may be an empty handle.
300 return !code.is_null(); 307 return !code.is_null();
301 } 308 }
302 309
303 310
311 unsigned FullCodeGenerator::EmitStackCheckTable() {
312 // The stack check table consists of a length (in number of entries)
313 // field, and then a sequence of entries. Each entry is a pair of AST id
314 // and code-relative pc offset.
315 masm()->Align(kIntSize);
316 masm()->RecordComment("[ Stack check table");
317 unsigned offset = masm()->pc_offset();
318 unsigned length = stack_checks_.length();
319 __ dd(length);
320 for (unsigned i = 0; i < length; ++i) {
321 __ dd(stack_checks_[i].id);
322 __ dd(stack_checks_[i].pc_and_state);
323 }
324 masm()->RecordComment("]");
325 return offset;
326 }
327
328
329 void FullCodeGenerator::PopulateDeoptimizationData(Handle<Code> code) {
330 // Fill in the deoptimization information.
331 ASSERT(info_->HasDeoptimizationSupport() || bailout_entries_.is_empty());
332 if (!info_->HasDeoptimizationSupport()) return;
333 int length = bailout_entries_.length();
334 Handle<DeoptimizationOutputData> data =
335 Isolate::Current()->factory()->
336 NewDeoptimizationOutputData(length, TENURED);
337 for (int i = 0; i < length; i++) {
338 data->SetAstId(i, Smi::FromInt(bailout_entries_[i].id));
339 data->SetPcAndState(i, Smi::FromInt(bailout_entries_[i].pc_and_state));
340 }
341 code->set_deoptimization_data(*data);
342 }
343
344
345 void FullCodeGenerator::PrepareForBailout(AstNode* node, State state) {
346 PrepareForBailoutForId(node->id(), state);
347 }
348
349
350 void FullCodeGenerator::RecordJSReturnSite(Call* call) {
351 // We record the offset of the function return so we can rebuild the frame
352 // if the function was inlined, i.e., this is the return address in the
353 // inlined function's frame.
354 //
355 // The state is ignored. We defensively set it to TOS_REG, which is the
356 // real state of the unoptimized code at the return site.
357 PrepareForBailoutForId(call->ReturnId(), TOS_REG);
358 #ifdef DEBUG
359 // In debug builds, mark the return so we can verify that this function
360 // was called.
361 ASSERT(!call->return_is_recorded_);
362 call->return_is_recorded_ = true;
363 #endif
364 }
365
366
367 void FullCodeGenerator::PrepareForBailoutForId(int id, State state) {
368 // There's no need to prepare this code for bailouts from already optimized
369 // code or code that can't be optimized.
370 if (!FLAG_deopt || !info_->HasDeoptimizationSupport()) return;
371 unsigned pc_and_state =
372 StateField::encode(state) | PcField::encode(masm_->pc_offset());
373 BailoutEntry entry = { id, pc_and_state };
374 #ifdef DEBUG
375 // Assert that we don't have multiple bailout entries for the same node.
376 for (int i = 0; i < bailout_entries_.length(); i++) {
377 if (bailout_entries_.at(i).id == entry.id) {
378 AstPrinter printer;
379 PrintF("%s", printer.PrintProgram(info_->function()));
380 UNREACHABLE();
381 }
382 }
383 #endif // DEBUG
384 bailout_entries_.Add(entry);
385 }
386
387
388 void FullCodeGenerator::RecordStackCheck(int ast_id) {
389 // The pc offset does not need to be encoded and packed together with a
390 // state.
391 BailoutEntry entry = { ast_id, masm_->pc_offset() };
392 stack_checks_.Add(entry);
393 }
394
395
304 int FullCodeGenerator::SlotOffset(Slot* slot) { 396 int FullCodeGenerator::SlotOffset(Slot* slot) {
305 ASSERT(slot != NULL); 397 ASSERT(slot != NULL);
306 // Offset is negative because higher indexes are at lower addresses. 398 // Offset is negative because higher indexes are at lower addresses.
307 int offset = -slot->index() * kPointerSize; 399 int offset = -slot->index() * kPointerSize;
308 // Adjust by a (parameter or local) base offset. 400 // Adjust by a (parameter or local) base offset.
309 switch (slot->type()) { 401 switch (slot->type()) {
310 case Slot::PARAMETER: 402 case Slot::PARAMETER:
311 offset += (scope()->num_parameters() + 1) * kPointerSize; 403 offset += (scope()->num_parameters() + 1) * kPointerSize;
312 break; 404 break;
313 case Slot::LOCAL: 405 case Slot::LOCAL:
(...skipping 14 matching lines...) Expand all
328 if (FLAG_always_inline_smi_code) return true; 420 if (FLAG_always_inline_smi_code) return true;
329 return loop_depth_ > 0; 421 return loop_depth_ > 0;
330 } 422 }
331 423
332 424
333 void FullCodeGenerator::EffectContext::Plug(Register reg) const { 425 void FullCodeGenerator::EffectContext::Plug(Register reg) const {
334 } 426 }
335 427
336 428
337 void FullCodeGenerator::AccumulatorValueContext::Plug(Register reg) const { 429 void FullCodeGenerator::AccumulatorValueContext::Plug(Register reg) const {
338 // Move value into place.
339 __ Move(result_register(), reg); 430 __ Move(result_register(), reg);
340 } 431 }
341 432
342 433
343 void FullCodeGenerator::StackValueContext::Plug(Register reg) const { 434 void FullCodeGenerator::StackValueContext::Plug(Register reg) const {
344 // Move value into place.
345 __ push(reg); 435 __ push(reg);
346 } 436 }
347 437
348 438
349 void FullCodeGenerator::TestContext::Plug(Register reg) const { 439 void FullCodeGenerator::TestContext::Plug(Register reg) const {
350 // For simplicity we always test the accumulator register. 440 // For simplicity we always test the accumulator register.
351 __ Move(result_register(), reg); 441 __ Move(result_register(), reg);
442 codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
352 codegen()->DoTest(true_label_, false_label_, fall_through_); 443 codegen()->DoTest(true_label_, false_label_, fall_through_);
353 } 444 }
354 445
355 446
356 void FullCodeGenerator::EffectContext::PlugTOS() const { 447 void FullCodeGenerator::EffectContext::PlugTOS() const {
357 __ Drop(1); 448 __ Drop(1);
358 } 449 }
359 450
360 451
361 void FullCodeGenerator::AccumulatorValueContext::PlugTOS() const { 452 void FullCodeGenerator::AccumulatorValueContext::PlugTOS() const {
362 __ pop(result_register()); 453 __ pop(result_register());
363 } 454 }
364 455
365 456
366 void FullCodeGenerator::StackValueContext::PlugTOS() const { 457 void FullCodeGenerator::StackValueContext::PlugTOS() const {
367 } 458 }
368 459
369 460
370 void FullCodeGenerator::TestContext::PlugTOS() const { 461 void FullCodeGenerator::TestContext::PlugTOS() const {
371 // For simplicity we always test the accumulator register. 462 // For simplicity we always test the accumulator register.
372 __ pop(result_register()); 463 __ pop(result_register());
464 codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
373 codegen()->DoTest(true_label_, false_label_, fall_through_); 465 codegen()->DoTest(true_label_, false_label_, fall_through_);
374 } 466 }
375 467
376 468
377 void FullCodeGenerator::EffectContext::PrepareTest( 469 void FullCodeGenerator::EffectContext::PrepareTest(
378 Label* materialize_true, 470 Label* materialize_true,
379 Label* materialize_false, 471 Label* materialize_false,
380 Label** if_true, 472 Label** if_true,
381 Label** if_false, 473 Label** if_false,
382 Label** fall_through) const { 474 Label** fall_through) const {
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
607 OverwriteMode mode = NO_OVERWRITE; 699 OverwriteMode mode = NO_OVERWRITE;
608 if (left->ResultOverwriteAllowed()) { 700 if (left->ResultOverwriteAllowed()) {
609 mode = OVERWRITE_LEFT; 701 mode = OVERWRITE_LEFT;
610 } else if (right->ResultOverwriteAllowed()) { 702 } else if (right->ResultOverwriteAllowed()) {
611 mode = OVERWRITE_RIGHT; 703 mode = OVERWRITE_RIGHT;
612 } 704 }
613 705
614 switch (op) { 706 switch (op) {
615 case Token::COMMA: 707 case Token::COMMA:
616 VisitForEffect(left); 708 VisitForEffect(left);
617 Visit(right); 709 if (context()->IsTest()) ForwardBailoutToChild(expr);
710 context()->HandleExpression(right);
618 break; 711 break;
619 712
620 case Token::OR: 713 case Token::OR:
621 case Token::AND: 714 case Token::AND:
622 EmitLogicalOperation(expr); 715 EmitLogicalOperation(expr);
623 break; 716 break;
624 717
625 case Token::ADD: 718 case Token::ADD:
626 case Token::SUB: 719 case Token::SUB:
627 case Token::DIV: 720 case Token::DIV:
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
663 } 756 }
664 } 757 }
665 758
666 759
667 void FullCodeGenerator::EmitLogicalOperation(BinaryOperation* expr) { 760 void FullCodeGenerator::EmitLogicalOperation(BinaryOperation* expr) {
668 Label eval_right, done; 761 Label eval_right, done;
669 762
670 context()->EmitLogicalLeft(expr, &eval_right, &done); 763 context()->EmitLogicalLeft(expr, &eval_right, &done);
671 764
672 __ bind(&eval_right); 765 __ bind(&eval_right);
673 Visit(expr->right()); 766 if (context()->IsTest()) ForwardBailoutToChild(expr);
767 context()->HandleExpression(expr->right());
674 768
675 __ bind(&done); 769 __ bind(&done);
676 } 770 }
677 771
678 772
679 void FullCodeGenerator::EffectContext::EmitLogicalLeft(BinaryOperation* expr, 773 void FullCodeGenerator::EffectContext::EmitLogicalLeft(BinaryOperation* expr,
680 Label* eval_right, 774 Label* eval_right,
681 Label* done) const { 775 Label* done) const {
682 if (expr->op() == Token::OR) { 776 if (expr->op() == Token::OR) {
683 codegen()->VisitForControl(expr->left(), done, eval_right, eval_right); 777 codegen()->VisitForControl(expr->left(), done, eval_right, eval_right);
684 } else { 778 } else {
685 ASSERT(expr->op() == Token::AND); 779 ASSERT(expr->op() == Token::AND);
686 codegen()->VisitForControl(expr->left(), eval_right, done, eval_right); 780 codegen()->VisitForControl(expr->left(), eval_right, done, eval_right);
687 } 781 }
688 } 782 }
689 783
690 784
691 void FullCodeGenerator::AccumulatorValueContext::EmitLogicalLeft( 785 void FullCodeGenerator::AccumulatorValueContext::EmitLogicalLeft(
692 BinaryOperation* expr, 786 BinaryOperation* expr,
693 Label* eval_right, 787 Label* eval_right,
694 Label* done) const { 788 Label* done) const {
695 codegen()->Visit(expr->left()); 789 HandleExpression(expr->left());
696 // We want the value in the accumulator for the test, and on the stack in case 790 // We want the value in the accumulator for the test, and on the stack in case
697 // we need it. 791 // we need it.
698 __ push(result_register()); 792 __ push(result_register());
699 Label discard, restore; 793 Label discard, restore;
700 if (expr->op() == Token::OR) { 794 if (expr->op() == Token::OR) {
795 codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
701 codegen()->DoTest(&restore, &discard, &restore); 796 codegen()->DoTest(&restore, &discard, &restore);
702 } else { 797 } else {
703 ASSERT(expr->op() == Token::AND); 798 ASSERT(expr->op() == Token::AND);
799 codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
704 codegen()->DoTest(&discard, &restore, &restore); 800 codegen()->DoTest(&discard, &restore, &restore);
705 } 801 }
706 __ bind(&restore); 802 __ bind(&restore);
707 __ pop(result_register()); 803 __ pop(result_register());
708 __ jmp(done); 804 __ jmp(done);
709 __ bind(&discard); 805 __ bind(&discard);
710 __ Drop(1); 806 __ Drop(1);
711 } 807 }
712 808
713 809
714 void FullCodeGenerator::StackValueContext::EmitLogicalLeft( 810 void FullCodeGenerator::StackValueContext::EmitLogicalLeft(
715 BinaryOperation* expr, 811 BinaryOperation* expr,
716 Label* eval_right, 812 Label* eval_right,
717 Label* done) const { 813 Label* done) const {
718 codegen()->VisitForAccumulatorValue(expr->left()); 814 codegen()->VisitForAccumulatorValue(expr->left());
719 // We want the value in the accumulator for the test, and on the stack in case 815 // We want the value in the accumulator for the test, and on the stack in case
720 // we need it. 816 // we need it.
721 __ push(result_register()); 817 __ push(result_register());
722 Label discard; 818 Label discard;
723 if (expr->op() == Token::OR) { 819 if (expr->op() == Token::OR) {
820 codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
724 codegen()->DoTest(done, &discard, &discard); 821 codegen()->DoTest(done, &discard, &discard);
725 } else { 822 } else {
726 ASSERT(expr->op() == Token::AND); 823 ASSERT(expr->op() == Token::AND);
824 codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
727 codegen()->DoTest(&discard, done, &discard); 825 codegen()->DoTest(&discard, done, &discard);
728 } 826 }
729 __ bind(&discard); 827 __ bind(&discard);
730 __ Drop(1); 828 __ Drop(1);
731 } 829 }
732 830
733 831
734 void FullCodeGenerator::TestContext::EmitLogicalLeft(BinaryOperation* expr, 832 void FullCodeGenerator::TestContext::EmitLogicalLeft(BinaryOperation* expr,
735 Label* eval_right, 833 Label* eval_right,
736 Label* done) const { 834 Label* done) const {
737 if (expr->op() == Token::OR) { 835 if (expr->op() == Token::OR) {
738 codegen()->VisitForControl(expr->left(), 836 codegen()->VisitForControl(expr->left(),
739 true_label_, eval_right, eval_right); 837 true_label_, eval_right, eval_right);
740 } else { 838 } else {
741 ASSERT(expr->op() == Token::AND); 839 ASSERT(expr->op() == Token::AND);
742 codegen()->VisitForControl(expr->left(), 840 codegen()->VisitForControl(expr->left(),
743 eval_right, false_label_, eval_right); 841 eval_right, false_label_, eval_right);
744 } 842 }
745 } 843 }
746 844
747 845
846 void FullCodeGenerator::ForwardBailoutToChild(Expression* expr) {
847 if (!info_->HasDeoptimizationSupport()) return;
848 ASSERT(context()->IsTest());
849 ASSERT(expr == forward_bailout_stack_->expr());
850 forward_bailout_pending_ = forward_bailout_stack_;
851 }
852
853
854 void FullCodeGenerator::EffectContext::HandleExpression(
855 Expression* expr) const {
856 codegen()->HandleInNonTestContext(expr, NO_REGISTERS);
857 }
858
859
860 void FullCodeGenerator::AccumulatorValueContext::HandleExpression(
861 Expression* expr) const {
862 codegen()->HandleInNonTestContext(expr, TOS_REG);
863 }
864
865
866 void FullCodeGenerator::StackValueContext::HandleExpression(
867 Expression* expr) const {
868 codegen()->HandleInNonTestContext(expr, NO_REGISTERS);
869 }
870
871
872 void FullCodeGenerator::TestContext::HandleExpression(Expression* expr) const {
873 codegen()->VisitInTestContext(expr);
874 }
875
876
877 void FullCodeGenerator::HandleInNonTestContext(Expression* expr, State state) {
878 ASSERT(forward_bailout_pending_ == NULL);
879 AstVisitor::Visit(expr);
880 PrepareForBailout(expr, state);
881 // Forwarding bailouts to children is a one shot operation. It
882 // should have been processed at this point.
883 ASSERT(forward_bailout_pending_ == NULL);
884 }
885
886
887 void FullCodeGenerator::VisitInTestContext(Expression* expr) {
888 ForwardBailoutStack stack(expr, forward_bailout_pending_);
889 ForwardBailoutStack* saved = forward_bailout_stack_;
890 forward_bailout_pending_ = NULL;
891 forward_bailout_stack_ = &stack;
892 AstVisitor::Visit(expr);
893 forward_bailout_stack_ = saved;
894 }
895
896
748 void FullCodeGenerator::VisitBlock(Block* stmt) { 897 void FullCodeGenerator::VisitBlock(Block* stmt) {
749 Comment cmnt(masm_, "[ Block"); 898 Comment cmnt(masm_, "[ Block");
750 Breakable nested_statement(this, stmt); 899 Breakable nested_statement(this, stmt);
751 SetStatementPosition(stmt); 900 SetStatementPosition(stmt);
901
902 PrepareForBailoutForId(stmt->EntryId(), TOS_REG);
752 VisitStatements(stmt->statements()); 903 VisitStatements(stmt->statements());
753 __ bind(nested_statement.break_target()); 904 __ bind(nested_statement.break_target());
905 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
754 } 906 }
755 907
756 908
757 void FullCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) { 909 void FullCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) {
758 Comment cmnt(masm_, "[ ExpressionStatement"); 910 Comment cmnt(masm_, "[ ExpressionStatement");
759 SetStatementPosition(stmt); 911 SetStatementPosition(stmt);
760 VisitForEffect(stmt->expression()); 912 VisitForEffect(stmt->expression());
761 } 913 }
762 914
763 915
(...skipping 15 matching lines...) Expand all
779 __ jmp(&done); 931 __ jmp(&done);
780 932
781 __ bind(&else_part); 933 __ bind(&else_part);
782 Visit(stmt->else_statement()); 934 Visit(stmt->else_statement());
783 } else { 935 } else {
784 VisitForControl(stmt->condition(), &then_part, &done, &then_part); 936 VisitForControl(stmt->condition(), &then_part, &done, &then_part);
785 __ bind(&then_part); 937 __ bind(&then_part);
786 Visit(stmt->then_statement()); 938 Visit(stmt->then_statement());
787 } 939 }
788 __ bind(&done); 940 __ bind(&done);
941 PrepareForBailoutForId(stmt->id(), NO_REGISTERS);
789 } 942 }
790 943
791 944
792 void FullCodeGenerator::VisitContinueStatement(ContinueStatement* stmt) { 945 void FullCodeGenerator::VisitContinueStatement(ContinueStatement* stmt) {
793 Comment cmnt(masm_, "[ ContinueStatement"); 946 Comment cmnt(masm_, "[ ContinueStatement");
794 SetStatementPosition(stmt); 947 SetStatementPosition(stmt);
795 NestedStatement* current = nesting_stack_; 948 NestedStatement* current = nesting_stack_;
796 int stack_depth = 0; 949 int stack_depth = 0;
797 while (!current->IsContinueTarget(stmt->target())) { 950 while (!current->IsContinueTarget(stmt->target())) {
798 stack_depth = current->Exit(stack_depth); 951 stack_depth = current->Exit(stack_depth);
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
865 // Pop context. 1018 // Pop context.
866 LoadContextField(context_register(), Context::PREVIOUS_INDEX); 1019 LoadContextField(context_register(), Context::PREVIOUS_INDEX);
867 // Update local stack frame context field. 1020 // Update local stack frame context field.
868 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); 1021 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register());
869 } 1022 }
870 1023
871 1024
872 void FullCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) { 1025 void FullCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) {
873 Comment cmnt(masm_, "[ DoWhileStatement"); 1026 Comment cmnt(masm_, "[ DoWhileStatement");
874 SetStatementPosition(stmt); 1027 SetStatementPosition(stmt);
875 Label body, stack_limit_hit, stack_check_success, done; 1028 Label body, stack_check;
876 1029
877 Iteration loop_statement(this, stmt); 1030 Iteration loop_statement(this, stmt);
878 increment_loop_depth(); 1031 increment_loop_depth();
879 1032
880 __ bind(&body); 1033 __ bind(&body);
881 Visit(stmt->body()); 1034 Visit(stmt->body());
882 1035
883 // Check stack before looping.
884 __ bind(loop_statement.continue_target());
885 __ StackLimitCheck(&stack_limit_hit);
886 __ bind(&stack_check_success);
887
888 // Record the position of the do while condition and make sure it is 1036 // Record the position of the do while condition and make sure it is
889 // possible to break on the condition. 1037 // possible to break on the condition.
1038 __ bind(loop_statement.continue_target());
1039 PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS);
890 SetExpressionPosition(stmt->cond(), stmt->condition_position()); 1040 SetExpressionPosition(stmt->cond(), stmt->condition_position());
891 VisitForControl(stmt->cond(), 1041 VisitForControl(stmt->cond(),
1042 &stack_check,
1043 loop_statement.break_target(),
1044 &stack_check);
1045
1046 // Check stack before looping.
1047 __ bind(&stack_check);
1048 EmitStackCheck(stmt);
1049 __ jmp(&body);
1050
1051 __ bind(loop_statement.break_target());
1052 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1053 decrement_loop_depth();
1054 }
1055
1056
1057 void FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
1058 Comment cmnt(masm_, "[ WhileStatement");
1059 Label test, body;
1060
1061 Iteration loop_statement(this, stmt);
1062 increment_loop_depth();
1063
1064 // Emit the test at the bottom of the loop.
1065 __ jmp(&test);
1066
1067 __ bind(&body);
1068 Visit(stmt->body());
1069
1070 // Emit the statement position here as this is where the while
1071 // statement code starts.
1072 __ bind(loop_statement.continue_target());
1073 SetStatementPosition(stmt);
1074
1075 // Check stack before looping.
1076 EmitStackCheck(stmt);
1077
1078 __ bind(&test);
1079 VisitForControl(stmt->cond(),
892 &body, 1080 &body,
893 loop_statement.break_target(), 1081 loop_statement.break_target(),
894 loop_statement.break_target()); 1082 loop_statement.break_target());
895 1083
896 __ bind(loop_statement.break_target()); 1084 __ bind(loop_statement.break_target());
897 __ jmp(&done); 1085 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
898
899 __ bind(&stack_limit_hit);
900 StackCheckStub stack_stub;
901 __ CallStub(&stack_stub);
902 __ jmp(&stack_check_success);
903
904 __ bind(&done);
905 decrement_loop_depth();
906 }
907
908
909 void FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
910 Comment cmnt(masm_, "[ WhileStatement");
911 Label body, stack_limit_hit, stack_check_success, done;
912
913 Iteration loop_statement(this, stmt);
914 increment_loop_depth();
915
916 // Emit the test at the bottom of the loop.
917 __ jmp(loop_statement.continue_target());
918
919 __ bind(&body);
920 Visit(stmt->body());
921 __ bind(loop_statement.continue_target());
922
923 // Emit the statement position here as this is where the while
924 // statement code starts.
925 SetStatementPosition(stmt);
926
927 // Check stack before looping.
928 __ StackLimitCheck(&stack_limit_hit);
929 __ bind(&stack_check_success);
930
931 VisitForControl(stmt->cond(),
932 &body,
933 loop_statement.break_target(),
934 loop_statement.break_target());
935
936 __ bind(loop_statement.break_target());
937 __ jmp(&done);
938
939 __ bind(&stack_limit_hit);
940 StackCheckStub stack_stub;
941 __ CallStub(&stack_stub);
942 __ jmp(&stack_check_success);
943
944 __ bind(&done);
945 decrement_loop_depth(); 1086 decrement_loop_depth();
946 } 1087 }
947 1088
948 1089
949 void FullCodeGenerator::VisitForStatement(ForStatement* stmt) { 1090 void FullCodeGenerator::VisitForStatement(ForStatement* stmt) {
950 Comment cmnt(masm_, "[ ForStatement"); 1091 Comment cmnt(masm_, "[ ForStatement");
951 Label test, body, stack_limit_hit, stack_check_success; 1092 Label test, body;
952 1093
953 Iteration loop_statement(this, stmt); 1094 Iteration loop_statement(this, stmt);
954 if (stmt->init() != NULL) { 1095 if (stmt->init() != NULL) {
955 Visit(stmt->init()); 1096 Visit(stmt->init());
956 } 1097 }
957 1098
958 increment_loop_depth(); 1099 increment_loop_depth();
959 // Emit the test at the bottom of the loop (even if empty). 1100 // Emit the test at the bottom of the loop (even if empty).
960 __ jmp(&test); 1101 __ jmp(&test);
961 1102
962 __ bind(&stack_limit_hit);
963 StackCheckStub stack_stub;
964 __ CallStub(&stack_stub);
965 __ jmp(&stack_check_success);
966
967 __ bind(&body); 1103 __ bind(&body);
968 Visit(stmt->body()); 1104 Visit(stmt->body());
969 1105
970 __ bind(loop_statement.continue_target()); 1106 __ bind(loop_statement.continue_target());
1107 PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS);
971 1108
972 SetStatementPosition(stmt); 1109 SetStatementPosition(stmt);
973 if (stmt->next() != NULL) { 1110 if (stmt->next() != NULL) {
974 Visit(stmt->next()); 1111 Visit(stmt->next());
975 } 1112 }
976 1113
977 __ bind(&test);
978 // Emit the statement position here as this is where the for 1114 // Emit the statement position here as this is where the for
979 // statement code starts. 1115 // statement code starts.
980 SetStatementPosition(stmt); 1116 SetStatementPosition(stmt);
981 1117
982 // Check stack before looping. 1118 // Check stack before looping.
983 __ StackLimitCheck(&stack_limit_hit); 1119 EmitStackCheck(stmt);
984 __ bind(&stack_check_success);
985 1120
1121 __ bind(&test);
986 if (stmt->cond() != NULL) { 1122 if (stmt->cond() != NULL) {
987 VisitForControl(stmt->cond(), 1123 VisitForControl(stmt->cond(),
988 &body, 1124 &body,
989 loop_statement.break_target(), 1125 loop_statement.break_target(),
990 loop_statement.break_target()); 1126 loop_statement.break_target());
991 } else { 1127 } else {
992 __ jmp(&body); 1128 __ jmp(&body);
993 } 1129 }
994 1130
995 __ bind(loop_statement.break_target()); 1131 __ bind(loop_statement.break_target());
1132 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
996 decrement_loop_depth(); 1133 decrement_loop_depth();
997 } 1134 }
998 1135
999 1136
1000 void FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { 1137 void FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
1001 Comment cmnt(masm_, "[ TryCatchStatement"); 1138 Comment cmnt(masm_, "[ TryCatchStatement");
1002 SetStatementPosition(stmt); 1139 SetStatementPosition(stmt);
1003 // The try block adds a handler to the exception handler chain 1140 // The try block adds a handler to the exception handler chain
1004 // before entering, and removes it again when exiting normally. 1141 // before entering, and removes it again when exiting normally.
1005 // If an exception is thrown during execution of the try block, 1142 // If an exception is thrown during execution of the try block,
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
1123 __ bind(&true_case); 1260 __ bind(&true_case);
1124 SetExpressionPosition(expr->then_expression(), 1261 SetExpressionPosition(expr->then_expression(),
1125 expr->then_expression_position()); 1262 expr->then_expression_position());
1126 if (context()->IsTest()) { 1263 if (context()->IsTest()) {
1127 const TestContext* for_test = TestContext::cast(context()); 1264 const TestContext* for_test = TestContext::cast(context());
1128 VisitForControl(expr->then_expression(), 1265 VisitForControl(expr->then_expression(),
1129 for_test->true_label(), 1266 for_test->true_label(),
1130 for_test->false_label(), 1267 for_test->false_label(),
1131 NULL); 1268 NULL);
1132 } else { 1269 } else {
1133 Visit(expr->then_expression()); 1270 context()->HandleExpression(expr->then_expression());
1134 __ jmp(&done); 1271 __ jmp(&done);
1135 } 1272 }
1136 1273
1137 __ bind(&false_case); 1274 __ bind(&false_case);
1275 if (context()->IsTest()) ForwardBailoutToChild(expr);
1138 SetExpressionPosition(expr->else_expression(), 1276 SetExpressionPosition(expr->else_expression(),
1139 expr->else_expression_position()); 1277 expr->else_expression_position());
1140 Visit(expr->else_expression()); 1278 context()->HandleExpression(expr->else_expression());
1141 // If control flow falls through Visit, merge it with true case here. 1279 // If control flow falls through Visit, merge it with true case here.
1142 if (!context()->IsTest()) { 1280 if (!context()->IsTest()) {
1143 __ bind(&done); 1281 __ bind(&done);
1144 } 1282 }
1145 } 1283 }
1146 1284
1147 1285
1148 void FullCodeGenerator::VisitSlot(Slot* expr) {
1149 // Slots do not appear directly in the AST.
1150 UNREACHABLE();
1151 }
1152
1153
1154 void FullCodeGenerator::VisitLiteral(Literal* expr) { 1286 void FullCodeGenerator::VisitLiteral(Literal* expr) {
1155 Comment cmnt(masm_, "[ Literal"); 1287 Comment cmnt(masm_, "[ Literal");
1156 context()->Plug(expr->handle()); 1288 context()->Plug(expr->handle());
1157 } 1289 }
1158 1290
1159 1291
1160 void FullCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) { 1292 void FullCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
1161 Comment cmnt(masm_, "[ FunctionLiteral"); 1293 Comment cmnt(masm_, "[ FunctionLiteral");
1162 1294
1163 // Build the function boilerplate and instantiate it. 1295 // Build the function boilerplate and instantiate it.
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1217 __ Drop(stack_depth); 1349 __ Drop(stack_depth);
1218 __ PopTryHandler(); 1350 __ PopTryHandler();
1219 return 0; 1351 return 0;
1220 } 1352 }
1221 1353
1222 1354
1223 #undef __ 1355 #undef __
1224 1356
1225 1357
1226 } } // namespace v8::internal 1358 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/full-codegen.h ('k') | src/global-handles.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698