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

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

Issue 541047: Introduce 'top-of-stack caching' to the toplevel code generator by... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 11 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/fast-codegen.h ('k') | src/ia32/fast-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 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 offset += JavaScriptFrameConstants::kLocal0Offset; 68 offset += JavaScriptFrameConstants::kLocal0Offset;
69 break; 69 break;
70 case Slot::CONTEXT: 70 case Slot::CONTEXT:
71 case Slot::LOOKUP: 71 case Slot::LOOKUP:
72 UNREACHABLE(); 72 UNREACHABLE();
73 } 73 }
74 return offset; 74 return offset;
75 } 75 }
76 76
77 77
78 void FastCodeGenerator::Apply(Expression::Context context, Register reg) {
79 switch (context) {
80 case Expression::kUninitialized:
81 UNREACHABLE();
82 case Expression::kEffect:
83 break;
84 case Expression::kValue:
85 __ push(reg);
86 break;
87 case Expression::kTest:
88 TestAndBranch(reg, true_label_, false_label_);
89 break;
90 case Expression::kValueTest: {
91 Label discard;
92 __ push(reg);
93 TestAndBranch(reg, true_label_, &discard);
94 __ bind(&discard);
95 __ Drop(1);
96 __ jmp(false_label_);
97 break;
98 }
99 case Expression::kTestValue: {
100 Label discard;
101 __ push(reg);
102 TestAndBranch(reg, &discard, false_label_);
103 __ bind(&discard);
104 __ Drop(1);
105 __ jmp(true_label_);
106 }
107 }
108 }
109
110
111 void FastCodeGenerator::VisitDeclarations( 78 void FastCodeGenerator::VisitDeclarations(
112 ZoneList<Declaration*>* declarations) { 79 ZoneList<Declaration*>* declarations) {
113 int length = declarations->length(); 80 int length = declarations->length();
114 int globals = 0; 81 int globals = 0;
115 for (int i = 0; i < length; i++) { 82 for (int i = 0; i < length; i++) {
116 Declaration* decl = declarations->at(i); 83 Declaration* decl = declarations->at(i);
117 Variable* var = decl->proxy()->var(); 84 Variable* var = decl->proxy()->var();
118 Slot* slot = var->slot(); 85 Slot* slot = var->slot();
119 86
120 // If it was not possible to allocate the variable at compile 87 // If it was not possible to allocate the variable at compile
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
338 305
339 Breakable* target = current->AsBreakable(); 306 Breakable* target = current->AsBreakable();
340 __ jmp(target->break_target()); 307 __ jmp(target->break_target());
341 } 308 }
342 309
343 310
344 void FastCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { 311 void FastCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
345 Comment cmnt(masm_, "[ ReturnStatement"); 312 Comment cmnt(masm_, "[ ReturnStatement");
346 SetStatementPosition(stmt); 313 SetStatementPosition(stmt);
347 Expression* expr = stmt->expression(); 314 Expression* expr = stmt->expression();
348 // Complete the statement based on the type of the subexpression. 315 VisitForValue(expr, kAccumulator);
349 if (expr->AsLiteral() != NULL) {
350 __ Move(result_register(), expr->AsLiteral()->handle());
351 } else {
352 ASSERT_EQ(Expression::kValue, expr->context());
353 Visit(expr);
354 __ pop(result_register());
355 }
356 316
357 // Exit all nested statements. 317 // Exit all nested statements.
358 NestedStatement* current = nesting_stack_; 318 NestedStatement* current = nesting_stack_;
359 int stack_depth = 0; 319 int stack_depth = 0;
360 while (current != NULL) { 320 while (current != NULL) {
361 stack_depth = current->Exit(stack_depth); 321 stack_depth = current->Exit(stack_depth);
362 current = current->outer(); 322 current = current->outer();
363 } 323 }
364 __ Drop(stack_depth); 324 __ Drop(stack_depth);
365 325
366 EmitReturnSequence(stmt->statement_pos()); 326 EmitReturnSequence(stmt->statement_pos());
367 } 327 }
368 328
369 329
370 void FastCodeGenerator::VisitWithEnterStatement(WithEnterStatement* stmt) { 330 void FastCodeGenerator::VisitWithEnterStatement(WithEnterStatement* stmt) {
371 Comment cmnt(masm_, "[ WithEnterStatement"); 331 Comment cmnt(masm_, "[ WithEnterStatement");
372 SetStatementPosition(stmt); 332 SetStatementPosition(stmt);
373 333
374 Visit(stmt->expression()); 334 VisitForValue(stmt->expression(), kStack);
375 if (stmt->is_catch_block()) { 335 if (stmt->is_catch_block()) {
376 __ CallRuntime(Runtime::kPushCatchContext, 1); 336 __ CallRuntime(Runtime::kPushCatchContext, 1);
377 } else { 337 } else {
378 __ CallRuntime(Runtime::kPushContext, 1); 338 __ CallRuntime(Runtime::kPushContext, 1);
379 } 339 }
380 // Both runtime calls return the new context in both the context and the 340 // Both runtime calls return the new context in both the context and the
381 // result registers. 341 // result registers.
382 342
383 // Update local stack frame context field. 343 // Update local stack frame context field.
384 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); 344 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register());
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after
651 ? NAMED_PROPERTY 611 ? NAMED_PROPERTY
652 : KEYED_PROPERTY; 612 : KEYED_PROPERTY;
653 } 613 }
654 614
655 // Evaluate LHS expression. 615 // Evaluate LHS expression.
656 switch (assign_type) { 616 switch (assign_type) {
657 case VARIABLE: 617 case VARIABLE:
658 // Nothing to do here. 618 // Nothing to do here.
659 break; 619 break;
660 case NAMED_PROPERTY: 620 case NAMED_PROPERTY:
661 Visit(prop->obj()); 621 VisitForValue(prop->obj(), kStack);
662 ASSERT_EQ(Expression::kValue, prop->obj()->context());
663 break; 622 break;
664 case KEYED_PROPERTY: 623 case KEYED_PROPERTY:
665 Visit(prop->obj()); 624 VisitForValue(prop->obj(), kStack);
666 ASSERT_EQ(Expression::kValue, prop->obj()->context()); 625 VisitForValue(prop->key(), kStack);
667 Visit(prop->key());
668 ASSERT_EQ(Expression::kValue, prop->key()->context());
669 break; 626 break;
670 } 627 }
671 628
672 // If we have a compound assignment: Get value of LHS expression and 629 // If we have a compound assignment: Get value of LHS expression and
673 // store in on top of the stack. 630 // store in on top of the stack.
674 // Note: Relies on kValue context being 'stack'.
675 if (expr->is_compound()) { 631 if (expr->is_compound()) {
632 Location saved_location = location_;
633 location_ = kStack;
676 switch (assign_type) { 634 switch (assign_type) {
677 case VARIABLE: 635 case VARIABLE:
678 EmitVariableLoad(expr->target()->AsVariableProxy()->var(), 636 EmitVariableLoad(expr->target()->AsVariableProxy()->var(),
679 Expression::kValue); 637 Expression::kValue);
680 break; 638 break;
681 case NAMED_PROPERTY: 639 case NAMED_PROPERTY:
682 EmitNamedPropertyLoad(prop); 640 EmitNamedPropertyLoad(prop);
683 __ push(result_register()); 641 __ push(result_register());
684 break; 642 break;
685 case KEYED_PROPERTY: 643 case KEYED_PROPERTY:
686 EmitKeyedPropertyLoad(prop); 644 EmitKeyedPropertyLoad(prop);
687 __ push(result_register()); 645 __ push(result_register());
688 break; 646 break;
689 } 647 }
648 location_ = saved_location;
690 } 649 }
691 650
692 // Evaluate RHS expression. 651 // Evaluate RHS expression.
693 Expression* rhs = expr->value(); 652 Expression* rhs = expr->value();
694 ASSERT_EQ(Expression::kValue, rhs->context()); 653 VisitForValue(rhs, kAccumulator);
695 Visit(rhs);
696 654
697 // If we have a compount assignment: Apply operator. 655 // If we have a compount assignment: Apply operator.
698 if (expr->is_compound()) { 656 if (expr->is_compound()) {
699 EmitCompoundAssignmentOp(expr->binary_op(), Expression::kValue); 657 Location saved_location = location_;
658 location_ = kAccumulator;
659 EmitBinaryOp(expr->binary_op(), Expression::kValue);
660 location_ = saved_location;
700 } 661 }
701 662
702 // Record source position before possible IC call. 663 // Record source position before possible IC call.
703 SetSourcePosition(expr->position()); 664 SetSourcePosition(expr->position());
704 665
705 // Store the value. 666 // Store the value.
706 switch (assign_type) { 667 switch (assign_type) {
707 case VARIABLE: 668 case VARIABLE:
708 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), 669 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(),
709 expr->context()); 670 expr->context());
710 break; 671 break;
711 case NAMED_PROPERTY: 672 case NAMED_PROPERTY:
712 EmitNamedPropertyAssignment(expr); 673 EmitNamedPropertyAssignment(expr);
713 break; 674 break;
714 case KEYED_PROPERTY: 675 case KEYED_PROPERTY:
715 EmitKeyedPropertyAssignment(expr); 676 EmitKeyedPropertyAssignment(expr);
716 break; 677 break;
717 } 678 }
718 } 679 }
719 680
720 681
721 void FastCodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* expr) { 682 void FastCodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* expr) {
722 // Call runtime routine to allocate the catch extension object and 683 // Call runtime routine to allocate the catch extension object and
723 // assign the exception value to the catch variable. 684 // assign the exception value to the catch variable.
724 Comment cmnt(masm_, "[ CatchExtensionObject"); 685 Comment cmnt(masm_, "[ CatchExtensionObject");
725 686
726 // Push key string. 687 VisitForValue(expr->key(), kStack);
727 ASSERT_EQ(Expression::kValue, expr->key()->context()); 688 VisitForValue(expr->value(), kStack);
728 Visit(expr->key());
729 ASSERT_EQ(Expression::kValue, expr->value()->context());
730 Visit(expr->value());
731 689
732 // Create catch extension object. 690 // Create catch extension object.
733 __ CallRuntime(Runtime::kCreateCatchExtensionObject, 2); 691 __ CallRuntime(Runtime::kCreateCatchExtensionObject, 2);
734 692
735 __ push(result_register()); 693 __ push(result_register());
736 } 694 }
737 695
738 696
739 void FastCodeGenerator::VisitThrow(Throw* expr) { 697 void FastCodeGenerator::VisitThrow(Throw* expr) {
740 Comment cmnt(masm_, "[ Throw"); 698 Comment cmnt(masm_, "[ Throw");
741 Visit(expr->exception()); 699 VisitForValue(expr->exception(), kStack);
742 // Exception is on stack.
743 __ CallRuntime(Runtime::kThrow, 1); 700 __ CallRuntime(Runtime::kThrow, 1);
744 // Never returns here. 701 // Never returns here.
745 } 702 }
746 703
747 704
748 int FastCodeGenerator::TryFinally::Exit(int stack_depth) { 705 int FastCodeGenerator::TryFinally::Exit(int stack_depth) {
749 // The macros used here must preserve the result register. 706 // The macros used here must preserve the result register.
750 __ Drop(stack_depth); 707 __ Drop(stack_depth);
751 __ PopTryHandler(); 708 __ PopTryHandler();
752 __ Call(finally_entry_); 709 __ Call(finally_entry_);
753 return 0; 710 return 0;
754 } 711 }
755 712
756 713
757 int FastCodeGenerator::TryCatch::Exit(int stack_depth) { 714 int FastCodeGenerator::TryCatch::Exit(int stack_depth) {
758 // The macros used here must preserve the result register. 715 // The macros used here must preserve the result register.
759 __ Drop(stack_depth); 716 __ Drop(stack_depth);
760 __ PopTryHandler(); 717 __ PopTryHandler();
761 return 0; 718 return 0;
762 } 719 }
763 720
764 721
765 #undef __ 722 #undef __
766 723
767 724
768 } } // namespace v8::internal 725 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/fast-codegen.h ('k') | src/ia32/fast-codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698