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 |