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

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

Issue 555073: Merge r3610, r3611, r3612, r3630, r3636, r3640, and r3664... (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
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 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 } 143 }
177 144
178 145
179 void FastCodeGenerator::SetStatementPosition(Statement* stmt) { 146 void FastCodeGenerator::SetStatementPosition(Statement* stmt) {
180 if (FLAG_debug_info) { 147 if (FLAG_debug_info) {
181 CodeGenerator::RecordPositions(masm_, stmt->statement_pos()); 148 CodeGenerator::RecordPositions(masm_, stmt->statement_pos());
182 } 149 }
183 } 150 }
184 151
185 152
153 void FastCodeGenerator::SetStatementPosition(int pos) {
154 if (FLAG_debug_info) {
155 CodeGenerator::RecordPositions(masm_, pos);
156 }
157 }
158
159
186 void FastCodeGenerator::SetSourcePosition(int pos) { 160 void FastCodeGenerator::SetSourcePosition(int pos) {
187 if (FLAG_debug_info && pos != RelocInfo::kNoPosition) { 161 if (FLAG_debug_info && pos != RelocInfo::kNoPosition) {
188 masm_->RecordPosition(pos); 162 masm_->RecordPosition(pos);
189 } 163 }
190 } 164 }
191 165
192 166
193 void FastCodeGenerator::EmitLogicalOperation(BinaryOperation* expr) { 167 void FastCodeGenerator::EmitLogicalOperation(BinaryOperation* expr) {
194 #ifdef DEBUG 168 #ifdef DEBUG
195 Expression::Context expected = Expression::kUninitialized; 169 Expression::Context expected = Expression::kUninitialized;
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
331 305
332 Breakable* target = current->AsBreakable(); 306 Breakable* target = current->AsBreakable();
333 __ jmp(target->break_target()); 307 __ jmp(target->break_target());
334 } 308 }
335 309
336 310
337 void FastCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { 311 void FastCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
338 Comment cmnt(masm_, "[ ReturnStatement"); 312 Comment cmnt(masm_, "[ ReturnStatement");
339 SetStatementPosition(stmt); 313 SetStatementPosition(stmt);
340 Expression* expr = stmt->expression(); 314 Expression* expr = stmt->expression();
341 // Complete the statement based on the type of the subexpression. 315 VisitForValue(expr, kAccumulator);
342 if (expr->AsLiteral() != NULL) {
343 __ Move(result_register(), expr->AsLiteral()->handle());
344 } else {
345 ASSERT_EQ(Expression::kValue, expr->context());
346 Visit(expr);
347 __ pop(result_register());
348 }
349 316
350 // Exit all nested statements. 317 // Exit all nested statements.
351 NestedStatement* current = nesting_stack_; 318 NestedStatement* current = nesting_stack_;
352 int stack_depth = 0; 319 int stack_depth = 0;
353 while (current != NULL) { 320 while (current != NULL) {
354 stack_depth = current->Exit(stack_depth); 321 stack_depth = current->Exit(stack_depth);
355 current = current->outer(); 322 current = current->outer();
356 } 323 }
357 __ Drop(stack_depth); 324 __ Drop(stack_depth);
358 325
359 EmitReturnSequence(stmt->statement_pos()); 326 EmitReturnSequence(stmt->statement_pos());
360 } 327 }
361 328
362 329
363
364
365 void FastCodeGenerator::VisitWithEnterStatement(WithEnterStatement* stmt) { 330 void FastCodeGenerator::VisitWithEnterStatement(WithEnterStatement* stmt) {
366 Comment cmnt(masm_, "[ WithEnterStatement"); 331 Comment cmnt(masm_, "[ WithEnterStatement");
367 SetStatementPosition(stmt); 332 SetStatementPosition(stmt);
368 333
369 Visit(stmt->expression()); 334 VisitForValue(stmt->expression(), kStack);
370 if (stmt->is_catch_block()) { 335 if (stmt->is_catch_block()) {
371 __ CallRuntime(Runtime::kPushCatchContext, 1); 336 __ CallRuntime(Runtime::kPushCatchContext, 1);
372 } else { 337 } else {
373 __ CallRuntime(Runtime::kPushContext, 1); 338 __ CallRuntime(Runtime::kPushContext, 1);
374 } 339 }
375 // 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
376 // result registers. 341 // result registers.
377 342
378 // Update local stack frame context field. 343 // Update local stack frame context field.
379 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); 344 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register());
(...skipping 25 matching lines...) Expand all
405 increment_loop_depth(); 370 increment_loop_depth();
406 371
407 __ bind(&body); 372 __ bind(&body);
408 Visit(stmt->body()); 373 Visit(stmt->body());
409 374
410 // Check stack before looping. 375 // Check stack before looping.
411 __ StackLimitCheck(&stack_limit_hit); 376 __ StackLimitCheck(&stack_limit_hit);
412 __ bind(&stack_check_success); 377 __ bind(&stack_check_success);
413 378
414 __ bind(loop_statement.continue_target()); 379 __ bind(loop_statement.continue_target());
380 SetStatementPosition(stmt->condition_position());
415 VisitForControl(stmt->cond(), &body, loop_statement.break_target()); 381 VisitForControl(stmt->cond(), &body, loop_statement.break_target());
416 382
417 __ bind(&stack_limit_hit); 383 __ bind(&stack_limit_hit);
418 StackCheckStub stack_stub; 384 StackCheckStub stack_stub;
419 __ CallStub(&stack_stub); 385 __ CallStub(&stack_stub);
420 __ jmp(&stack_check_success); 386 __ jmp(&stack_check_success);
421 387
422 __ bind(loop_statement.break_target()); 388 __ bind(loop_statement.break_target());
423 389
424 decrement_loop_depth(); 390 decrement_loop_depth();
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
626 592
627 void FastCodeGenerator::VisitLiteral(Literal* expr) { 593 void FastCodeGenerator::VisitLiteral(Literal* expr) {
628 Comment cmnt(masm_, "[ Literal"); 594 Comment cmnt(masm_, "[ Literal");
629 Apply(expr->context(), expr); 595 Apply(expr->context(), expr);
630 } 596 }
631 597
632 598
633 void FastCodeGenerator::VisitAssignment(Assignment* expr) { 599 void FastCodeGenerator::VisitAssignment(Assignment* expr) {
634 Comment cmnt(masm_, "[ Assignment"); 600 Comment cmnt(masm_, "[ Assignment");
635 601
636 // Record source code position of the (possible) IC call.
637 SetSourcePosition(expr->position());
638
639 // Left-hand side can only be a property, a global or a (parameter or local) 602 // Left-hand side can only be a property, a global or a (parameter or local)
640 // slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY. 603 // slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY.
641 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; 604 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
642 LhsKind assign_type = VARIABLE; 605 LhsKind assign_type = VARIABLE;
643 Property* prop = expr->target()->AsProperty(); 606 Property* prop = expr->target()->AsProperty();
644 // In case of a property we use the uninitialized expression context 607 // In case of a property we use the uninitialized expression context
645 // of the key to detect a named property. 608 // of the key to detect a named property.
646 if (prop != NULL) { 609 if (prop != NULL) {
647 assign_type = (prop->key()->context() == Expression::kUninitialized) 610 assign_type = (prop->key()->context() == Expression::kUninitialized)
648 ? NAMED_PROPERTY 611 ? NAMED_PROPERTY
649 : KEYED_PROPERTY; 612 : KEYED_PROPERTY;
650 } 613 }
651 614
652 // Evaluate LHS expression. 615 // Evaluate LHS expression.
653 switch (assign_type) { 616 switch (assign_type) {
654 case VARIABLE: 617 case VARIABLE:
655 // Nothing to do here. 618 // Nothing to do here.
656 break; 619 break;
657 case NAMED_PROPERTY: 620 case NAMED_PROPERTY:
658 Visit(prop->obj()); 621 VisitForValue(prop->obj(), kStack);
659 ASSERT_EQ(Expression::kValue, prop->obj()->context());
660 break; 622 break;
661 case KEYED_PROPERTY: 623 case KEYED_PROPERTY:
662 Visit(prop->obj()); 624 VisitForValue(prop->obj(), kStack);
663 ASSERT_EQ(Expression::kValue, prop->obj()->context()); 625 VisitForValue(prop->key(), kStack);
664 Visit(prop->key());
665 ASSERT_EQ(Expression::kValue, prop->key()->context());
666 break; 626 break;
667 } 627 }
668 628
669 // 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
670 // store in on top of the stack. 630 // store in on top of the stack.
671 // Note: Relies on kValue context being 'stack'.
672 if (expr->is_compound()) { 631 if (expr->is_compound()) {
632 Location saved_location = location_;
633 location_ = kStack;
673 switch (assign_type) { 634 switch (assign_type) {
674 case VARIABLE: 635 case VARIABLE:
675 EmitVariableLoad(expr->target()->AsVariableProxy()->var(), 636 EmitVariableLoad(expr->target()->AsVariableProxy()->var(),
676 Expression::kValue); 637 Expression::kValue);
677 break; 638 break;
678 case NAMED_PROPERTY: 639 case NAMED_PROPERTY:
679 EmitNamedPropertyLoad(prop, Expression::kValue); 640 EmitNamedPropertyLoad(prop);
641 __ push(result_register());
680 break; 642 break;
681 case KEYED_PROPERTY: 643 case KEYED_PROPERTY:
682 EmitKeyedPropertyLoad(prop, Expression::kValue); 644 EmitKeyedPropertyLoad(prop);
645 __ push(result_register());
683 break; 646 break;
684 } 647 }
648 location_ = saved_location;
685 } 649 }
686 650
687 // Evaluate RHS expression. 651 // Evaluate RHS expression.
688 Expression* rhs = expr->value(); 652 Expression* rhs = expr->value();
689 ASSERT_EQ(Expression::kValue, rhs->context()); 653 VisitForValue(rhs, kAccumulator);
690 Visit(rhs);
691 654
692 // If we have a compount assignment: Apply operator. 655 // If we have a compount assignment: Apply operator.
693 if (expr->is_compound()) { 656 if (expr->is_compound()) {
694 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;
695 } 661 }
696 662
663 // Record source position before possible IC call.
664 SetSourcePosition(expr->position());
665
697 // Store the value. 666 // Store the value.
698 switch (assign_type) { 667 switch (assign_type) {
699 case VARIABLE: 668 case VARIABLE:
700 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), 669 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(),
701 expr->context()); 670 expr->context());
702 break; 671 break;
703 case NAMED_PROPERTY: 672 case NAMED_PROPERTY:
704 EmitNamedPropertyAssignment(expr); 673 EmitNamedPropertyAssignment(expr);
705 break; 674 break;
706 case KEYED_PROPERTY: 675 case KEYED_PROPERTY:
707 EmitKeyedPropertyAssignment(expr); 676 EmitKeyedPropertyAssignment(expr);
708 break; 677 break;
709 } 678 }
710 } 679 }
711 680
712 681
713 void FastCodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* expr) { 682 void FastCodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* expr) {
714 // Call runtime routine to allocate the catch extension object and 683 // Call runtime routine to allocate the catch extension object and
715 // assign the exception value to the catch variable. 684 // assign the exception value to the catch variable.
716 Comment cmnt(masm_, "[ CatchExtensionObject"); 685 Comment cmnt(masm_, "[ CatchExtensionObject");
717 686
718 // Push key string. 687 VisitForValue(expr->key(), kStack);
719 ASSERT_EQ(Expression::kValue, expr->key()->context()); 688 VisitForValue(expr->value(), kStack);
720 Visit(expr->key());
721 ASSERT_EQ(Expression::kValue, expr->value()->context());
722 Visit(expr->value());
723 689
724 // Create catch extension object. 690 // Create catch extension object.
725 __ CallRuntime(Runtime::kCreateCatchExtensionObject, 2); 691 __ CallRuntime(Runtime::kCreateCatchExtensionObject, 2);
726 692
727 __ push(result_register()); 693 __ push(result_register());
728 } 694 }
729 695
730 696
731 void FastCodeGenerator::VisitThrow(Throw* expr) { 697 void FastCodeGenerator::VisitThrow(Throw* expr) {
732 Comment cmnt(masm_, "[ Throw"); 698 Comment cmnt(masm_, "[ Throw");
733 Visit(expr->exception()); 699 VisitForValue(expr->exception(), kStack);
734 // Exception is on stack.
735 __ CallRuntime(Runtime::kThrow, 1); 700 __ CallRuntime(Runtime::kThrow, 1);
736 // Never returns here. 701 // Never returns here.
737 } 702 }
738 703
739 704
740 int FastCodeGenerator::TryFinally::Exit(int stack_depth) { 705 int FastCodeGenerator::TryFinally::Exit(int stack_depth) {
741 // The macros used here must preserve the result register. 706 // The macros used here must preserve the result register.
742 __ Drop(stack_depth); 707 __ Drop(stack_depth);
743 __ PopTryHandler(); 708 __ PopTryHandler();
744 __ Call(finally_entry_); 709 __ Call(finally_entry_);
745 return 0; 710 return 0;
746 } 711 }
747 712
748 713
749 int FastCodeGenerator::TryCatch::Exit(int stack_depth) { 714 int FastCodeGenerator::TryCatch::Exit(int stack_depth) {
750 // The macros used here must preserve the result register. 715 // The macros used here must preserve the result register.
751 __ Drop(stack_depth); 716 __ Drop(stack_depth);
752 __ PopTryHandler(); 717 __ PopTryHandler();
753 return 0; 718 return 0;
754 } 719 }
755 720
756 721
757 #undef __ 722 #undef __
758 723
759 724
760 } } // 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