| OLD | NEW |
| 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 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 126 bool is_eval) | 126 bool is_eval) |
| 127 : is_eval_(is_eval), | 127 : is_eval_(is_eval), |
| 128 script_(script), | 128 script_(script), |
| 129 deferred_(8), | 129 deferred_(8), |
| 130 masm_(new MacroAssembler(NULL, buffer_size)), | 130 masm_(new MacroAssembler(NULL, buffer_size)), |
| 131 scope_(NULL), | 131 scope_(NULL), |
| 132 frame_(NULL), | 132 frame_(NULL), |
| 133 allocator_(NULL), | 133 allocator_(NULL), |
| 134 cc_reg_(al), | 134 cc_reg_(al), |
| 135 state_(NULL), | 135 state_(NULL), |
| 136 function_return_is_shadowed_(false), | 136 function_return_is_shadowed_(false) { |
| 137 in_spilled_code_(false) { | |
| 138 } | 137 } |
| 139 | 138 |
| 140 | 139 |
| 141 // Calling conventions: | 140 // Calling conventions: |
| 142 // fp: caller's frame pointer | 141 // fp: caller's frame pointer |
| 143 // sp: stack pointer | 142 // sp: stack pointer |
| 144 // r1: called JS function | 143 // r1: called JS function |
| 145 // cp: callee's context | 144 // cp: callee's context |
| 146 | 145 |
| 147 void CodeGenerator::GenCode(FunctionLiteral* fun) { | 146 void CodeGenerator::GenCode(FunctionLiteral* fun) { |
| 148 ZoneList<Statement*>* body = fun->body(); | 147 ZoneList<Statement*>* body = fun->body(); |
| 149 | 148 |
| 150 // Initialize state. | 149 // Initialize state. |
| 151 ASSERT(scope_ == NULL); | 150 ASSERT(scope_ == NULL); |
| 152 scope_ = fun->scope(); | 151 scope_ = fun->scope(); |
| 153 ASSERT(allocator_ == NULL); | 152 ASSERT(allocator_ == NULL); |
| 154 RegisterAllocator register_allocator(this); | 153 RegisterAllocator register_allocator(this); |
| 155 allocator_ = ®ister_allocator; | 154 allocator_ = ®ister_allocator; |
| 156 ASSERT(frame_ == NULL); | 155 ASSERT(frame_ == NULL); |
| 157 frame_ = new VirtualFrame(); | 156 frame_ = new VirtualFrame(); |
| 158 cc_reg_ = al; | 157 cc_reg_ = al; |
| 159 set_in_spilled_code(false); | |
| 160 { | 158 { |
| 161 CodeGenState state(this); | 159 CodeGenState state(this); |
| 162 | 160 |
| 163 // Entry: | 161 // Entry: |
| 164 // Stack: receiver, arguments | 162 // Stack: receiver, arguments |
| 165 // lr: return address | 163 // lr: return address |
| 166 // fp: caller's frame pointer | 164 // fp: caller's frame pointer |
| 167 // sp: stack pointer | 165 // sp: stack pointer |
| 168 // r1: called JS function | 166 // r1: called JS function |
| 169 // cp: callee's context | 167 // cp: callee's context |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 416 } | 414 } |
| 417 // Check that last extension is NULL. | 415 // Check that last extension is NULL. |
| 418 __ ldr(tmp2, ContextOperand(context, Context::EXTENSION_INDEX)); | 416 __ ldr(tmp2, ContextOperand(context, Context::EXTENSION_INDEX)); |
| 419 __ tst(tmp2, tmp2); | 417 __ tst(tmp2, tmp2); |
| 420 slow->Branch(ne); | 418 slow->Branch(ne); |
| 421 __ ldr(tmp, ContextOperand(context, Context::FCONTEXT_INDEX)); | 419 __ ldr(tmp, ContextOperand(context, Context::FCONTEXT_INDEX)); |
| 422 return ContextOperand(tmp, slot->index()); | 420 return ContextOperand(tmp, slot->index()); |
| 423 } | 421 } |
| 424 | 422 |
| 425 | 423 |
| 426 void CodeGenerator::LoadConditionAndSpill(Expression* expression, | |
| 427 TypeofState typeof_state, | |
| 428 JumpTarget* true_target, | |
| 429 JumpTarget* false_target, | |
| 430 bool force_control) { | |
| 431 ASSERT(in_spilled_code()); | |
| 432 set_in_spilled_code(false); | |
| 433 LoadCondition(expression, typeof_state, true_target, false_target, | |
| 434 force_control); | |
| 435 if (frame_ != NULL) { | |
| 436 frame_->SpillAll(); | |
| 437 } | |
| 438 set_in_spilled_code(true); | |
| 439 } | |
| 440 | |
| 441 | |
| 442 // Loads a value on TOS. If it is a boolean value, the result may have been | 424 // Loads a value on TOS. If it is a boolean value, the result may have been |
| 443 // (partially) translated into branches, or it may have set the condition | 425 // (partially) translated into branches, or it may have set the condition |
| 444 // code register. If force_cc is set, the value is forced to set the | 426 // code register. If force_cc is set, the value is forced to set the |
| 445 // condition code register and no value is pushed. If the condition code | 427 // condition code register and no value is pushed. If the condition code |
| 446 // register was set, has_cc() is true and cc_reg_ contains the condition to | 428 // register was set, has_cc() is true and cc_reg_ contains the condition to |
| 447 // test for 'true'. | 429 // test for 'true'. |
| 448 void CodeGenerator::LoadCondition(Expression* x, | 430 void CodeGenerator::LoadCondition(Expression* x, |
| 449 TypeofState typeof_state, | 431 TypeofState typeof_state, |
| 450 JumpTarget* true_target, | 432 JumpTarget* true_target, |
| 451 JumpTarget* false_target, | 433 JumpTarget* false_target, |
| 452 bool force_cc) { | 434 bool force_cc) { |
| 453 ASSERT(!in_spilled_code()); | |
| 454 ASSERT(!has_cc()); | 435 ASSERT(!has_cc()); |
| 455 int original_height = frame_->height(); | 436 int original_height = frame_->height(); |
| 456 | 437 |
| 457 { CodeGenState new_state(this, typeof_state, true_target, false_target); | 438 { CodeGenState new_state(this, typeof_state, true_target, false_target); |
| 458 Visit(x); | 439 Visit(x); |
| 459 | 440 |
| 460 // If we hit a stack overflow, we may not have actually visited | 441 // If we hit a stack overflow, we may not have actually visited |
| 461 // the expression. In that case, we ensure that we have a | 442 // the expression. In that case, we ensure that we have a |
| 462 // valid-looking frame state because we will continue to generate | 443 // valid-looking frame state because we will continue to generate |
| 463 // code as we unwind the C++ stack. | 444 // code as we unwind the C++ stack. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 477 // Convert the TOS value to a boolean in the condition code register. | 458 // Convert the TOS value to a boolean in the condition code register. |
| 478 ToBoolean(true_target, false_target); | 459 ToBoolean(true_target, false_target); |
| 479 } | 460 } |
| 480 ASSERT(!force_cc || !has_valid_frame() || has_cc()); | 461 ASSERT(!force_cc || !has_valid_frame() || has_cc()); |
| 481 ASSERT(!has_valid_frame() || | 462 ASSERT(!has_valid_frame() || |
| 482 (has_cc() && frame_->height() == original_height) || | 463 (has_cc() && frame_->height() == original_height) || |
| 483 (!has_cc() && frame_->height() == original_height + 1)); | 464 (!has_cc() && frame_->height() == original_height + 1)); |
| 484 } | 465 } |
| 485 | 466 |
| 486 | 467 |
| 487 void CodeGenerator::LoadAndSpill(Expression* expression, | |
| 488 TypeofState typeof_state) { | |
| 489 ASSERT(in_spilled_code()); | |
| 490 set_in_spilled_code(false); | |
| 491 Load(expression, typeof_state); | |
| 492 frame_->SpillAll(); | |
| 493 set_in_spilled_code(true); | |
| 494 } | |
| 495 | |
| 496 | |
| 497 void CodeGenerator::Load(Expression* x, TypeofState typeof_state) { | 468 void CodeGenerator::Load(Expression* x, TypeofState typeof_state) { |
| 498 #ifdef DEBUG | 469 #ifdef DEBUG |
| 499 int original_height = frame_->height(); | 470 int original_height = frame_->height(); |
| 500 #endif | 471 #endif |
| 501 ASSERT(!in_spilled_code()); | |
| 502 JumpTarget true_target; | 472 JumpTarget true_target; |
| 503 JumpTarget false_target; | 473 JumpTarget false_target; |
| 504 LoadCondition(x, typeof_state, &true_target, &false_target, false); | 474 LoadCondition(x, typeof_state, &true_target, &false_target, false); |
| 505 | 475 |
| 506 if (has_cc()) { | 476 if (has_cc()) { |
| 507 // Convert cc_reg_ into a boolean value. | 477 // Convert cc_reg_ into a boolean value. |
| 508 JumpTarget loaded; | 478 JumpTarget loaded; |
| 509 JumpTarget materialize_true; | 479 JumpTarget materialize_true; |
| 510 materialize_true.Branch(cc_reg_); | 480 materialize_true.Branch(cc_reg_); |
| 511 __ mov(r0, Operand(Factory::false_value())); | 481 __ mov(r0, Operand(Factory::false_value())); |
| (...skipping 627 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1139 void CodeGenerator::CheckStack() { | 1109 void CodeGenerator::CheckStack() { |
| 1140 VirtualFrame::SpilledScope spilled_scope; | 1110 VirtualFrame::SpilledScope spilled_scope; |
| 1141 if (FLAG_check_stack) { | 1111 if (FLAG_check_stack) { |
| 1142 Comment cmnt(masm_, "[ check stack"); | 1112 Comment cmnt(masm_, "[ check stack"); |
| 1143 StackCheckStub stub; | 1113 StackCheckStub stub; |
| 1144 frame_->CallStub(&stub, 0); | 1114 frame_->CallStub(&stub, 0); |
| 1145 } | 1115 } |
| 1146 } | 1116 } |
| 1147 | 1117 |
| 1148 | 1118 |
| 1149 void CodeGenerator::VisitAndSpill(Statement* statement) { | |
| 1150 ASSERT(in_spilled_code()); | |
| 1151 set_in_spilled_code(false); | |
| 1152 Visit(statement); | |
| 1153 if (frame_ != NULL) { | |
| 1154 frame_->SpillAll(); | |
| 1155 } | |
| 1156 set_in_spilled_code(true); | |
| 1157 } | |
| 1158 | |
| 1159 | |
| 1160 void CodeGenerator::VisitStatementsAndSpill(ZoneList<Statement*>* statements) { | |
| 1161 ASSERT(in_spilled_code()); | |
| 1162 set_in_spilled_code(false); | |
| 1163 VisitStatements(statements); | |
| 1164 if (frame_ != NULL) { | |
| 1165 frame_->SpillAll(); | |
| 1166 } | |
| 1167 set_in_spilled_code(true); | |
| 1168 } | |
| 1169 | |
| 1170 | |
| 1171 void CodeGenerator::VisitStatements(ZoneList<Statement*>* statements) { | 1119 void CodeGenerator::VisitStatements(ZoneList<Statement*>* statements) { |
| 1172 #ifdef DEBUG | 1120 #ifdef DEBUG |
| 1173 int original_height = frame_->height(); | 1121 int original_height = frame_->height(); |
| 1174 #endif | 1122 #endif |
| 1175 VirtualFrame::SpilledScope spilled_scope; | 1123 VirtualFrame::SpilledScope spilled_scope; |
| 1176 for (int i = 0; frame_ != NULL && i < statements->length(); i++) { | 1124 for (int i = 0; frame_ != NULL && i < statements->length(); i++) { |
| 1177 VisitAndSpill(statements->at(i)); | 1125 VisitAndSpill(statements->at(i)); |
| 1178 } | 1126 } |
| 1179 ASSERT(!has_valid_frame() || frame_->height() == original_height); | 1127 ASSERT(!has_valid_frame() || frame_->height() == original_height); |
| 1180 } | 1128 } |
| (...skipping 576 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1757 node->continue_target()->Unuse(); | 1705 node->continue_target()->Unuse(); |
| 1758 node->break_target()->Unuse(); | 1706 node->break_target()->Unuse(); |
| 1759 ASSERT(!has_valid_frame() || frame_->height() == original_height); | 1707 ASSERT(!has_valid_frame() || frame_->height() == original_height); |
| 1760 } | 1708 } |
| 1761 | 1709 |
| 1762 | 1710 |
| 1763 void CodeGenerator::VisitForInStatement(ForInStatement* node) { | 1711 void CodeGenerator::VisitForInStatement(ForInStatement* node) { |
| 1764 #ifdef DEBUG | 1712 #ifdef DEBUG |
| 1765 int original_height = frame_->height(); | 1713 int original_height = frame_->height(); |
| 1766 #endif | 1714 #endif |
| 1767 ASSERT(!in_spilled_code()); | |
| 1768 VirtualFrame::SpilledScope spilled_scope; | 1715 VirtualFrame::SpilledScope spilled_scope; |
| 1769 Comment cmnt(masm_, "[ ForInStatement"); | 1716 Comment cmnt(masm_, "[ ForInStatement"); |
| 1770 CodeForStatementPosition(node); | 1717 CodeForStatementPosition(node); |
| 1771 | 1718 |
| 1772 JumpTarget primitive; | 1719 JumpTarget primitive; |
| 1773 JumpTarget jsobject; | 1720 JumpTarget jsobject; |
| 1774 JumpTarget fixed_array; | 1721 JumpTarget fixed_array; |
| 1775 JumpTarget entry(JumpTarget::BIDIRECTIONAL); | 1722 JumpTarget entry(JumpTarget::BIDIRECTIONAL); |
| 1776 JumpTarget end_del_check; | 1723 JumpTarget end_del_check; |
| 1777 JumpTarget exit; | 1724 JumpTarget exit; |
| (...skipping 1037 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2815 __ RecordWrite(r1, r3, r2); | 2762 __ RecordWrite(r1, r3, r2); |
| 2816 } | 2763 } |
| 2817 ASSERT(frame_->height() == original_height + 1); | 2764 ASSERT(frame_->height() == original_height + 1); |
| 2818 } | 2765 } |
| 2819 | 2766 |
| 2820 | 2767 |
| 2821 void CodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* node) { | 2768 void CodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* node) { |
| 2822 #ifdef DEBUG | 2769 #ifdef DEBUG |
| 2823 int original_height = frame_->height(); | 2770 int original_height = frame_->height(); |
| 2824 #endif | 2771 #endif |
| 2825 ASSERT(!in_spilled_code()); | |
| 2826 VirtualFrame::SpilledScope spilled_scope; | 2772 VirtualFrame::SpilledScope spilled_scope; |
| 2827 // Call runtime routine to allocate the catch extension object and | 2773 // Call runtime routine to allocate the catch extension object and |
| 2828 // assign the exception value to the catch variable. | 2774 // assign the exception value to the catch variable. |
| 2829 Comment cmnt(masm_, "[ CatchExtensionObject"); | 2775 Comment cmnt(masm_, "[ CatchExtensionObject"); |
| 2830 LoadAndSpill(node->key()); | 2776 LoadAndSpill(node->key()); |
| 2831 LoadAndSpill(node->value()); | 2777 LoadAndSpill(node->value()); |
| 2832 Result result = | 2778 Result result = |
| 2833 frame_->CallRuntime(Runtime::kCreateCatchExtensionObject, 2); | 2779 frame_->CallRuntime(Runtime::kCreateCatchExtensionObject, 2); |
| 2834 frame_->EmitPush(result.reg()); | 2780 frame_->EmitPush(result.reg()); |
| 2835 ASSERT(frame_->height() == original_height + 1); | 2781 ASSERT(frame_->height() == original_height + 1); |
| (...skipping 1315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4151 ASSERT(proxy->AsVariable()->is_global()); | 4097 ASSERT(proxy->AsVariable()->is_global()); |
| 4152 return proxy->name(); | 4098 return proxy->name(); |
| 4153 } else { | 4099 } else { |
| 4154 Literal* raw_name = property->key()->AsLiteral(); | 4100 Literal* raw_name = property->key()->AsLiteral(); |
| 4155 ASSERT(raw_name != NULL); | 4101 ASSERT(raw_name != NULL); |
| 4156 return Handle<String>(String::cast(*raw_name->handle())); | 4102 return Handle<String>(String::cast(*raw_name->handle())); |
| 4157 } | 4103 } |
| 4158 } | 4104 } |
| 4159 | 4105 |
| 4160 | 4106 |
| 4161 void Reference::GetValueAndSpill(TypeofState typeof_state) { | |
| 4162 ASSERT(cgen_->in_spilled_code()); | |
| 4163 cgen_->set_in_spilled_code(false); | |
| 4164 GetValue(typeof_state); | |
| 4165 cgen_->frame()->SpillAll(); | |
| 4166 cgen_->set_in_spilled_code(true); | |
| 4167 } | |
| 4168 | |
| 4169 | |
| 4170 void Reference::GetValue(TypeofState typeof_state) { | 4107 void Reference::GetValue(TypeofState typeof_state) { |
| 4171 ASSERT(!cgen_->in_spilled_code()); | |
| 4172 ASSERT(cgen_->HasValidEntryRegisters()); | 4108 ASSERT(cgen_->HasValidEntryRegisters()); |
| 4173 ASSERT(!is_illegal()); | 4109 ASSERT(!is_illegal()); |
| 4174 ASSERT(!cgen_->has_cc()); | 4110 ASSERT(!cgen_->has_cc()); |
| 4175 MacroAssembler* masm = cgen_->masm(); | 4111 MacroAssembler* masm = cgen_->masm(); |
| 4176 Property* property = expression_->AsProperty(); | 4112 Property* property = expression_->AsProperty(); |
| 4177 if (property != NULL) { | 4113 if (property != NULL) { |
| 4178 cgen_->CodeForSourcePosition(property->position()); | 4114 cgen_->CodeForSourcePosition(property->position()); |
| 4179 } | 4115 } |
| 4180 | 4116 |
| 4181 switch (type_) { | 4117 switch (type_) { |
| (...skipping 2144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6326 int CompareStub::MinorKey() { | 6262 int CompareStub::MinorKey() { |
| 6327 // Encode the two parameters in a unique 16 bit value. | 6263 // Encode the two parameters in a unique 16 bit value. |
| 6328 ASSERT(static_cast<unsigned>(cc_) >> 28 < (1 << 15)); | 6264 ASSERT(static_cast<unsigned>(cc_) >> 28 < (1 << 15)); |
| 6329 return (static_cast<unsigned>(cc_) >> 27) | (strict_ ? 1 : 0); | 6265 return (static_cast<unsigned>(cc_) >> 27) | (strict_ ? 1 : 0); |
| 6330 } | 6266 } |
| 6331 | 6267 |
| 6332 | 6268 |
| 6333 #undef __ | 6269 #undef __ |
| 6334 | 6270 |
| 6335 } } // namespace v8::internal | 6271 } } // namespace v8::internal |
| OLD | NEW |