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

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

Issue 115564: Size reduction of VirtualFrame objects. Remove the code generator and... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 11 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 | « no previous file | src/arm/virtual-frame-arm.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 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-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 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 void CodeGenerator::GenCode(FunctionLiteral* fun) { 101 void CodeGenerator::GenCode(FunctionLiteral* fun) {
102 ZoneList<Statement*>* body = fun->body(); 102 ZoneList<Statement*>* body = fun->body();
103 103
104 // Initialize state. 104 // Initialize state.
105 ASSERT(scope_ == NULL); 105 ASSERT(scope_ == NULL);
106 scope_ = fun->scope(); 106 scope_ = fun->scope();
107 ASSERT(allocator_ == NULL); 107 ASSERT(allocator_ == NULL);
108 RegisterAllocator register_allocator(this); 108 RegisterAllocator register_allocator(this);
109 allocator_ = &register_allocator; 109 allocator_ = &register_allocator;
110 ASSERT(frame_ == NULL); 110 ASSERT(frame_ == NULL);
111 frame_ = new VirtualFrame(this); 111 frame_ = new VirtualFrame();
112 cc_reg_ = al; 112 cc_reg_ = al;
113 set_in_spilled_code(false); 113 set_in_spilled_code(false);
114 { 114 {
115 CodeGenState state(this); 115 CodeGenState state(this);
116 116
117 // Entry: 117 // Entry:
118 // Stack: receiver, arguments 118 // Stack: receiver, arguments
119 // lr: return address 119 // lr: return address
120 // fp: caller's frame pointer 120 // fp: caller's frame pointer
121 // sp: stack pointer 121 // sp: stack pointer
122 // r1: called JS function 122 // r1: called JS function
123 // cp: callee's context 123 // cp: callee's context
124 allocator_->Initialize(); 124 allocator_->Initialize();
125 frame_->Enter(); 125 frame_->Enter();
126 // tos: code slot 126 // tos: code slot
127 #ifdef DEBUG 127 #ifdef DEBUG
128 if (strlen(FLAG_stop_at) > 0 && 128 if (strlen(FLAG_stop_at) > 0 &&
129 fun->name()->IsEqualTo(CStrVector(FLAG_stop_at))) { 129 fun->name()->IsEqualTo(CStrVector(FLAG_stop_at))) {
130 frame_->SpillAll(); 130 frame_->SpillAll();
131 __ stop("stop-at"); 131 __ stop("stop-at");
132 } 132 }
133 #endif 133 #endif
134 134
135 // Allocate space for locals and initialize them. 135 // Allocate space for locals and initialize them.
136 frame_->AllocateStackSlots(scope_->num_stack_slots()); 136 frame_->AllocateStackSlots();
137 // Initialize the function return target after the locals are set 137 // Initialize the function return target after the locals are set
138 // up, because it needs the expected frame height from the frame. 138 // up, because it needs the expected frame height from the frame.
139 function_return_.set_direction(JumpTarget::BIDIRECTIONAL); 139 function_return_.set_direction(JumpTarget::BIDIRECTIONAL);
140 function_return_is_shadowed_ = false; 140 function_return_is_shadowed_ = false;
141 141
142 VirtualFrame::SpilledScope spilled_scope(this); 142 VirtualFrame::SpilledScope spilled_scope;
143 if (scope_->num_heap_slots() > 0) { 143 if (scope_->num_heap_slots() > 0) {
144 // Allocate local context. 144 // Allocate local context.
145 // Get outer context and create a new context based on it. 145 // Get outer context and create a new context based on it.
146 __ ldr(r0, frame_->Function()); 146 __ ldr(r0, frame_->Function());
147 frame_->EmitPush(r0); 147 frame_->EmitPush(r0);
148 frame_->CallRuntime(Runtime::kNewContext, 1); // r0 holds the result 148 frame_->CallRuntime(Runtime::kNewContext, 1); // r0 holds the result
149 149
150 #ifdef DEBUG 150 #ifdef DEBUG
151 JumpTarget verified_true; 151 JumpTarget verified_true;
152 __ cmp(r0, Operand(cp)); 152 __ cmp(r0, Operand(cp));
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after
503 // A value is loaded on all paths reaching this point. 503 // A value is loaded on all paths reaching this point.
504 loaded.Bind(); 504 loaded.Bind();
505 } 505 }
506 ASSERT(has_valid_frame()); 506 ASSERT(has_valid_frame());
507 ASSERT(!has_cc()); 507 ASSERT(!has_cc());
508 ASSERT(frame_->height() == original_height + 1); 508 ASSERT(frame_->height() == original_height + 1);
509 } 509 }
510 510
511 511
512 void CodeGenerator::LoadGlobal() { 512 void CodeGenerator::LoadGlobal() {
513 VirtualFrame::SpilledScope spilled_scope(this); 513 VirtualFrame::SpilledScope spilled_scope;
514 __ ldr(r0, GlobalObject()); 514 __ ldr(r0, GlobalObject());
515 frame_->EmitPush(r0); 515 frame_->EmitPush(r0);
516 } 516 }
517 517
518 518
519 void CodeGenerator::LoadGlobalReceiver(Register scratch) { 519 void CodeGenerator::LoadGlobalReceiver(Register scratch) {
520 VirtualFrame::SpilledScope spilled_scope(this); 520 VirtualFrame::SpilledScope spilled_scope;
521 __ ldr(scratch, ContextOperand(cp, Context::GLOBAL_INDEX)); 521 __ ldr(scratch, ContextOperand(cp, Context::GLOBAL_INDEX));
522 __ ldr(scratch, 522 __ ldr(scratch,
523 FieldMemOperand(scratch, GlobalObject::kGlobalReceiverOffset)); 523 FieldMemOperand(scratch, GlobalObject::kGlobalReceiverOffset));
524 frame_->EmitPush(scratch); 524 frame_->EmitPush(scratch);
525 } 525 }
526 526
527 527
528 // TODO(1241834): Get rid of this function in favor of just using Load, now 528 // TODO(1241834): Get rid of this function in favor of just using Load, now
529 // that we have the INSIDE_TYPEOF typeof state. => Need to handle global 529 // that we have the INSIDE_TYPEOF typeof state. => Need to handle global
530 // variables w/o reference errors elsewhere. 530 // variables w/o reference errors elsewhere.
531 void CodeGenerator::LoadTypeofExpression(Expression* x) { 531 void CodeGenerator::LoadTypeofExpression(Expression* x) {
532 VirtualFrame::SpilledScope spilled_scope(this); 532 VirtualFrame::SpilledScope spilled_scope;
533 Variable* variable = x->AsVariableProxy()->AsVariable(); 533 Variable* variable = x->AsVariableProxy()->AsVariable();
534 if (variable != NULL && !variable->is_this() && variable->is_global()) { 534 if (variable != NULL && !variable->is_this() && variable->is_global()) {
535 // NOTE: This is somewhat nasty. We force the compiler to load 535 // NOTE: This is somewhat nasty. We force the compiler to load
536 // the variable as if through '<global>.<variable>' to make sure we 536 // the variable as if through '<global>.<variable>' to make sure we
537 // do not get reference errors. 537 // do not get reference errors.
538 Slot global(variable, Slot::CONTEXT, Context::GLOBAL_INDEX); 538 Slot global(variable, Slot::CONTEXT, Context::GLOBAL_INDEX);
539 Literal key(variable->name()); 539 Literal key(variable->name());
540 // TODO(1241834): Fetch the position from the variable instead of using 540 // TODO(1241834): Fetch the position from the variable instead of using
541 // no position. 541 // no position.
542 Property property(&global, &key, RelocInfo::kNoPosition); 542 Property property(&global, &key, RelocInfo::kNoPosition);
543 LoadAndSpill(&property); 543 LoadAndSpill(&property);
544 } else { 544 } else {
545 LoadAndSpill(x, INSIDE_TYPEOF); 545 LoadAndSpill(x, INSIDE_TYPEOF);
546 } 546 }
547 } 547 }
548 548
549 549
550 Reference::Reference(CodeGenerator* cgen, Expression* expression) 550 Reference::Reference(CodeGenerator* cgen, Expression* expression)
551 : cgen_(cgen), expression_(expression), type_(ILLEGAL) { 551 : cgen_(cgen), expression_(expression), type_(ILLEGAL) {
552 cgen->LoadReference(this); 552 cgen->LoadReference(this);
553 } 553 }
554 554
555 555
556 Reference::~Reference() { 556 Reference::~Reference() {
557 cgen_->UnloadReference(this); 557 cgen_->UnloadReference(this);
558 } 558 }
559 559
560 560
561 void CodeGenerator::LoadReference(Reference* ref) { 561 void CodeGenerator::LoadReference(Reference* ref) {
562 VirtualFrame::SpilledScope spilled_scope(this); 562 VirtualFrame::SpilledScope spilled_scope;
563 Comment cmnt(masm_, "[ LoadReference"); 563 Comment cmnt(masm_, "[ LoadReference");
564 Expression* e = ref->expression(); 564 Expression* e = ref->expression();
565 Property* property = e->AsProperty(); 565 Property* property = e->AsProperty();
566 Variable* var = e->AsVariableProxy()->AsVariable(); 566 Variable* var = e->AsVariableProxy()->AsVariable();
567 567
568 if (property != NULL) { 568 if (property != NULL) {
569 // The expression is either a property or a variable proxy that rewrites 569 // The expression is either a property or a variable proxy that rewrites
570 // to a property. 570 // to a property.
571 LoadAndSpill(property->obj()); 571 LoadAndSpill(property->obj());
572 // We use a named reference if the key is a literal symbol, unless it is 572 // We use a named reference if the key is a literal symbol, unless it is
(...skipping 22 matching lines...) Expand all
595 } 595 }
596 } else { 596 } else {
597 // Anything else is a runtime error. 597 // Anything else is a runtime error.
598 LoadAndSpill(e); 598 LoadAndSpill(e);
599 frame_->CallRuntime(Runtime::kThrowReferenceError, 1); 599 frame_->CallRuntime(Runtime::kThrowReferenceError, 1);
600 } 600 }
601 } 601 }
602 602
603 603
604 void CodeGenerator::UnloadReference(Reference* ref) { 604 void CodeGenerator::UnloadReference(Reference* ref) {
605 VirtualFrame::SpilledScope spilled_scope(this); 605 VirtualFrame::SpilledScope spilled_scope;
606 // Pop a reference from the stack while preserving TOS. 606 // Pop a reference from the stack while preserving TOS.
607 Comment cmnt(masm_, "[ UnloadReference"); 607 Comment cmnt(masm_, "[ UnloadReference");
608 int size = ref->size(); 608 int size = ref->size();
609 if (size > 0) { 609 if (size > 0) {
610 frame_->EmitPop(r0); 610 frame_->EmitPop(r0);
611 frame_->Drop(size); 611 frame_->Drop(size);
612 frame_->EmitPush(r0); 612 frame_->EmitPush(r0);
613 } 613 }
614 } 614 }
615 615
616 616
617 // ECMA-262, section 9.2, page 30: ToBoolean(). Convert the given 617 // ECMA-262, section 9.2, page 30: ToBoolean(). Convert the given
618 // register to a boolean in the condition code register. The code 618 // register to a boolean in the condition code register. The code
619 // may jump to 'false_target' in case the register converts to 'false'. 619 // may jump to 'false_target' in case the register converts to 'false'.
620 void CodeGenerator::ToBoolean(JumpTarget* true_target, 620 void CodeGenerator::ToBoolean(JumpTarget* true_target,
621 JumpTarget* false_target) { 621 JumpTarget* false_target) {
622 VirtualFrame::SpilledScope spilled_scope(this); 622 VirtualFrame::SpilledScope spilled_scope;
623 // Note: The generated code snippet does not change stack variables. 623 // Note: The generated code snippet does not change stack variables.
624 // Only the condition code should be set. 624 // Only the condition code should be set.
625 frame_->EmitPop(r0); 625 frame_->EmitPop(r0);
626 626
627 // Fast case checks 627 // Fast case checks
628 628
629 // Check if the value is 'false'. 629 // Check if the value is 'false'.
630 __ cmp(r0, Operand(Factory::false_value())); 630 __ cmp(r0, Operand(Factory::false_value()));
631 false_target->Branch(eq); 631 false_target->Branch(eq);
632 632
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
694 } 694 }
695 695
696 #ifdef DEBUG 696 #ifdef DEBUG
697 void Print() { PrintF("GenericBinaryOpStub (%s)\n", Token::String(op_)); } 697 void Print() { PrintF("GenericBinaryOpStub (%s)\n", Token::String(op_)); }
698 #endif 698 #endif
699 }; 699 };
700 700
701 701
702 void CodeGenerator::GenericBinaryOperation(Token::Value op, 702 void CodeGenerator::GenericBinaryOperation(Token::Value op,
703 OverwriteMode overwrite_mode) { 703 OverwriteMode overwrite_mode) {
704 VirtualFrame::SpilledScope spilled_scope(this); 704 VirtualFrame::SpilledScope spilled_scope;
705 // sp[0] : y 705 // sp[0] : y
706 // sp[1] : x 706 // sp[1] : x
707 // result : r0 707 // result : r0
708 708
709 // Stub is entered with a call: 'return address' is in lr. 709 // Stub is entered with a call: 'return address' is in lr.
710 switch (op) { 710 switch (op) {
711 case Token::ADD: // fall through. 711 case Token::ADD: // fall through.
712 case Token::SUB: // fall through. 712 case Token::SUB: // fall through.
713 case Token::MUL: 713 case Token::MUL:
714 case Token::BIT_OR: 714 case Token::BIT_OR:
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
774 private: 774 private:
775 Token::Value op_; 775 Token::Value op_;
776 int value_; 776 int value_;
777 bool reversed_; 777 bool reversed_;
778 OverwriteMode overwrite_mode_; 778 OverwriteMode overwrite_mode_;
779 }; 779 };
780 780
781 781
782 void DeferredInlineSmiOperation::Generate() { 782 void DeferredInlineSmiOperation::Generate() {
783 enter()->Bind(); 783 enter()->Bind();
784 VirtualFrame::SpilledScope spilled_scope(generator()); 784 VirtualFrame::SpilledScope spilled_scope;
785 785
786 switch (op_) { 786 switch (op_) {
787 case Token::ADD: { 787 case Token::ADD: {
788 if (reversed_) { 788 if (reversed_) {
789 // revert optimistic add 789 // revert optimistic add
790 __ sub(r0, r0, Operand(Smi::FromInt(value_))); 790 __ sub(r0, r0, Operand(Smi::FromInt(value_)));
791 __ mov(r1, Operand(Smi::FromInt(value_))); 791 __ mov(r1, Operand(Smi::FromInt(value_)));
792 } else { 792 } else {
793 // revert optimistic add 793 // revert optimistic add
794 __ sub(r1, r0, Operand(Smi::FromInt(value_))); 794 __ sub(r1, r0, Operand(Smi::FromInt(value_)));
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
846 ASSERT(arg1.is_valid()); 846 ASSERT(arg1.is_valid());
847 generator()->frame()->CallStub(&igostub, &arg0, &arg1); 847 generator()->frame()->CallStub(&igostub, &arg0, &arg1);
848 exit_.Jump(); 848 exit_.Jump();
849 } 849 }
850 850
851 851
852 void CodeGenerator::SmiOperation(Token::Value op, 852 void CodeGenerator::SmiOperation(Token::Value op,
853 Handle<Object> value, 853 Handle<Object> value,
854 bool reversed, 854 bool reversed,
855 OverwriteMode mode) { 855 OverwriteMode mode) {
856 VirtualFrame::SpilledScope spilled_scope(this); 856 VirtualFrame::SpilledScope spilled_scope;
857 // NOTE: This is an attempt to inline (a bit) more of the code for 857 // NOTE: This is an attempt to inline (a bit) more of the code for
858 // some possible smi operations (like + and -) when (at least) one 858 // some possible smi operations (like + and -) when (at least) one
859 // of the operands is a literal smi. With this optimization, the 859 // of the operands is a literal smi. With this optimization, the
860 // performance of the system is increased by ~15%, and the generated 860 // performance of the system is increased by ~15%, and the generated
861 // code size is increased by ~1% (measured on a combination of 861 // code size is increased by ~1% (measured on a combination of
862 // different benchmarks). 862 // different benchmarks).
863 863
864 // sp[0] : operand 864 // sp[0] : operand
865 865
866 int int_value = Smi::cast(*value)->value(); 866 int int_value = Smi::cast(*value)->value();
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
980 } 980 }
981 GenericBinaryOperation(op, mode); 981 GenericBinaryOperation(op, mode);
982 break; 982 break;
983 } 983 }
984 984
985 exit.Bind(); 985 exit.Bind();
986 } 986 }
987 987
988 988
989 void CodeGenerator::Comparison(Condition cc, bool strict) { 989 void CodeGenerator::Comparison(Condition cc, bool strict) {
990 VirtualFrame::SpilledScope spilled_scope(this); 990 VirtualFrame::SpilledScope spilled_scope;
991 // sp[0] : y 991 // sp[0] : y
992 // sp[1] : x 992 // sp[1] : x
993 // result : cc register 993 // result : cc register
994 994
995 // Strict only makes sense for equality comparisons. 995 // Strict only makes sense for equality comparisons.
996 ASSERT(!strict || cc == eq); 996 ASSERT(!strict || cc == eq);
997 997
998 JumpTarget exit; 998 JumpTarget exit;
999 JumpTarget smi; 999 JumpTarget smi;
1000 // Implement '>' and '<=' by reversal to obtain ECMA-262 conversion order. 1000 // Implement '>' and '<=' by reversal to obtain ECMA-262 conversion order.
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
1069 #endif // defined(DEBUG) 1069 #endif // defined(DEBUG)
1070 1070
1071 Major MajorKey() { return CallFunction; } 1071 Major MajorKey() { return CallFunction; }
1072 int MinorKey() { return argc_; } 1072 int MinorKey() { return argc_; }
1073 }; 1073 };
1074 1074
1075 1075
1076 // Call the function on the stack with the given arguments. 1076 // Call the function on the stack with the given arguments.
1077 void CodeGenerator::CallWithArguments(ZoneList<Expression*>* args, 1077 void CodeGenerator::CallWithArguments(ZoneList<Expression*>* args,
1078 int position) { 1078 int position) {
1079 VirtualFrame::SpilledScope spilled_scope(this); 1079 VirtualFrame::SpilledScope spilled_scope;
1080 // Push the arguments ("left-to-right") on the stack. 1080 // Push the arguments ("left-to-right") on the stack.
1081 int arg_count = args->length(); 1081 int arg_count = args->length();
1082 for (int i = 0; i < arg_count; i++) { 1082 for (int i = 0; i < arg_count; i++) {
1083 LoadAndSpill(args->at(i)); 1083 LoadAndSpill(args->at(i));
1084 } 1084 }
1085 1085
1086 // Record the position for debugging purposes. 1086 // Record the position for debugging purposes.
1087 CodeForSourcePosition(position); 1087 CodeForSourcePosition(position);
1088 1088
1089 // Use the shared code stub to call the function. 1089 // Use the shared code stub to call the function.
1090 CallFunctionStub call_function(arg_count); 1090 CallFunctionStub call_function(arg_count);
1091 frame_->CallStub(&call_function, arg_count + 1); 1091 frame_->CallStub(&call_function, arg_count + 1);
1092 1092
1093 // Restore context and pop function from the stack. 1093 // Restore context and pop function from the stack.
1094 __ ldr(cp, frame_->Context()); 1094 __ ldr(cp, frame_->Context());
1095 frame_->Drop(); // discard the TOS 1095 frame_->Drop(); // discard the TOS
1096 } 1096 }
1097 1097
1098 1098
1099 void CodeGenerator::Branch(bool if_true, JumpTarget* target) { 1099 void CodeGenerator::Branch(bool if_true, JumpTarget* target) {
1100 VirtualFrame::SpilledScope spilled_scope(this); 1100 VirtualFrame::SpilledScope spilled_scope;
1101 ASSERT(has_cc()); 1101 ASSERT(has_cc());
1102 Condition cc = if_true ? cc_reg_ : NegateCondition(cc_reg_); 1102 Condition cc = if_true ? cc_reg_ : NegateCondition(cc_reg_);
1103 target->Branch(cc); 1103 target->Branch(cc);
1104 cc_reg_ = al; 1104 cc_reg_ = al;
1105 } 1105 }
1106 1106
1107 1107
1108 void CodeGenerator::CheckStack() { 1108 void CodeGenerator::CheckStack() {
1109 VirtualFrame::SpilledScope spilled_scope(this); 1109 VirtualFrame::SpilledScope spilled_scope;
1110 if (FLAG_check_stack) { 1110 if (FLAG_check_stack) {
1111 Comment cmnt(masm_, "[ check stack"); 1111 Comment cmnt(masm_, "[ check stack");
1112 StackCheckStub stub; 1112 StackCheckStub stub;
1113 frame_->CallStub(&stub, 0); 1113 frame_->CallStub(&stub, 0);
1114 } 1114 }
1115 } 1115 }
1116 1116
1117 1117
1118 void CodeGenerator::VisitAndSpill(Statement* statement) { 1118 void CodeGenerator::VisitAndSpill(Statement* statement) {
1119 ASSERT(in_spilled_code()); 1119 ASSERT(in_spilled_code());
(...skipping 14 matching lines...) Expand all
1134 frame_->SpillAll(); 1134 frame_->SpillAll();
1135 } 1135 }
1136 set_in_spilled_code(true); 1136 set_in_spilled_code(true);
1137 } 1137 }
1138 1138
1139 1139
1140 void CodeGenerator::VisitStatements(ZoneList<Statement*>* statements) { 1140 void CodeGenerator::VisitStatements(ZoneList<Statement*>* statements) {
1141 #ifdef DEBUG 1141 #ifdef DEBUG
1142 int original_height = frame_->height(); 1142 int original_height = frame_->height();
1143 #endif 1143 #endif
1144 VirtualFrame::SpilledScope spilled_scope(this); 1144 VirtualFrame::SpilledScope spilled_scope;
1145 for (int i = 0; frame_ != NULL && i < statements->length(); i++) { 1145 for (int i = 0; frame_ != NULL && i < statements->length(); i++) {
1146 VisitAndSpill(statements->at(i)); 1146 VisitAndSpill(statements->at(i));
1147 } 1147 }
1148 ASSERT(!has_valid_frame() || frame_->height() == original_height); 1148 ASSERT(!has_valid_frame() || frame_->height() == original_height);
1149 } 1149 }
1150 1150
1151 1151
1152 void CodeGenerator::VisitBlock(Block* node) { 1152 void CodeGenerator::VisitBlock(Block* node) {
1153 #ifdef DEBUG 1153 #ifdef DEBUG
1154 int original_height = frame_->height(); 1154 int original_height = frame_->height();
1155 #endif 1155 #endif
1156 VirtualFrame::SpilledScope spilled_scope(this); 1156 VirtualFrame::SpilledScope spilled_scope;
1157 Comment cmnt(masm_, "[ Block"); 1157 Comment cmnt(masm_, "[ Block");
1158 CodeForStatementPosition(node); 1158 CodeForStatementPosition(node);
1159 node->break_target()->set_direction(JumpTarget::FORWARD_ONLY); 1159 node->break_target()->set_direction(JumpTarget::FORWARD_ONLY);
1160 VisitStatementsAndSpill(node->statements()); 1160 VisitStatementsAndSpill(node->statements());
1161 if (node->break_target()->is_linked()) { 1161 if (node->break_target()->is_linked()) {
1162 node->break_target()->Bind(); 1162 node->break_target()->Bind();
1163 } 1163 }
1164 node->break_target()->Unuse(); 1164 node->break_target()->Unuse();
1165 ASSERT(!has_valid_frame() || frame_->height() == original_height); 1165 ASSERT(!has_valid_frame() || frame_->height() == original_height);
1166 } 1166 }
1167 1167
1168 1168
1169 void CodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 1169 void CodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
1170 VirtualFrame::SpilledScope spilled_scope(this); 1170 VirtualFrame::SpilledScope spilled_scope;
1171 __ mov(r0, Operand(pairs)); 1171 __ mov(r0, Operand(pairs));
1172 frame_->EmitPush(r0); 1172 frame_->EmitPush(r0);
1173 frame_->EmitPush(cp); 1173 frame_->EmitPush(cp);
1174 __ mov(r0, Operand(Smi::FromInt(is_eval() ? 1 : 0))); 1174 __ mov(r0, Operand(Smi::FromInt(is_eval() ? 1 : 0)));
1175 frame_->EmitPush(r0); 1175 frame_->EmitPush(r0);
1176 frame_->CallRuntime(Runtime::kDeclareGlobals, 3); 1176 frame_->CallRuntime(Runtime::kDeclareGlobals, 3);
1177 // The result is discarded. 1177 // The result is discarded.
1178 } 1178 }
1179 1179
1180 1180
1181 void CodeGenerator::VisitDeclaration(Declaration* node) { 1181 void CodeGenerator::VisitDeclaration(Declaration* node) {
1182 #ifdef DEBUG 1182 #ifdef DEBUG
1183 int original_height = frame_->height(); 1183 int original_height = frame_->height();
1184 #endif 1184 #endif
1185 VirtualFrame::SpilledScope spilled_scope(this); 1185 VirtualFrame::SpilledScope spilled_scope;
1186 Comment cmnt(masm_, "[ Declaration"); 1186 Comment cmnt(masm_, "[ Declaration");
1187 CodeForStatementPosition(node); 1187 CodeForStatementPosition(node);
1188 Variable* var = node->proxy()->var(); 1188 Variable* var = node->proxy()->var();
1189 ASSERT(var != NULL); // must have been resolved 1189 ASSERT(var != NULL); // must have been resolved
1190 Slot* slot = var->slot(); 1190 Slot* slot = var->slot();
1191 1191
1192 // If it was not possible to allocate the variable at compile time, 1192 // If it was not possible to allocate the variable at compile time,
1193 // we need to "declare" it at runtime to make sure it actually 1193 // we need to "declare" it at runtime to make sure it actually
1194 // exists in the local context. 1194 // exists in the local context.
1195 if (slot != NULL && slot->type() == Slot::LOOKUP) { 1195 if (slot != NULL && slot->type() == Slot::LOOKUP) {
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1247 frame_->Drop(); 1247 frame_->Drop();
1248 } 1248 }
1249 ASSERT(frame_->height() == original_height); 1249 ASSERT(frame_->height() == original_height);
1250 } 1250 }
1251 1251
1252 1252
1253 void CodeGenerator::VisitExpressionStatement(ExpressionStatement* node) { 1253 void CodeGenerator::VisitExpressionStatement(ExpressionStatement* node) {
1254 #ifdef DEBUG 1254 #ifdef DEBUG
1255 int original_height = frame_->height(); 1255 int original_height = frame_->height();
1256 #endif 1256 #endif
1257 VirtualFrame::SpilledScope spilled_scope(this); 1257 VirtualFrame::SpilledScope spilled_scope;
1258 Comment cmnt(masm_, "[ ExpressionStatement"); 1258 Comment cmnt(masm_, "[ ExpressionStatement");
1259 CodeForStatementPosition(node); 1259 CodeForStatementPosition(node);
1260 Expression* expression = node->expression(); 1260 Expression* expression = node->expression();
1261 expression->MarkAsStatement(); 1261 expression->MarkAsStatement();
1262 LoadAndSpill(expression); 1262 LoadAndSpill(expression);
1263 frame_->Drop(); 1263 frame_->Drop();
1264 ASSERT(frame_->height() == original_height); 1264 ASSERT(frame_->height() == original_height);
1265 } 1265 }
1266 1266
1267 1267
1268 void CodeGenerator::VisitEmptyStatement(EmptyStatement* node) { 1268 void CodeGenerator::VisitEmptyStatement(EmptyStatement* node) {
1269 #ifdef DEBUG 1269 #ifdef DEBUG
1270 int original_height = frame_->height(); 1270 int original_height = frame_->height();
1271 #endif 1271 #endif
1272 VirtualFrame::SpilledScope spilled_scope(this); 1272 VirtualFrame::SpilledScope spilled_scope;
1273 Comment cmnt(masm_, "// EmptyStatement"); 1273 Comment cmnt(masm_, "// EmptyStatement");
1274 CodeForStatementPosition(node); 1274 CodeForStatementPosition(node);
1275 // nothing to do 1275 // nothing to do
1276 ASSERT(frame_->height() == original_height); 1276 ASSERT(frame_->height() == original_height);
1277 } 1277 }
1278 1278
1279 1279
1280 void CodeGenerator::VisitIfStatement(IfStatement* node) { 1280 void CodeGenerator::VisitIfStatement(IfStatement* node) {
1281 #ifdef DEBUG 1281 #ifdef DEBUG
1282 int original_height = frame_->height(); 1282 int original_height = frame_->height();
1283 #endif 1283 #endif
1284 VirtualFrame::SpilledScope spilled_scope(this); 1284 VirtualFrame::SpilledScope spilled_scope;
1285 Comment cmnt(masm_, "[ IfStatement"); 1285 Comment cmnt(masm_, "[ IfStatement");
1286 // Generate different code depending on which parts of the if statement 1286 // Generate different code depending on which parts of the if statement
1287 // are present or not. 1287 // are present or not.
1288 bool has_then_stm = node->HasThenStatement(); 1288 bool has_then_stm = node->HasThenStatement();
1289 bool has_else_stm = node->HasElseStatement(); 1289 bool has_else_stm = node->HasElseStatement();
1290 1290
1291 CodeForStatementPosition(node); 1291 CodeForStatementPosition(node);
1292 1292
1293 JumpTarget exit; 1293 JumpTarget exit;
1294 if (has_then_stm && has_else_stm) { 1294 if (has_then_stm && has_else_stm) {
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1364 1364
1365 // end 1365 // end
1366 if (exit.is_linked()) { 1366 if (exit.is_linked()) {
1367 exit.Bind(); 1367 exit.Bind();
1368 } 1368 }
1369 ASSERT(!has_valid_frame() || frame_->height() == original_height); 1369 ASSERT(!has_valid_frame() || frame_->height() == original_height);
1370 } 1370 }
1371 1371
1372 1372
1373 void CodeGenerator::VisitContinueStatement(ContinueStatement* node) { 1373 void CodeGenerator::VisitContinueStatement(ContinueStatement* node) {
1374 VirtualFrame::SpilledScope spilled_scope(this); 1374 VirtualFrame::SpilledScope spilled_scope;
1375 Comment cmnt(masm_, "[ ContinueStatement"); 1375 Comment cmnt(masm_, "[ ContinueStatement");
1376 CodeForStatementPosition(node); 1376 CodeForStatementPosition(node);
1377 node->target()->continue_target()->Jump(); 1377 node->target()->continue_target()->Jump();
1378 } 1378 }
1379 1379
1380 1380
1381 void CodeGenerator::VisitBreakStatement(BreakStatement* node) { 1381 void CodeGenerator::VisitBreakStatement(BreakStatement* node) {
1382 VirtualFrame::SpilledScope spilled_scope(this); 1382 VirtualFrame::SpilledScope spilled_scope;
1383 Comment cmnt(masm_, "[ BreakStatement"); 1383 Comment cmnt(masm_, "[ BreakStatement");
1384 CodeForStatementPosition(node); 1384 CodeForStatementPosition(node);
1385 node->target()->break_target()->Jump(); 1385 node->target()->break_target()->Jump();
1386 } 1386 }
1387 1387
1388 1388
1389 void CodeGenerator::VisitReturnStatement(ReturnStatement* node) { 1389 void CodeGenerator::VisitReturnStatement(ReturnStatement* node) {
1390 VirtualFrame::SpilledScope spilled_scope(this); 1390 VirtualFrame::SpilledScope spilled_scope;
1391 Comment cmnt(masm_, "[ ReturnStatement"); 1391 Comment cmnt(masm_, "[ ReturnStatement");
1392 1392
1393 if (function_return_is_shadowed_) { 1393 if (function_return_is_shadowed_) {
1394 CodeForStatementPosition(node); 1394 CodeForStatementPosition(node);
1395 LoadAndSpill(node->expression()); 1395 LoadAndSpill(node->expression());
1396 frame_->EmitPop(r0); 1396 frame_->EmitPop(r0);
1397 function_return_.Jump(); 1397 function_return_.Jump();
1398 } else { 1398 } else {
1399 // Load the returned value. 1399 // Load the returned value.
1400 CodeForStatementPosition(node); 1400 CodeForStatementPosition(node);
1401 LoadAndSpill(node->expression()); 1401 LoadAndSpill(node->expression());
1402 1402
1403 // Pop the result from the frame and prepare the frame for 1403 // Pop the result from the frame and prepare the frame for
1404 // returning thus making it easier to merge. 1404 // returning thus making it easier to merge.
1405 frame_->EmitPop(r0); 1405 frame_->EmitPop(r0);
1406 frame_->PrepareForReturn(); 1406 frame_->PrepareForReturn();
1407 1407
1408 function_return_.Jump(); 1408 function_return_.Jump();
1409 } 1409 }
1410 } 1410 }
1411 1411
1412 1412
1413 void CodeGenerator::VisitWithEnterStatement(WithEnterStatement* node) { 1413 void CodeGenerator::VisitWithEnterStatement(WithEnterStatement* node) {
1414 #ifdef DEBUG 1414 #ifdef DEBUG
1415 int original_height = frame_->height(); 1415 int original_height = frame_->height();
1416 #endif 1416 #endif
1417 VirtualFrame::SpilledScope spilled_scope(this); 1417 VirtualFrame::SpilledScope spilled_scope;
1418 Comment cmnt(masm_, "[ WithEnterStatement"); 1418 Comment cmnt(masm_, "[ WithEnterStatement");
1419 CodeForStatementPosition(node); 1419 CodeForStatementPosition(node);
1420 LoadAndSpill(node->expression()); 1420 LoadAndSpill(node->expression());
1421 if (node->is_catch_block()) { 1421 if (node->is_catch_block()) {
1422 frame_->CallRuntime(Runtime::kPushCatchContext, 1); 1422 frame_->CallRuntime(Runtime::kPushCatchContext, 1);
1423 } else { 1423 } else {
1424 frame_->CallRuntime(Runtime::kPushContext, 1); 1424 frame_->CallRuntime(Runtime::kPushContext, 1);
1425 } 1425 }
1426 #ifdef DEBUG 1426 #ifdef DEBUG
1427 JumpTarget verified_true; 1427 JumpTarget verified_true;
1428 __ cmp(r0, Operand(cp)); 1428 __ cmp(r0, Operand(cp));
1429 verified_true.Branch(eq); 1429 verified_true.Branch(eq);
1430 __ stop("PushContext: r0 is expected to be the same as cp"); 1430 __ stop("PushContext: r0 is expected to be the same as cp");
1431 verified_true.Bind(); 1431 verified_true.Bind();
1432 #endif 1432 #endif
1433 // Update context local. 1433 // Update context local.
1434 __ str(cp, frame_->Context()); 1434 __ str(cp, frame_->Context());
1435 ASSERT(frame_->height() == original_height); 1435 ASSERT(frame_->height() == original_height);
1436 } 1436 }
1437 1437
1438 1438
1439 void CodeGenerator::VisitWithExitStatement(WithExitStatement* node) { 1439 void CodeGenerator::VisitWithExitStatement(WithExitStatement* node) {
1440 #ifdef DEBUG 1440 #ifdef DEBUG
1441 int original_height = frame_->height(); 1441 int original_height = frame_->height();
1442 #endif 1442 #endif
1443 VirtualFrame::SpilledScope spilled_scope(this); 1443 VirtualFrame::SpilledScope spilled_scope;
1444 Comment cmnt(masm_, "[ WithExitStatement"); 1444 Comment cmnt(masm_, "[ WithExitStatement");
1445 CodeForStatementPosition(node); 1445 CodeForStatementPosition(node);
1446 // Pop context. 1446 // Pop context.
1447 __ ldr(cp, ContextOperand(cp, Context::PREVIOUS_INDEX)); 1447 __ ldr(cp, ContextOperand(cp, Context::PREVIOUS_INDEX));
1448 // Update context local. 1448 // Update context local.
1449 __ str(cp, frame_->Context()); 1449 __ str(cp, frame_->Context());
1450 ASSERT(frame_->height() == original_height); 1450 ASSERT(frame_->height() == original_height);
1451 } 1451 }
1452 1452
1453 1453
1454 int CodeGenerator::FastCaseSwitchMaxOverheadFactor() { 1454 int CodeGenerator::FastCaseSwitchMaxOverheadFactor() {
1455 return kFastSwitchMaxOverheadFactor; 1455 return kFastSwitchMaxOverheadFactor;
1456 } 1456 }
1457 1457
1458 int CodeGenerator::FastCaseSwitchMinCaseCount() { 1458 int CodeGenerator::FastCaseSwitchMinCaseCount() {
1459 return kFastSwitchMinCaseCount; 1459 return kFastSwitchMinCaseCount;
1460 } 1460 }
1461 1461
1462 1462
1463 void CodeGenerator::GenerateFastCaseSwitchJumpTable( 1463 void CodeGenerator::GenerateFastCaseSwitchJumpTable(
1464 SwitchStatement* node, 1464 SwitchStatement* node,
1465 int min_index, 1465 int min_index,
1466 int range, 1466 int range,
1467 Label* default_label, 1467 Label* default_label,
1468 Vector<Label*> case_targets, 1468 Vector<Label*> case_targets,
1469 Vector<Label> case_labels) { 1469 Vector<Label> case_labels) {
1470 VirtualFrame::SpilledScope spilled_scope(this); 1470 VirtualFrame::SpilledScope spilled_scope;
1471 JumpTarget setup_default; 1471 JumpTarget setup_default;
1472 JumpTarget is_smi; 1472 JumpTarget is_smi;
1473 1473
1474 // A non-null default label pointer indicates a default case among 1474 // A non-null default label pointer indicates a default case among
1475 // the case labels. Otherwise we use the break target as a 1475 // the case labels. Otherwise we use the break target as a
1476 // "default" for failure to hit the jump table. 1476 // "default" for failure to hit the jump table.
1477 JumpTarget* default_target = 1477 JumpTarget* default_target =
1478 (default_label == NULL) ? node->break_target() : &setup_default; 1478 (default_label == NULL) ? node->break_target() : &setup_default;
1479 1479
1480 ASSERT(kSmiTag == 0 && kSmiTagSize <= 2); 1480 ASSERT(kSmiTag == 0 && kSmiTagSize <= 2);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1529 if (node->break_target()->is_linked()) { 1529 if (node->break_target()->is_linked()) {
1530 node->break_target()->Bind(); 1530 node->break_target()->Bind();
1531 } 1531 }
1532 } 1532 }
1533 1533
1534 1534
1535 void CodeGenerator::VisitSwitchStatement(SwitchStatement* node) { 1535 void CodeGenerator::VisitSwitchStatement(SwitchStatement* node) {
1536 #ifdef DEBUG 1536 #ifdef DEBUG
1537 int original_height = frame_->height(); 1537 int original_height = frame_->height();
1538 #endif 1538 #endif
1539 VirtualFrame::SpilledScope spilled_scope(this); 1539 VirtualFrame::SpilledScope spilled_scope;
1540 Comment cmnt(masm_, "[ SwitchStatement"); 1540 Comment cmnt(masm_, "[ SwitchStatement");
1541 CodeForStatementPosition(node); 1541 CodeForStatementPosition(node);
1542 node->break_target()->set_direction(JumpTarget::FORWARD_ONLY); 1542 node->break_target()->set_direction(JumpTarget::FORWARD_ONLY);
1543 1543
1544 LoadAndSpill(node->tag()); 1544 LoadAndSpill(node->tag());
1545 if (TryGenerateFastCaseSwitchStatement(node)) { 1545 if (TryGenerateFastCaseSwitchStatement(node)) {
1546 ASSERT(!has_valid_frame() || frame_->height() == original_height); 1546 ASSERT(!has_valid_frame() || frame_->height() == original_height);
1547 return; 1547 return;
1548 } 1548 }
1549 1549
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1623 } 1623 }
1624 node->break_target()->Unuse(); 1624 node->break_target()->Unuse();
1625 ASSERT(!has_valid_frame() || frame_->height() == original_height); 1625 ASSERT(!has_valid_frame() || frame_->height() == original_height);
1626 } 1626 }
1627 1627
1628 1628
1629 void CodeGenerator::VisitLoopStatement(LoopStatement* node) { 1629 void CodeGenerator::VisitLoopStatement(LoopStatement* node) {
1630 #ifdef DEBUG 1630 #ifdef DEBUG
1631 int original_height = frame_->height(); 1631 int original_height = frame_->height();
1632 #endif 1632 #endif
1633 VirtualFrame::SpilledScope spilled_scope(this); 1633 VirtualFrame::SpilledScope spilled_scope;
1634 Comment cmnt(masm_, "[ LoopStatement"); 1634 Comment cmnt(masm_, "[ LoopStatement");
1635 CodeForStatementPosition(node); 1635 CodeForStatementPosition(node);
1636 node->break_target()->set_direction(JumpTarget::FORWARD_ONLY); 1636 node->break_target()->set_direction(JumpTarget::FORWARD_ONLY);
1637 1637
1638 // Simple condition analysis. ALWAYS_TRUE and ALWAYS_FALSE represent a 1638 // Simple condition analysis. ALWAYS_TRUE and ALWAYS_FALSE represent a
1639 // known result for the test expression, with no side effects. 1639 // known result for the test expression, with no side effects.
1640 enum { ALWAYS_TRUE, ALWAYS_FALSE, DONT_KNOW } info = DONT_KNOW; 1640 enum { ALWAYS_TRUE, ALWAYS_FALSE, DONT_KNOW } info = DONT_KNOW;
1641 if (node->cond() == NULL) { 1641 if (node->cond() == NULL) {
1642 ASSERT(node->type() == LoopStatement::FOR_LOOP); 1642 ASSERT(node->type() == LoopStatement::FOR_LOOP);
1643 info = ALWAYS_TRUE; 1643 info = ALWAYS_TRUE;
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
1813 node->break_target()->Unuse(); 1813 node->break_target()->Unuse();
1814 ASSERT(!has_valid_frame() || frame_->height() == original_height); 1814 ASSERT(!has_valid_frame() || frame_->height() == original_height);
1815 } 1815 }
1816 1816
1817 1817
1818 void CodeGenerator::VisitForInStatement(ForInStatement* node) { 1818 void CodeGenerator::VisitForInStatement(ForInStatement* node) {
1819 #ifdef DEBUG 1819 #ifdef DEBUG
1820 int original_height = frame_->height(); 1820 int original_height = frame_->height();
1821 #endif 1821 #endif
1822 ASSERT(!in_spilled_code()); 1822 ASSERT(!in_spilled_code());
1823 VirtualFrame::SpilledScope spilled_scope(this); 1823 VirtualFrame::SpilledScope spilled_scope;
1824 Comment cmnt(masm_, "[ ForInStatement"); 1824 Comment cmnt(masm_, "[ ForInStatement");
1825 CodeForStatementPosition(node); 1825 CodeForStatementPosition(node);
1826 1826
1827 JumpTarget primitive; 1827 JumpTarget primitive;
1828 JumpTarget jsobject; 1828 JumpTarget jsobject;
1829 JumpTarget fixed_array; 1829 JumpTarget fixed_array;
1830 JumpTarget entry(JumpTarget::BIDIRECTIONAL); 1830 JumpTarget entry(JumpTarget::BIDIRECTIONAL);
1831 JumpTarget end_del_check; 1831 JumpTarget end_del_check;
1832 JumpTarget exit; 1832 JumpTarget exit;
1833 1833
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
2007 node->continue_target()->Unuse(); 2007 node->continue_target()->Unuse();
2008 node->break_target()->Unuse(); 2008 node->break_target()->Unuse();
2009 ASSERT(frame_->height() == original_height); 2009 ASSERT(frame_->height() == original_height);
2010 } 2010 }
2011 2011
2012 2012
2013 void CodeGenerator::VisitTryCatch(TryCatch* node) { 2013 void CodeGenerator::VisitTryCatch(TryCatch* node) {
2014 #ifdef DEBUG 2014 #ifdef DEBUG
2015 int original_height = frame_->height(); 2015 int original_height = frame_->height();
2016 #endif 2016 #endif
2017 VirtualFrame::SpilledScope spilled_scope(this); 2017 VirtualFrame::SpilledScope spilled_scope;
2018 Comment cmnt(masm_, "[ TryCatch"); 2018 Comment cmnt(masm_, "[ TryCatch");
2019 CodeForStatementPosition(node); 2019 CodeForStatementPosition(node);
2020 2020
2021 JumpTarget try_block; 2021 JumpTarget try_block;
2022 JumpTarget exit; 2022 JumpTarget exit;
2023 2023
2024 try_block.Call(); 2024 try_block.Call();
2025 // --- Catch block --- 2025 // --- Catch block ---
2026 frame_->EmitPush(r0); 2026 frame_->EmitPush(r0);
2027 2027
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
2134 2134
2135 exit.Bind(); 2135 exit.Bind();
2136 ASSERT(!has_valid_frame() || frame_->height() == original_height); 2136 ASSERT(!has_valid_frame() || frame_->height() == original_height);
2137 } 2137 }
2138 2138
2139 2139
2140 void CodeGenerator::VisitTryFinally(TryFinally* node) { 2140 void CodeGenerator::VisitTryFinally(TryFinally* node) {
2141 #ifdef DEBUG 2141 #ifdef DEBUG
2142 int original_height = frame_->height(); 2142 int original_height = frame_->height();
2143 #endif 2143 #endif
2144 VirtualFrame::SpilledScope spilled_scope(this); 2144 VirtualFrame::SpilledScope spilled_scope;
2145 Comment cmnt(masm_, "[ TryFinally"); 2145 Comment cmnt(masm_, "[ TryFinally");
2146 CodeForStatementPosition(node); 2146 CodeForStatementPosition(node);
2147 2147
2148 // State: Used to keep track of reason for entering the finally 2148 // State: Used to keep track of reason for entering the finally
2149 // block. Should probably be extended to hold information for 2149 // block. Should probably be extended to hold information for
2150 // break/continue from within the try block. 2150 // break/continue from within the try block.
2151 enum { FALLING, THROWING, JUMPING }; 2151 enum { FALLING, THROWING, JUMPING };
2152 2152
2153 JumpTarget try_block; 2153 JumpTarget try_block;
2154 JumpTarget finally_block; 2154 JumpTarget finally_block;
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
2321 exit.Bind(); 2321 exit.Bind();
2322 } 2322 }
2323 ASSERT(!has_valid_frame() || frame_->height() == original_height); 2323 ASSERT(!has_valid_frame() || frame_->height() == original_height);
2324 } 2324 }
2325 2325
2326 2326
2327 void CodeGenerator::VisitDebuggerStatement(DebuggerStatement* node) { 2327 void CodeGenerator::VisitDebuggerStatement(DebuggerStatement* node) {
2328 #ifdef DEBUG 2328 #ifdef DEBUG
2329 int original_height = frame_->height(); 2329 int original_height = frame_->height();
2330 #endif 2330 #endif
2331 VirtualFrame::SpilledScope spilled_scope(this); 2331 VirtualFrame::SpilledScope spilled_scope;
2332 Comment cmnt(masm_, "[ DebuggerStatament"); 2332 Comment cmnt(masm_, "[ DebuggerStatament");
2333 CodeForStatementPosition(node); 2333 CodeForStatementPosition(node);
2334 #ifdef ENABLE_DEBUGGER_SUPPORT 2334 #ifdef ENABLE_DEBUGGER_SUPPORT
2335 frame_->CallRuntime(Runtime::kDebugBreak, 0); 2335 frame_->CallRuntime(Runtime::kDebugBreak, 0);
2336 #endif 2336 #endif
2337 // Ignore the return value. 2337 // Ignore the return value.
2338 ASSERT(frame_->height() == original_height); 2338 ASSERT(frame_->height() == original_height);
2339 } 2339 }
2340 2340
2341 2341
2342 void CodeGenerator::InstantiateBoilerplate(Handle<JSFunction> boilerplate) { 2342 void CodeGenerator::InstantiateBoilerplate(Handle<JSFunction> boilerplate) {
2343 VirtualFrame::SpilledScope spilled_scope(this); 2343 VirtualFrame::SpilledScope spilled_scope;
2344 ASSERT(boilerplate->IsBoilerplate()); 2344 ASSERT(boilerplate->IsBoilerplate());
2345 2345
2346 // Push the boilerplate on the stack. 2346 // Push the boilerplate on the stack.
2347 __ mov(r0, Operand(boilerplate)); 2347 __ mov(r0, Operand(boilerplate));
2348 frame_->EmitPush(r0); 2348 frame_->EmitPush(r0);
2349 2349
2350 // Create a new closure. 2350 // Create a new closure.
2351 frame_->EmitPush(cp); 2351 frame_->EmitPush(cp);
2352 frame_->CallRuntime(Runtime::kNewClosure, 2); 2352 frame_->CallRuntime(Runtime::kNewClosure, 2);
2353 frame_->EmitPush(r0); 2353 frame_->EmitPush(r0);
2354 } 2354 }
2355 2355
2356 2356
2357 void CodeGenerator::VisitFunctionLiteral(FunctionLiteral* node) { 2357 void CodeGenerator::VisitFunctionLiteral(FunctionLiteral* node) {
2358 #ifdef DEBUG 2358 #ifdef DEBUG
2359 int original_height = frame_->height(); 2359 int original_height = frame_->height();
2360 #endif 2360 #endif
2361 VirtualFrame::SpilledScope spilled_scope(this); 2361 VirtualFrame::SpilledScope spilled_scope;
2362 Comment cmnt(masm_, "[ FunctionLiteral"); 2362 Comment cmnt(masm_, "[ FunctionLiteral");
2363 2363
2364 // Build the function boilerplate and instantiate it. 2364 // Build the function boilerplate and instantiate it.
2365 Handle<JSFunction> boilerplate = BuildBoilerplate(node); 2365 Handle<JSFunction> boilerplate = BuildBoilerplate(node);
2366 // Check for stack-overflow exception. 2366 // Check for stack-overflow exception.
2367 if (HasStackOverflow()) { 2367 if (HasStackOverflow()) {
2368 ASSERT(frame_->height() == original_height); 2368 ASSERT(frame_->height() == original_height);
2369 return; 2369 return;
2370 } 2370 }
2371 InstantiateBoilerplate(boilerplate); 2371 InstantiateBoilerplate(boilerplate);
2372 ASSERT(frame_->height() == original_height + 1); 2372 ASSERT(frame_->height() == original_height + 1);
2373 } 2373 }
2374 2374
2375 2375
2376 void CodeGenerator::VisitFunctionBoilerplateLiteral( 2376 void CodeGenerator::VisitFunctionBoilerplateLiteral(
2377 FunctionBoilerplateLiteral* node) { 2377 FunctionBoilerplateLiteral* node) {
2378 #ifdef DEBUG 2378 #ifdef DEBUG
2379 int original_height = frame_->height(); 2379 int original_height = frame_->height();
2380 #endif 2380 #endif
2381 VirtualFrame::SpilledScope spilled_scope(this); 2381 VirtualFrame::SpilledScope spilled_scope;
2382 Comment cmnt(masm_, "[ FunctionBoilerplateLiteral"); 2382 Comment cmnt(masm_, "[ FunctionBoilerplateLiteral");
2383 InstantiateBoilerplate(node->boilerplate()); 2383 InstantiateBoilerplate(node->boilerplate());
2384 ASSERT(frame_->height() == original_height + 1); 2384 ASSERT(frame_->height() == original_height + 1);
2385 } 2385 }
2386 2386
2387 2387
2388 void CodeGenerator::VisitConditional(Conditional* node) { 2388 void CodeGenerator::VisitConditional(Conditional* node) {
2389 #ifdef DEBUG 2389 #ifdef DEBUG
2390 int original_height = frame_->height(); 2390 int original_height = frame_->height();
2391 #endif 2391 #endif
2392 VirtualFrame::SpilledScope spilled_scope(this); 2392 VirtualFrame::SpilledScope spilled_scope;
2393 Comment cmnt(masm_, "[ Conditional"); 2393 Comment cmnt(masm_, "[ Conditional");
2394 JumpTarget then; 2394 JumpTarget then;
2395 JumpTarget else_; 2395 JumpTarget else_;
2396 JumpTarget exit; 2396 JumpTarget exit;
2397 LoadConditionAndSpill(node->condition(), NOT_INSIDE_TYPEOF, 2397 LoadConditionAndSpill(node->condition(), NOT_INSIDE_TYPEOF,
2398 &then, &else_, true); 2398 &then, &else_, true);
2399 Branch(false, &else_); 2399 Branch(false, &else_);
2400 then.Bind(); 2400 then.Bind();
2401 LoadAndSpill(node->then_expression(), typeof_state()); 2401 LoadAndSpill(node->then_expression(), typeof_state());
2402 exit.Jump(); 2402 exit.Jump();
2403 else_.Bind(); 2403 else_.Bind();
2404 LoadAndSpill(node->else_expression(), typeof_state()); 2404 LoadAndSpill(node->else_expression(), typeof_state());
2405 exit.Bind(); 2405 exit.Bind();
2406 ASSERT(frame_->height() == original_height + 1); 2406 ASSERT(frame_->height() == original_height + 1);
2407 } 2407 }
2408 2408
2409 2409
2410 void CodeGenerator::LoadFromSlot(Slot* slot, TypeofState typeof_state) { 2410 void CodeGenerator::LoadFromSlot(Slot* slot, TypeofState typeof_state) {
2411 VirtualFrame::SpilledScope spilled_scope(this); 2411 VirtualFrame::SpilledScope spilled_scope;
2412 if (slot->type() == Slot::LOOKUP) { 2412 if (slot->type() == Slot::LOOKUP) {
2413 ASSERT(slot->var()->is_dynamic()); 2413 ASSERT(slot->var()->is_dynamic());
2414 2414
2415 JumpTarget slow; 2415 JumpTarget slow;
2416 JumpTarget done; 2416 JumpTarget done;
2417 2417
2418 // Generate fast-case code for variables that might be shadowed by 2418 // Generate fast-case code for variables that might be shadowed by
2419 // eval-introduced variables. Eval is used a lot without 2419 // eval-introduced variables. Eval is used a lot without
2420 // introducing variables. In those cases, we do not want to 2420 // introducing variables. In those cases, we do not want to
2421 // perform a runtime call for all variables in the scope 2421 // perform a runtime call for all variables in the scope
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
2554 2554
2555 // Drop the global object. The result is in r0. 2555 // Drop the global object. The result is in r0.
2556 frame_->Drop(); 2556 frame_->Drop();
2557 } 2557 }
2558 2558
2559 2559
2560 void CodeGenerator::VisitSlot(Slot* node) { 2560 void CodeGenerator::VisitSlot(Slot* node) {
2561 #ifdef DEBUG 2561 #ifdef DEBUG
2562 int original_height = frame_->height(); 2562 int original_height = frame_->height();
2563 #endif 2563 #endif
2564 VirtualFrame::SpilledScope spilled_scope(this); 2564 VirtualFrame::SpilledScope spilled_scope;
2565 Comment cmnt(masm_, "[ Slot"); 2565 Comment cmnt(masm_, "[ Slot");
2566 LoadFromSlot(node, typeof_state()); 2566 LoadFromSlot(node, typeof_state());
2567 ASSERT(frame_->height() == original_height + 1); 2567 ASSERT(frame_->height() == original_height + 1);
2568 } 2568 }
2569 2569
2570 2570
2571 void CodeGenerator::VisitVariableProxy(VariableProxy* node) { 2571 void CodeGenerator::VisitVariableProxy(VariableProxy* node) {
2572 #ifdef DEBUG 2572 #ifdef DEBUG
2573 int original_height = frame_->height(); 2573 int original_height = frame_->height();
2574 #endif 2574 #endif
2575 VirtualFrame::SpilledScope spilled_scope(this); 2575 VirtualFrame::SpilledScope spilled_scope;
2576 Comment cmnt(masm_, "[ VariableProxy"); 2576 Comment cmnt(masm_, "[ VariableProxy");
2577 2577
2578 Variable* var = node->var(); 2578 Variable* var = node->var();
2579 Expression* expr = var->rewrite(); 2579 Expression* expr = var->rewrite();
2580 if (expr != NULL) { 2580 if (expr != NULL) {
2581 Visit(expr); 2581 Visit(expr);
2582 } else { 2582 } else {
2583 ASSERT(var->is_global()); 2583 ASSERT(var->is_global());
2584 Reference ref(this, node); 2584 Reference ref(this, node);
2585 ref.GetValueAndSpill(typeof_state()); 2585 ref.GetValueAndSpill(typeof_state());
2586 } 2586 }
2587 ASSERT(frame_->height() == original_height + 1); 2587 ASSERT(frame_->height() == original_height + 1);
2588 } 2588 }
2589 2589
2590 2590
2591 void CodeGenerator::VisitLiteral(Literal* node) { 2591 void CodeGenerator::VisitLiteral(Literal* node) {
2592 #ifdef DEBUG 2592 #ifdef DEBUG
2593 int original_height = frame_->height(); 2593 int original_height = frame_->height();
2594 #endif 2594 #endif
2595 VirtualFrame::SpilledScope spilled_scope(this); 2595 VirtualFrame::SpilledScope spilled_scope;
2596 Comment cmnt(masm_, "[ Literal"); 2596 Comment cmnt(masm_, "[ Literal");
2597 __ mov(r0, Operand(node->handle())); 2597 __ mov(r0, Operand(node->handle()));
2598 frame_->EmitPush(r0); 2598 frame_->EmitPush(r0);
2599 ASSERT(frame_->height() == original_height + 1); 2599 ASSERT(frame_->height() == original_height + 1);
2600 } 2600 }
2601 2601
2602 2602
2603 void CodeGenerator::VisitRegExpLiteral(RegExpLiteral* node) { 2603 void CodeGenerator::VisitRegExpLiteral(RegExpLiteral* node) {
2604 #ifdef DEBUG 2604 #ifdef DEBUG
2605 int original_height = frame_->height(); 2605 int original_height = frame_->height();
2606 #endif 2606 #endif
2607 VirtualFrame::SpilledScope spilled_scope(this); 2607 VirtualFrame::SpilledScope spilled_scope;
2608 Comment cmnt(masm_, "[ RexExp Literal"); 2608 Comment cmnt(masm_, "[ RexExp Literal");
2609 2609
2610 // Retrieve the literal array and check the allocated entry. 2610 // Retrieve the literal array and check the allocated entry.
2611 2611
2612 // Load the function of this activation. 2612 // Load the function of this activation.
2613 __ ldr(r1, frame_->Function()); 2613 __ ldr(r1, frame_->Function());
2614 2614
2615 // Load the literals array of the function. 2615 // Load the literals array of the function.
2616 __ ldr(r1, FieldMemOperand(r1, JSFunction::kLiteralsOffset)); 2616 __ ldr(r1, FieldMemOperand(r1, JSFunction::kLiteralsOffset));
2617 2617
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
2657 virtual void Generate(); 2657 virtual void Generate();
2658 2658
2659 private: 2659 private:
2660 ObjectLiteral* node_; 2660 ObjectLiteral* node_;
2661 }; 2661 };
2662 2662
2663 2663
2664 void DeferredObjectLiteral::Generate() { 2664 void DeferredObjectLiteral::Generate() {
2665 // Argument is passed in r1. 2665 // Argument is passed in r1.
2666 enter()->Bind(); 2666 enter()->Bind();
2667 VirtualFrame::SpilledScope spilled_scope(generator()); 2667 VirtualFrame::SpilledScope spilled_scope;
2668 2668
2669 // If the entry is undefined we call the runtime system to compute 2669 // If the entry is undefined we call the runtime system to compute
2670 // the literal. 2670 // the literal.
2671 2671
2672 VirtualFrame* frame = generator()->frame(); 2672 VirtualFrame* frame = generator()->frame();
2673 // Literal array (0). 2673 // Literal array (0).
2674 frame->EmitPush(r1); 2674 frame->EmitPush(r1);
2675 // Literal index (1). 2675 // Literal index (1).
2676 __ mov(r0, Operand(Smi::FromInt(node_->literal_index()))); 2676 __ mov(r0, Operand(Smi::FromInt(node_->literal_index())));
2677 frame->EmitPush(r0); 2677 frame->EmitPush(r0);
2678 // Constant properties (2). 2678 // Constant properties (2).
2679 __ mov(r0, Operand(node_->constant_properties())); 2679 __ mov(r0, Operand(node_->constant_properties()));
2680 frame->EmitPush(r0); 2680 frame->EmitPush(r0);
2681 Result boilerplate = 2681 Result boilerplate =
2682 frame->CallRuntime(Runtime::kCreateObjectLiteralBoilerplate, 3); 2682 frame->CallRuntime(Runtime::kCreateObjectLiteralBoilerplate, 3);
2683 __ mov(r2, Operand(boilerplate.reg())); 2683 __ mov(r2, Operand(boilerplate.reg()));
2684 // Result is returned in r2. 2684 // Result is returned in r2.
2685 exit_.Jump(); 2685 exit_.Jump();
2686 } 2686 }
2687 2687
2688 2688
2689 void CodeGenerator::VisitObjectLiteral(ObjectLiteral* node) { 2689 void CodeGenerator::VisitObjectLiteral(ObjectLiteral* node) {
2690 #ifdef DEBUG 2690 #ifdef DEBUG
2691 int original_height = frame_->height(); 2691 int original_height = frame_->height();
2692 #endif 2692 #endif
2693 VirtualFrame::SpilledScope spilled_scope(this); 2693 VirtualFrame::SpilledScope spilled_scope;
2694 Comment cmnt(masm_, "[ ObjectLiteral"); 2694 Comment cmnt(masm_, "[ ObjectLiteral");
2695 2695
2696 DeferredObjectLiteral* deferred = new DeferredObjectLiteral(this, node); 2696 DeferredObjectLiteral* deferred = new DeferredObjectLiteral(this, node);
2697 2697
2698 // Retrieve the literal array and check the allocated entry. 2698 // Retrieve the literal array and check the allocated entry.
2699 2699
2700 // Load the function of this activation. 2700 // Load the function of this activation.
2701 __ ldr(r1, frame_->Function()); 2701 __ ldr(r1, frame_->Function());
2702 2702
2703 // Load the literals array of the function. 2703 // Load the literals array of the function.
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
2786 virtual void Generate(); 2786 virtual void Generate();
2787 2787
2788 private: 2788 private:
2789 ArrayLiteral* node_; 2789 ArrayLiteral* node_;
2790 }; 2790 };
2791 2791
2792 2792
2793 void DeferredArrayLiteral::Generate() { 2793 void DeferredArrayLiteral::Generate() {
2794 // Argument is passed in r1. 2794 // Argument is passed in r1.
2795 enter()->Bind(); 2795 enter()->Bind();
2796 VirtualFrame::SpilledScope spilled_scope(generator()); 2796 VirtualFrame::SpilledScope spilled_scope;
2797 2797
2798 // If the entry is undefined we call the runtime system to computed 2798 // If the entry is undefined we call the runtime system to computed
2799 // the literal. 2799 // the literal.
2800 2800
2801 VirtualFrame* frame = generator()->frame(); 2801 VirtualFrame* frame = generator()->frame();
2802 // Literal array (0). 2802 // Literal array (0).
2803 frame->EmitPush(r1); 2803 frame->EmitPush(r1);
2804 // Literal index (1). 2804 // Literal index (1).
2805 __ mov(r0, Operand(Smi::FromInt(node_->literal_index()))); 2805 __ mov(r0, Operand(Smi::FromInt(node_->literal_index())));
2806 frame->EmitPush(r0); 2806 frame->EmitPush(r0);
2807 // Constant properties (2). 2807 // Constant properties (2).
2808 __ mov(r0, Operand(node_->literals())); 2808 __ mov(r0, Operand(node_->literals()));
2809 frame->EmitPush(r0); 2809 frame->EmitPush(r0);
2810 Result boilerplate = 2810 Result boilerplate =
2811 frame->CallRuntime(Runtime::kCreateArrayLiteralBoilerplate, 3); 2811 frame->CallRuntime(Runtime::kCreateArrayLiteralBoilerplate, 3);
2812 __ mov(r2, Operand(boilerplate.reg())); 2812 __ mov(r2, Operand(boilerplate.reg()));
2813 // Result is returned in r2. 2813 // Result is returned in r2.
2814 exit_.Jump(); 2814 exit_.Jump();
2815 } 2815 }
2816 2816
2817 2817
2818 void CodeGenerator::VisitArrayLiteral(ArrayLiteral* node) { 2818 void CodeGenerator::VisitArrayLiteral(ArrayLiteral* node) {
2819 #ifdef DEBUG 2819 #ifdef DEBUG
2820 int original_height = frame_->height(); 2820 int original_height = frame_->height();
2821 #endif 2821 #endif
2822 VirtualFrame::SpilledScope spilled_scope(this); 2822 VirtualFrame::SpilledScope spilled_scope;
2823 Comment cmnt(masm_, "[ ArrayLiteral"); 2823 Comment cmnt(masm_, "[ ArrayLiteral");
2824 2824
2825 DeferredArrayLiteral* deferred = new DeferredArrayLiteral(this, node); 2825 DeferredArrayLiteral* deferred = new DeferredArrayLiteral(this, node);
2826 2826
2827 // Retrieve the literal array and check the allocated entry. 2827 // Retrieve the literal array and check the allocated entry.
2828 2828
2829 // Load the function of this activation. 2829 // Load the function of this activation.
2830 __ ldr(r1, frame_->Function()); 2830 __ ldr(r1, frame_->Function());
2831 2831
2832 // Load the literals array of the function. 2832 // Load the literals array of the function.
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
2886 } 2886 }
2887 ASSERT(frame_->height() == original_height + 1); 2887 ASSERT(frame_->height() == original_height + 1);
2888 } 2888 }
2889 2889
2890 2890
2891 void CodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* node) { 2891 void CodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* node) {
2892 #ifdef DEBUG 2892 #ifdef DEBUG
2893 int original_height = frame_->height(); 2893 int original_height = frame_->height();
2894 #endif 2894 #endif
2895 ASSERT(!in_spilled_code()); 2895 ASSERT(!in_spilled_code());
2896 VirtualFrame::SpilledScope spilled_scope(this); 2896 VirtualFrame::SpilledScope spilled_scope;
2897 // Call runtime routine to allocate the catch extension object and 2897 // Call runtime routine to allocate the catch extension object and
2898 // assign the exception value to the catch variable. 2898 // assign the exception value to the catch variable.
2899 Comment cmnt(masm_, "[ CatchExtensionObject"); 2899 Comment cmnt(masm_, "[ CatchExtensionObject");
2900 LoadAndSpill(node->key()); 2900 LoadAndSpill(node->key());
2901 LoadAndSpill(node->value()); 2901 LoadAndSpill(node->value());
2902 Result result = 2902 Result result =
2903 frame_->CallRuntime(Runtime::kCreateCatchExtensionObject, 2); 2903 frame_->CallRuntime(Runtime::kCreateCatchExtensionObject, 2);
2904 frame_->EmitPush(result.reg()); 2904 frame_->EmitPush(result.reg());
2905 ASSERT(frame_->height() == original_height + 1); 2905 ASSERT(frame_->height() == original_height + 1);
2906 } 2906 }
2907 2907
2908 2908
2909 void CodeGenerator::VisitAssignment(Assignment* node) { 2909 void CodeGenerator::VisitAssignment(Assignment* node) {
2910 #ifdef DEBUG 2910 #ifdef DEBUG
2911 int original_height = frame_->height(); 2911 int original_height = frame_->height();
2912 #endif 2912 #endif
2913 VirtualFrame::SpilledScope spilled_scope(this); 2913 VirtualFrame::SpilledScope spilled_scope;
2914 Comment cmnt(masm_, "[ Assignment"); 2914 Comment cmnt(masm_, "[ Assignment");
2915 CodeForStatementPosition(node); 2915 CodeForStatementPosition(node);
2916 2916
2917 { Reference target(this, node->target()); 2917 { Reference target(this, node->target());
2918 if (target.is_illegal()) { 2918 if (target.is_illegal()) {
2919 // Fool the virtual frame into thinking that we left the assignment's 2919 // Fool the virtual frame into thinking that we left the assignment's
2920 // value on the frame. 2920 // value on the frame.
2921 __ mov(r0, Operand(Smi::FromInt(0))); 2921 __ mov(r0, Operand(Smi::FromInt(0)));
2922 frame_->EmitPush(r0); 2922 frame_->EmitPush(r0);
2923 ASSERT(frame_->height() == original_height + 1); 2923 ASSERT(frame_->height() == original_height + 1);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
2971 } 2971 }
2972 } 2972 }
2973 ASSERT(frame_->height() == original_height + 1); 2973 ASSERT(frame_->height() == original_height + 1);
2974 } 2974 }
2975 2975
2976 2976
2977 void CodeGenerator::VisitThrow(Throw* node) { 2977 void CodeGenerator::VisitThrow(Throw* node) {
2978 #ifdef DEBUG 2978 #ifdef DEBUG
2979 int original_height = frame_->height(); 2979 int original_height = frame_->height();
2980 #endif 2980 #endif
2981 VirtualFrame::SpilledScope spilled_scope(this); 2981 VirtualFrame::SpilledScope spilled_scope;
2982 Comment cmnt(masm_, "[ Throw"); 2982 Comment cmnt(masm_, "[ Throw");
2983 2983
2984 LoadAndSpill(node->exception()); 2984 LoadAndSpill(node->exception());
2985 CodeForSourcePosition(node->position()); 2985 CodeForSourcePosition(node->position());
2986 frame_->CallRuntime(Runtime::kThrow, 1); 2986 frame_->CallRuntime(Runtime::kThrow, 1);
2987 frame_->EmitPush(r0); 2987 frame_->EmitPush(r0);
2988 ASSERT(frame_->height() == original_height + 1); 2988 ASSERT(frame_->height() == original_height + 1);
2989 } 2989 }
2990 2990
2991 2991
2992 void CodeGenerator::VisitProperty(Property* node) { 2992 void CodeGenerator::VisitProperty(Property* node) {
2993 #ifdef DEBUG 2993 #ifdef DEBUG
2994 int original_height = frame_->height(); 2994 int original_height = frame_->height();
2995 #endif 2995 #endif
2996 VirtualFrame::SpilledScope spilled_scope(this); 2996 VirtualFrame::SpilledScope spilled_scope;
2997 Comment cmnt(masm_, "[ Property"); 2997 Comment cmnt(masm_, "[ Property");
2998 2998
2999 { Reference property(this, node); 2999 { Reference property(this, node);
3000 property.GetValueAndSpill(typeof_state()); 3000 property.GetValueAndSpill(typeof_state());
3001 } 3001 }
3002 ASSERT(frame_->height() == original_height + 1); 3002 ASSERT(frame_->height() == original_height + 1);
3003 } 3003 }
3004 3004
3005 3005
3006 void CodeGenerator::VisitCall(Call* node) { 3006 void CodeGenerator::VisitCall(Call* node) {
3007 #ifdef DEBUG 3007 #ifdef DEBUG
3008 int original_height = frame_->height(); 3008 int original_height = frame_->height();
3009 #endif 3009 #endif
3010 VirtualFrame::SpilledScope spilled_scope(this); 3010 VirtualFrame::SpilledScope spilled_scope;
3011 Comment cmnt(masm_, "[ Call"); 3011 Comment cmnt(masm_, "[ Call");
3012 3012
3013 ZoneList<Expression*>* args = node->arguments(); 3013 ZoneList<Expression*>* args = node->arguments();
3014 3014
3015 CodeForStatementPosition(node); 3015 CodeForStatementPosition(node);
3016 // Standard function call. 3016 // Standard function call.
3017 3017
3018 // Check if the function is a variable or a property. 3018 // Check if the function is a variable or a property.
3019 Expression* function = node->expression(); 3019 Expression* function = node->expression();
3020 Variable* var = function->AsVariableProxy()->AsVariable(); 3020 Variable* var = function->AsVariableProxy()->AsVariable();
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
3149 frame_->EmitPush(r0); 3149 frame_->EmitPush(r0);
3150 } 3150 }
3151 ASSERT(frame_->height() == original_height + 1); 3151 ASSERT(frame_->height() == original_height + 1);
3152 } 3152 }
3153 3153
3154 3154
3155 void CodeGenerator::VisitCallEval(CallEval* node) { 3155 void CodeGenerator::VisitCallEval(CallEval* node) {
3156 #ifdef DEBUG 3156 #ifdef DEBUG
3157 int original_height = frame_->height(); 3157 int original_height = frame_->height();
3158 #endif 3158 #endif
3159 VirtualFrame::SpilledScope spilled_scope(this); 3159 VirtualFrame::SpilledScope spilled_scope;
3160 Comment cmnt(masm_, "[ CallEval"); 3160 Comment cmnt(masm_, "[ CallEval");
3161 3161
3162 // In a call to eval, we first call %ResolvePossiblyDirectEval to resolve 3162 // In a call to eval, we first call %ResolvePossiblyDirectEval to resolve
3163 // the function we need to call and the receiver of the call. 3163 // the function we need to call and the receiver of the call.
3164 // Then we call the resolved function using the given arguments. 3164 // Then we call the resolved function using the given arguments.
3165 3165
3166 ZoneList<Expression*>* args = node->arguments(); 3166 ZoneList<Expression*>* args = node->arguments();
3167 Expression* function = node->expression(); 3167 Expression* function = node->expression();
3168 3168
3169 CodeForStatementPosition(node); 3169 CodeForStatementPosition(node);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
3207 frame_->Drop(); 3207 frame_->Drop();
3208 frame_->EmitPush(r0); 3208 frame_->EmitPush(r0);
3209 ASSERT(frame_->height() == original_height + 1); 3209 ASSERT(frame_->height() == original_height + 1);
3210 } 3210 }
3211 3211
3212 3212
3213 void CodeGenerator::VisitCallNew(CallNew* node) { 3213 void CodeGenerator::VisitCallNew(CallNew* node) {
3214 #ifdef DEBUG 3214 #ifdef DEBUG
3215 int original_height = frame_->height(); 3215 int original_height = frame_->height();
3216 #endif 3216 #endif
3217 VirtualFrame::SpilledScope spilled_scope(this); 3217 VirtualFrame::SpilledScope spilled_scope;
3218 Comment cmnt(masm_, "[ CallNew"); 3218 Comment cmnt(masm_, "[ CallNew");
3219 CodeForStatementPosition(node); 3219 CodeForStatementPosition(node);
3220 3220
3221 // According to ECMA-262, section 11.2.2, page 44, the function 3221 // According to ECMA-262, section 11.2.2, page 44, the function
3222 // expression in new calls must be evaluated before the 3222 // expression in new calls must be evaluated before the
3223 // arguments. This is different from ordinary calls, where the 3223 // arguments. This is different from ordinary calls, where the
3224 // actual function to call is resolved after the arguments have been 3224 // actual function to call is resolved after the arguments have been
3225 // evaluated. 3225 // evaluated.
3226 3226
3227 // Compute function to call and use the global object as the 3227 // Compute function to call and use the global object as the
(...skipping 29 matching lines...) Expand all
3257 &function, 3257 &function,
3258 arg_count + 1); 3258 arg_count + 1);
3259 3259
3260 // Discard old TOS value and push r0 on the stack (same as Pop(), push(r0)). 3260 // Discard old TOS value and push r0 on the stack (same as Pop(), push(r0)).
3261 __ str(r0, frame_->Top()); 3261 __ str(r0, frame_->Top());
3262 ASSERT(frame_->height() == original_height + 1); 3262 ASSERT(frame_->height() == original_height + 1);
3263 } 3263 }
3264 3264
3265 3265
3266 void CodeGenerator::GenerateValueOf(ZoneList<Expression*>* args) { 3266 void CodeGenerator::GenerateValueOf(ZoneList<Expression*>* args) {
3267 VirtualFrame::SpilledScope spilled_scope(this); 3267 VirtualFrame::SpilledScope spilled_scope;
3268 ASSERT(args->length() == 1); 3268 ASSERT(args->length() == 1);
3269 JumpTarget leave; 3269 JumpTarget leave;
3270 LoadAndSpill(args->at(0)); 3270 LoadAndSpill(args->at(0));
3271 frame_->EmitPop(r0); // r0 contains object. 3271 frame_->EmitPop(r0); // r0 contains object.
3272 // if (object->IsSmi()) return the object. 3272 // if (object->IsSmi()) return the object.
3273 __ tst(r0, Operand(kSmiTagMask)); 3273 __ tst(r0, Operand(kSmiTagMask));
3274 leave.Branch(eq); 3274 leave.Branch(eq);
3275 // It is a heap object - get map. 3275 // It is a heap object - get map.
3276 __ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset)); 3276 __ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset));
3277 __ ldrb(r1, FieldMemOperand(r1, Map::kInstanceTypeOffset)); 3277 __ ldrb(r1, FieldMemOperand(r1, Map::kInstanceTypeOffset));
3278 // if (!object->IsJSValue()) return the object. 3278 // if (!object->IsJSValue()) return the object.
3279 __ cmp(r1, Operand(JS_VALUE_TYPE)); 3279 __ cmp(r1, Operand(JS_VALUE_TYPE));
3280 leave.Branch(ne); 3280 leave.Branch(ne);
3281 // Load the value. 3281 // Load the value.
3282 __ ldr(r0, FieldMemOperand(r0, JSValue::kValueOffset)); 3282 __ ldr(r0, FieldMemOperand(r0, JSValue::kValueOffset));
3283 leave.Bind(); 3283 leave.Bind();
3284 frame_->EmitPush(r0); 3284 frame_->EmitPush(r0);
3285 } 3285 }
3286 3286
3287 3287
3288 void CodeGenerator::GenerateSetValueOf(ZoneList<Expression*>* args) { 3288 void CodeGenerator::GenerateSetValueOf(ZoneList<Expression*>* args) {
3289 VirtualFrame::SpilledScope spilled_scope(this); 3289 VirtualFrame::SpilledScope spilled_scope;
3290 ASSERT(args->length() == 2); 3290 ASSERT(args->length() == 2);
3291 JumpTarget leave; 3291 JumpTarget leave;
3292 LoadAndSpill(args->at(0)); // Load the object. 3292 LoadAndSpill(args->at(0)); // Load the object.
3293 LoadAndSpill(args->at(1)); // Load the value. 3293 LoadAndSpill(args->at(1)); // Load the value.
3294 frame_->EmitPop(r0); // r0 contains value 3294 frame_->EmitPop(r0); // r0 contains value
3295 frame_->EmitPop(r1); // r1 contains object 3295 frame_->EmitPop(r1); // r1 contains object
3296 // if (object->IsSmi()) return object. 3296 // if (object->IsSmi()) return object.
3297 __ tst(r1, Operand(kSmiTagMask)); 3297 __ tst(r1, Operand(kSmiTagMask));
3298 leave.Branch(eq); 3298 leave.Branch(eq);
3299 // It is a heap object - get map. 3299 // It is a heap object - get map.
3300 __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); 3300 __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset));
3301 __ ldrb(r2, FieldMemOperand(r2, Map::kInstanceTypeOffset)); 3301 __ ldrb(r2, FieldMemOperand(r2, Map::kInstanceTypeOffset));
3302 // if (!object->IsJSValue()) return object. 3302 // if (!object->IsJSValue()) return object.
3303 __ cmp(r2, Operand(JS_VALUE_TYPE)); 3303 __ cmp(r2, Operand(JS_VALUE_TYPE));
3304 leave.Branch(ne); 3304 leave.Branch(ne);
3305 // Store the value. 3305 // Store the value.
3306 __ str(r0, FieldMemOperand(r1, JSValue::kValueOffset)); 3306 __ str(r0, FieldMemOperand(r1, JSValue::kValueOffset));
3307 // Update the write barrier. 3307 // Update the write barrier.
3308 __ mov(r2, Operand(JSValue::kValueOffset - kHeapObjectTag)); 3308 __ mov(r2, Operand(JSValue::kValueOffset - kHeapObjectTag));
3309 __ RecordWrite(r1, r2, r3); 3309 __ RecordWrite(r1, r2, r3);
3310 // Leave. 3310 // Leave.
3311 leave.Bind(); 3311 leave.Bind();
3312 frame_->EmitPush(r0); 3312 frame_->EmitPush(r0);
3313 } 3313 }
3314 3314
3315 3315
3316 void CodeGenerator::GenerateIsSmi(ZoneList<Expression*>* args) { 3316 void CodeGenerator::GenerateIsSmi(ZoneList<Expression*>* args) {
3317 VirtualFrame::SpilledScope spilled_scope(this); 3317 VirtualFrame::SpilledScope spilled_scope;
3318 ASSERT(args->length() == 1); 3318 ASSERT(args->length() == 1);
3319 LoadAndSpill(args->at(0)); 3319 LoadAndSpill(args->at(0));
3320 frame_->EmitPop(r0); 3320 frame_->EmitPop(r0);
3321 __ tst(r0, Operand(kSmiTagMask)); 3321 __ tst(r0, Operand(kSmiTagMask));
3322 cc_reg_ = eq; 3322 cc_reg_ = eq;
3323 } 3323 }
3324 3324
3325 3325
3326 void CodeGenerator::GenerateLog(ZoneList<Expression*>* args) { 3326 void CodeGenerator::GenerateLog(ZoneList<Expression*>* args) {
3327 VirtualFrame::SpilledScope spilled_scope(this); 3327 VirtualFrame::SpilledScope spilled_scope;
3328 // See comment in CodeGenerator::GenerateLog in codegen-ia32.cc. 3328 // See comment in CodeGenerator::GenerateLog in codegen-ia32.cc.
3329 ASSERT_EQ(args->length(), 3); 3329 ASSERT_EQ(args->length(), 3);
3330 #ifdef ENABLE_LOGGING_AND_PROFILING 3330 #ifdef ENABLE_LOGGING_AND_PROFILING
3331 if (ShouldGenerateLog(args->at(0))) { 3331 if (ShouldGenerateLog(args->at(0))) {
3332 LoadAndSpill(args->at(1)); 3332 LoadAndSpill(args->at(1));
3333 LoadAndSpill(args->at(2)); 3333 LoadAndSpill(args->at(2));
3334 __ CallRuntime(Runtime::kLog, 2); 3334 __ CallRuntime(Runtime::kLog, 2);
3335 } 3335 }
3336 #endif 3336 #endif
3337 __ mov(r0, Operand(Factory::undefined_value())); 3337 __ mov(r0, Operand(Factory::undefined_value()));
3338 frame_->EmitPush(r0); 3338 frame_->EmitPush(r0);
3339 } 3339 }
3340 3340
3341 3341
3342 void CodeGenerator::GenerateIsNonNegativeSmi(ZoneList<Expression*>* args) { 3342 void CodeGenerator::GenerateIsNonNegativeSmi(ZoneList<Expression*>* args) {
3343 VirtualFrame::SpilledScope spilled_scope(this); 3343 VirtualFrame::SpilledScope spilled_scope;
3344 ASSERT(args->length() == 1); 3344 ASSERT(args->length() == 1);
3345 LoadAndSpill(args->at(0)); 3345 LoadAndSpill(args->at(0));
3346 frame_->EmitPop(r0); 3346 frame_->EmitPop(r0);
3347 __ tst(r0, Operand(kSmiTagMask | 0x80000000)); 3347 __ tst(r0, Operand(kSmiTagMask | 0x80000000));
3348 cc_reg_ = eq; 3348 cc_reg_ = eq;
3349 } 3349 }
3350 3350
3351 3351
3352 // This should generate code that performs a charCodeAt() call or returns 3352 // This should generate code that performs a charCodeAt() call or returns
3353 // undefined in order to trigger the slow case, Runtime_StringCharCodeAt. 3353 // undefined in order to trigger the slow case, Runtime_StringCharCodeAt.
3354 // It is not yet implemented on ARM, so it always goes to the slow case. 3354 // It is not yet implemented on ARM, so it always goes to the slow case.
3355 void CodeGenerator::GenerateFastCharCodeAt(ZoneList<Expression*>* args) { 3355 void CodeGenerator::GenerateFastCharCodeAt(ZoneList<Expression*>* args) {
3356 VirtualFrame::SpilledScope spilled_scope(this); 3356 VirtualFrame::SpilledScope spilled_scope;
3357 ASSERT(args->length() == 2); 3357 ASSERT(args->length() == 2);
3358 __ mov(r0, Operand(Factory::undefined_value())); 3358 __ mov(r0, Operand(Factory::undefined_value()));
3359 frame_->EmitPush(r0); 3359 frame_->EmitPush(r0);
3360 } 3360 }
3361 3361
3362 3362
3363 void CodeGenerator::GenerateIsArray(ZoneList<Expression*>* args) { 3363 void CodeGenerator::GenerateIsArray(ZoneList<Expression*>* args) {
3364 VirtualFrame::SpilledScope spilled_scope(this); 3364 VirtualFrame::SpilledScope spilled_scope;
3365 ASSERT(args->length() == 1); 3365 ASSERT(args->length() == 1);
3366 LoadAndSpill(args->at(0)); 3366 LoadAndSpill(args->at(0));
3367 JumpTarget answer; 3367 JumpTarget answer;
3368 // We need the CC bits to come out as not_equal in the case where the 3368 // We need the CC bits to come out as not_equal in the case where the
3369 // object is a smi. This can't be done with the usual test opcode so 3369 // object is a smi. This can't be done with the usual test opcode so
3370 // we use XOR to get the right CC bits. 3370 // we use XOR to get the right CC bits.
3371 frame_->EmitPop(r0); 3371 frame_->EmitPop(r0);
3372 __ and_(r1, r0, Operand(kSmiTagMask)); 3372 __ and_(r1, r0, Operand(kSmiTagMask));
3373 __ eor(r1, r1, Operand(kSmiTagMask), SetCC); 3373 __ eor(r1, r1, Operand(kSmiTagMask), SetCC);
3374 answer.Branch(ne); 3374 answer.Branch(ne);
3375 // It is a heap object - get the map. 3375 // It is a heap object - get the map.
3376 __ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset)); 3376 __ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset));
3377 __ ldrb(r1, FieldMemOperand(r1, Map::kInstanceTypeOffset)); 3377 __ ldrb(r1, FieldMemOperand(r1, Map::kInstanceTypeOffset));
3378 // Check if the object is a JS array or not. 3378 // Check if the object is a JS array or not.
3379 __ cmp(r1, Operand(JS_ARRAY_TYPE)); 3379 __ cmp(r1, Operand(JS_ARRAY_TYPE));
3380 answer.Bind(); 3380 answer.Bind();
3381 cc_reg_ = eq; 3381 cc_reg_ = eq;
3382 } 3382 }
3383 3383
3384 3384
3385 void CodeGenerator::GenerateArgumentsLength(ZoneList<Expression*>* args) { 3385 void CodeGenerator::GenerateArgumentsLength(ZoneList<Expression*>* args) {
3386 VirtualFrame::SpilledScope spilled_scope(this); 3386 VirtualFrame::SpilledScope spilled_scope;
3387 ASSERT(args->length() == 0); 3387 ASSERT(args->length() == 0);
3388 3388
3389 // Seed the result with the formal parameters count, which will be used 3389 // Seed the result with the formal parameters count, which will be used
3390 // in case no arguments adaptor frame is found below the current frame. 3390 // in case no arguments adaptor frame is found below the current frame.
3391 __ mov(r0, Operand(Smi::FromInt(scope_->num_parameters()))); 3391 __ mov(r0, Operand(Smi::FromInt(scope_->num_parameters())));
3392 3392
3393 // Call the shared stub to get to the arguments.length. 3393 // Call the shared stub to get to the arguments.length.
3394 ArgumentsAccessStub stub(ArgumentsAccessStub::READ_LENGTH); 3394 ArgumentsAccessStub stub(ArgumentsAccessStub::READ_LENGTH);
3395 frame_->CallStub(&stub, 0); 3395 frame_->CallStub(&stub, 0);
3396 frame_->EmitPush(r0); 3396 frame_->EmitPush(r0);
3397 } 3397 }
3398 3398
3399 3399
3400 void CodeGenerator::GenerateArgumentsAccess(ZoneList<Expression*>* args) { 3400 void CodeGenerator::GenerateArgumentsAccess(ZoneList<Expression*>* args) {
3401 VirtualFrame::SpilledScope spilled_scope(this); 3401 VirtualFrame::SpilledScope spilled_scope;
3402 ASSERT(args->length() == 1); 3402 ASSERT(args->length() == 1);
3403 3403
3404 // Satisfy contract with ArgumentsAccessStub: 3404 // Satisfy contract with ArgumentsAccessStub:
3405 // Load the key into r1 and the formal parameters count into r0. 3405 // Load the key into r1 and the formal parameters count into r0.
3406 LoadAndSpill(args->at(0)); 3406 LoadAndSpill(args->at(0));
3407 frame_->EmitPop(r1); 3407 frame_->EmitPop(r1);
3408 __ mov(r0, Operand(Smi::FromInt(scope_->num_parameters()))); 3408 __ mov(r0, Operand(Smi::FromInt(scope_->num_parameters())));
3409 3409
3410 // Call the shared stub to get to arguments[key]. 3410 // Call the shared stub to get to arguments[key].
3411 ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT); 3411 ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT);
3412 frame_->CallStub(&stub, 0); 3412 frame_->CallStub(&stub, 0);
3413 frame_->EmitPush(r0); 3413 frame_->EmitPush(r0);
3414 } 3414 }
3415 3415
3416 3416
3417 void CodeGenerator::GenerateObjectEquals(ZoneList<Expression*>* args) { 3417 void CodeGenerator::GenerateObjectEquals(ZoneList<Expression*>* args) {
3418 VirtualFrame::SpilledScope spilled_scope(this); 3418 VirtualFrame::SpilledScope spilled_scope;
3419 ASSERT(args->length() == 2); 3419 ASSERT(args->length() == 2);
3420 3420
3421 // Load the two objects into registers and perform the comparison. 3421 // Load the two objects into registers and perform the comparison.
3422 LoadAndSpill(args->at(0)); 3422 LoadAndSpill(args->at(0));
3423 LoadAndSpill(args->at(1)); 3423 LoadAndSpill(args->at(1));
3424 frame_->EmitPop(r0); 3424 frame_->EmitPop(r0);
3425 frame_->EmitPop(r1); 3425 frame_->EmitPop(r1);
3426 __ cmp(r0, Operand(r1)); 3426 __ cmp(r0, Operand(r1));
3427 cc_reg_ = eq; 3427 cc_reg_ = eq;
3428 } 3428 }
3429 3429
3430 3430
3431 void CodeGenerator::VisitCallRuntime(CallRuntime* node) { 3431 void CodeGenerator::VisitCallRuntime(CallRuntime* node) {
3432 #ifdef DEBUG 3432 #ifdef DEBUG
3433 int original_height = frame_->height(); 3433 int original_height = frame_->height();
3434 #endif 3434 #endif
3435 VirtualFrame::SpilledScope spilled_scope(this); 3435 VirtualFrame::SpilledScope spilled_scope;
3436 if (CheckForInlineRuntimeCall(node)) { 3436 if (CheckForInlineRuntimeCall(node)) {
3437 ASSERT((has_cc() && frame_->height() == original_height) || 3437 ASSERT((has_cc() && frame_->height() == original_height) ||
3438 (!has_cc() && frame_->height() == original_height + 1)); 3438 (!has_cc() && frame_->height() == original_height + 1));
3439 return; 3439 return;
3440 } 3440 }
3441 3441
3442 ZoneList<Expression*>* args = node->arguments(); 3442 ZoneList<Expression*>* args = node->arguments();
3443 Comment cmnt(masm_, "[ CallRuntime"); 3443 Comment cmnt(masm_, "[ CallRuntime");
3444 Runtime::Function* function = node->function(); 3444 Runtime::Function* function = node->function();
3445 3445
(...skipping 26 matching lines...) Expand all
3472 frame_->EmitPush(r0); 3472 frame_->EmitPush(r0);
3473 } 3473 }
3474 ASSERT(frame_->height() == original_height + 1); 3474 ASSERT(frame_->height() == original_height + 1);
3475 } 3475 }
3476 3476
3477 3477
3478 void CodeGenerator::VisitUnaryOperation(UnaryOperation* node) { 3478 void CodeGenerator::VisitUnaryOperation(UnaryOperation* node) {
3479 #ifdef DEBUG 3479 #ifdef DEBUG
3480 int original_height = frame_->height(); 3480 int original_height = frame_->height();
3481 #endif 3481 #endif
3482 VirtualFrame::SpilledScope spilled_scope(this); 3482 VirtualFrame::SpilledScope spilled_scope;
3483 Comment cmnt(masm_, "[ UnaryOperation"); 3483 Comment cmnt(masm_, "[ UnaryOperation");
3484 3484
3485 Token::Value op = node->op(); 3485 Token::Value op = node->op();
3486 3486
3487 if (op == Token::NOT) { 3487 if (op == Token::NOT) {
3488 LoadConditionAndSpill(node->expression(), 3488 LoadConditionAndSpill(node->expression(),
3489 NOT_INSIDE_TYPEOF, 3489 NOT_INSIDE_TYPEOF,
3490 false_target(), 3490 false_target(),
3491 true_target(), 3491 true_target(),
3492 true); 3492 true);
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
3613 } 3613 }
3614 ASSERT((has_cc() && frame_->height() == original_height) || 3614 ASSERT((has_cc() && frame_->height() == original_height) ||
3615 (!has_cc() && frame_->height() == original_height + 1)); 3615 (!has_cc() && frame_->height() == original_height + 1));
3616 } 3616 }
3617 3617
3618 3618
3619 void CodeGenerator::VisitCountOperation(CountOperation* node) { 3619 void CodeGenerator::VisitCountOperation(CountOperation* node) {
3620 #ifdef DEBUG 3620 #ifdef DEBUG
3621 int original_height = frame_->height(); 3621 int original_height = frame_->height();
3622 #endif 3622 #endif
3623 VirtualFrame::SpilledScope spilled_scope(this); 3623 VirtualFrame::SpilledScope spilled_scope;
3624 Comment cmnt(masm_, "[ CountOperation"); 3624 Comment cmnt(masm_, "[ CountOperation");
3625 3625
3626 bool is_postfix = node->is_postfix(); 3626 bool is_postfix = node->is_postfix();
3627 bool is_increment = node->op() == Token::INC; 3627 bool is_increment = node->op() == Token::INC;
3628 3628
3629 Variable* var = node->expression()->AsVariableProxy()->AsVariable(); 3629 Variable* var = node->expression()->AsVariableProxy()->AsVariable();
3630 bool is_const = (var != NULL && var->mode() == Variable::CONST); 3630 bool is_const = (var != NULL && var->mode() == Variable::CONST);
3631 3631
3632 // Postfix: Make room for the result. 3632 // Postfix: Make room for the result.
3633 if (is_postfix) { 3633 if (is_postfix) {
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
3715 // Postfix: Discard the new value and use the old. 3715 // Postfix: Discard the new value and use the old.
3716 if (is_postfix) frame_->EmitPop(r0); 3716 if (is_postfix) frame_->EmitPop(r0);
3717 ASSERT(frame_->height() == original_height + 1); 3717 ASSERT(frame_->height() == original_height + 1);
3718 } 3718 }
3719 3719
3720 3720
3721 void CodeGenerator::VisitBinaryOperation(BinaryOperation* node) { 3721 void CodeGenerator::VisitBinaryOperation(BinaryOperation* node) {
3722 #ifdef DEBUG 3722 #ifdef DEBUG
3723 int original_height = frame_->height(); 3723 int original_height = frame_->height();
3724 #endif 3724 #endif
3725 VirtualFrame::SpilledScope spilled_scope(this); 3725 VirtualFrame::SpilledScope spilled_scope;
3726 Comment cmnt(masm_, "[ BinaryOperation"); 3726 Comment cmnt(masm_, "[ BinaryOperation");
3727 Token::Value op = node->op(); 3727 Token::Value op = node->op();
3728 3728
3729 // According to ECMA-262 section 11.11, page 58, the binary logical 3729 // According to ECMA-262 section 11.11, page 58, the binary logical
3730 // operators must yield the result of one of the two expressions 3730 // operators must yield the result of one of the two expressions
3731 // before any ToBoolean() conversions. This means that the value 3731 // before any ToBoolean() conversions. This means that the value
3732 // produced by a && or || operator is not necessarily a boolean. 3732 // produced by a && or || operator is not necessarily a boolean.
3733 3733
3734 // NOTE: If the left hand side produces a materialized value (not in 3734 // NOTE: If the left hand side produces a materialized value (not in
3735 // the CC register), we force the right hand side to do the 3735 // the CC register), we force the right hand side to do the
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
3865 } 3865 }
3866 ASSERT((has_cc() && frame_->height() == original_height) || 3866 ASSERT((has_cc() && frame_->height() == original_height) ||
3867 (!has_cc() && frame_->height() == original_height + 1)); 3867 (!has_cc() && frame_->height() == original_height + 1));
3868 } 3868 }
3869 3869
3870 3870
3871 void CodeGenerator::VisitThisFunction(ThisFunction* node) { 3871 void CodeGenerator::VisitThisFunction(ThisFunction* node) {
3872 #ifdef DEBUG 3872 #ifdef DEBUG
3873 int original_height = frame_->height(); 3873 int original_height = frame_->height();
3874 #endif 3874 #endif
3875 VirtualFrame::SpilledScope spilled_scope(this); 3875 VirtualFrame::SpilledScope spilled_scope;
3876 __ ldr(r0, frame_->Function()); 3876 __ ldr(r0, frame_->Function());
3877 frame_->EmitPush(r0); 3877 frame_->EmitPush(r0);
3878 ASSERT(frame_->height() == original_height + 1); 3878 ASSERT(frame_->height() == original_height + 1);
3879 } 3879 }
3880 3880
3881 3881
3882 void CodeGenerator::VisitCompareOperation(CompareOperation* node) { 3882 void CodeGenerator::VisitCompareOperation(CompareOperation* node) {
3883 #ifdef DEBUG 3883 #ifdef DEBUG
3884 int original_height = frame_->height(); 3884 int original_height = frame_->height();
3885 #endif 3885 #endif
3886 VirtualFrame::SpilledScope spilled_scope(this); 3886 VirtualFrame::SpilledScope spilled_scope;
3887 Comment cmnt(masm_, "[ CompareOperation"); 3887 Comment cmnt(masm_, "[ CompareOperation");
3888 3888
3889 // Get the expressions from the node. 3889 // Get the expressions from the node.
3890 Expression* left = node->left(); 3890 Expression* left = node->left();
3891 Expression* right = node->right(); 3891 Expression* right = node->right();
3892 Token::Value op = node->op(); 3892 Token::Value op = node->op();
3893 3893
3894 // To make null checks efficient, we check if either left or right is the 3894 // To make null checks efficient, we check if either left or right is the
3895 // literal 'null'. If so, we optimize the code by inlining a null check 3895 // literal 'null'. If so, we optimize the code by inlining a null check
3896 // instead of calling the (very) general runtime routine for checking 3896 // instead of calling the (very) general runtime routine for checking
(...skipping 1283 matching lines...) Expand 10 before | Expand all | Expand 10 after
5180 __ mov(r2, Operand(0)); 5180 __ mov(r2, Operand(0));
5181 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); 5181 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION);
5182 __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)), 5182 __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)),
5183 RelocInfo::CODE_TARGET); 5183 RelocInfo::CODE_TARGET);
5184 } 5184 }
5185 5185
5186 5186
5187 #undef __ 5187 #undef __
5188 5188
5189 } } // namespace v8::internal 5189 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/arm/virtual-frame-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698