| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 | 83 |
| 84 if (HasPointerMap()) { | 84 if (HasPointerMap()) { |
| 85 stream->Add(" "); | 85 stream->Add(" "); |
| 86 pointer_map()->PrintTo(stream); | 86 pointer_map()->PrintTo(stream); |
| 87 } | 87 } |
| 88 } | 88 } |
| 89 | 89 |
| 90 | 90 |
| 91 template<int R, int I, int T> | 91 template<int R, int I, int T> |
| 92 void LTemplateInstruction<R, I, T>::PrintDataTo(StringStream* stream) { | 92 void LTemplateInstruction<R, I, T>::PrintDataTo(StringStream* stream) { |
| 93 for (int i = 0; i < I; i++) { | 93 stream->Add("= "); |
| 94 stream->Add(i == 0 ? "= " : " "); | 94 inputs_.PrintOperandsTo(stream); |
| 95 inputs_.at(i)->PrintTo(stream); | |
| 96 } | |
| 97 } | 95 } |
| 98 | 96 |
| 99 | 97 |
| 100 template<int R, int I, int T> | 98 template<int R, int I, int T> |
| 101 void LTemplateInstruction<R, I, T>::PrintOutputOperandTo(StringStream* stream) { | 99 void LTemplateInstruction<R, I, T>::PrintOutputOperandTo(StringStream* stream) { |
| 102 if (this->HasResult()) { | 100 results_.PrintOperandsTo(stream); |
| 103 this->result()->PrintTo(stream); | 101 } |
| 104 stream->Add(" "); | 102 |
| 103 |
| 104 template<typename T, int N> |
| 105 void OperandContainer<T, N>::PrintOperandsTo(StringStream* stream) { |
| 106 for (int i = 0; i < N; i++) { |
| 107 if (i > 0) stream->Add(" "); |
| 108 elems_[i]->PrintTo(stream); |
| 105 } | 109 } |
| 106 } | 110 } |
| 107 | 111 |
| 108 | 112 |
| 109 void LLabel::PrintDataTo(StringStream* stream) { | 113 void LLabel::PrintDataTo(StringStream* stream) { |
| 110 LGap::PrintDataTo(stream); | 114 LGap::PrintDataTo(stream); |
| 111 LLabel* rep = replacement(); | 115 LLabel* rep = replacement(); |
| 112 if (rep != NULL) { | 116 if (rep != NULL) { |
| 113 stream->Add(" Dead block replaced with B%d", rep->block_id()); | 117 stream->Add(" Dead block replaced with B%d", rep->block_id()); |
| 114 } | 118 } |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 165 } | 169 } |
| 166 | 170 |
| 167 | 171 |
| 168 void LGoto::PrintDataTo(StringStream* stream) { | 172 void LGoto::PrintDataTo(StringStream* stream) { |
| 169 stream->Add("B%d", block_id()); | 173 stream->Add("B%d", block_id()); |
| 170 } | 174 } |
| 171 | 175 |
| 172 | 176 |
| 173 void LBranch::PrintDataTo(StringStream* stream) { | 177 void LBranch::PrintDataTo(StringStream* stream) { |
| 174 stream->Add("B%d | B%d on ", true_block_id(), false_block_id()); | 178 stream->Add("B%d | B%d on ", true_block_id(), false_block_id()); |
| 175 input()->PrintTo(stream); | 179 InputAt(0)->PrintTo(stream); |
| 176 } | 180 } |
| 177 | 181 |
| 178 | 182 |
| 179 void LCmpIDAndBranch::PrintDataTo(StringStream* stream) { | 183 void LCmpIDAndBranch::PrintDataTo(StringStream* stream) { |
| 180 stream->Add("if "); | 184 stream->Add("if "); |
| 181 left()->PrintTo(stream); | 185 InputAt(0)->PrintTo(stream); |
| 182 stream->Add(" %s ", Token::String(op())); | 186 stream->Add(" %s ", Token::String(op())); |
| 183 right()->PrintTo(stream); | 187 InputAt(1)->PrintTo(stream); |
| 184 stream->Add(" then B%d else B%d", true_block_id(), false_block_id()); | 188 stream->Add(" then B%d else B%d", true_block_id(), false_block_id()); |
| 185 } | 189 } |
| 186 | 190 |
| 187 | 191 |
| 188 void LIsNullAndBranch::PrintDataTo(StringStream* stream) { | 192 void LIsNullAndBranch::PrintDataTo(StringStream* stream) { |
| 189 stream->Add("if "); | 193 stream->Add("if "); |
| 190 input()->PrintTo(stream); | 194 InputAt(0)->PrintTo(stream); |
| 191 stream->Add(is_strict() ? " === null" : " == null"); | 195 stream->Add(is_strict() ? " === null" : " == null"); |
| 192 stream->Add(" then B%d else B%d", true_block_id(), false_block_id()); | 196 stream->Add(" then B%d else B%d", true_block_id(), false_block_id()); |
| 193 } | 197 } |
| 194 | 198 |
| 195 | 199 |
| 196 void LIsObjectAndBranch::PrintDataTo(StringStream* stream) { | 200 void LIsObjectAndBranch::PrintDataTo(StringStream* stream) { |
| 197 stream->Add("if is_object("); | 201 stream->Add("if is_object("); |
| 198 input()->PrintTo(stream); | 202 InputAt(0)->PrintTo(stream); |
| 199 stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); | 203 stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); |
| 200 } | 204 } |
| 201 | 205 |
| 202 | 206 |
| 203 void LIsSmiAndBranch::PrintDataTo(StringStream* stream) { | 207 void LIsSmiAndBranch::PrintDataTo(StringStream* stream) { |
| 204 stream->Add("if is_smi("); | 208 stream->Add("if is_smi("); |
| 205 input()->PrintTo(stream); | 209 InputAt(0)->PrintTo(stream); |
| 206 stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); | 210 stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); |
| 207 } | 211 } |
| 208 | 212 |
| 209 | 213 |
| 210 void LHasInstanceTypeAndBranch::PrintDataTo(StringStream* stream) { | 214 void LHasInstanceTypeAndBranch::PrintDataTo(StringStream* stream) { |
| 211 stream->Add("if has_instance_type("); | 215 stream->Add("if has_instance_type("); |
| 212 input()->PrintTo(stream); | 216 InputAt(0)->PrintTo(stream); |
| 213 stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); | 217 stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); |
| 214 } | 218 } |
| 215 | 219 |
| 216 | 220 |
| 217 void LHasCachedArrayIndexAndBranch::PrintDataTo(StringStream* stream) { | 221 void LHasCachedArrayIndexAndBranch::PrintDataTo(StringStream* stream) { |
| 218 stream->Add("if has_cached_array_index("); | 222 stream->Add("if has_cached_array_index("); |
| 219 input()->PrintTo(stream); | 223 InputAt(0)->PrintTo(stream); |
| 220 stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); | 224 stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); |
| 221 } | 225 } |
| 222 | 226 |
| 223 | 227 |
| 224 void LClassOfTestAndBranch::PrintDataTo(StringStream* stream) { | 228 void LClassOfTestAndBranch::PrintDataTo(StringStream* stream) { |
| 225 stream->Add("if class_of_test("); | 229 stream->Add("if class_of_test("); |
| 226 input()->PrintTo(stream); | 230 InputAt(0)->PrintTo(stream); |
| 227 stream->Add(", \"%o\") then B%d else B%d", | 231 stream->Add(", \"%o\") then B%d else B%d", |
| 228 *hydrogen()->class_name(), | 232 *hydrogen()->class_name(), |
| 229 true_block_id(), | 233 true_block_id(), |
| 230 false_block_id()); | 234 false_block_id()); |
| 231 } | 235 } |
| 232 | 236 |
| 233 | 237 |
| 234 void LTypeofIs::PrintDataTo(StringStream* stream) { | 238 void LTypeofIs::PrintDataTo(StringStream* stream) { |
| 235 input()->PrintTo(stream); | 239 InputAt(0)->PrintTo(stream); |
| 236 stream->Add(" == \"%s\"", *hydrogen()->type_literal()->ToCString()); | 240 stream->Add(" == \"%s\"", *hydrogen()->type_literal()->ToCString()); |
| 237 } | 241 } |
| 238 | 242 |
| 239 | 243 |
| 240 void LTypeofIsAndBranch::PrintDataTo(StringStream* stream) { | 244 void LTypeofIsAndBranch::PrintDataTo(StringStream* stream) { |
| 241 stream->Add("if typeof "); | 245 stream->Add("if typeof "); |
| 242 input()->PrintTo(stream); | 246 InputAt(0)->PrintTo(stream); |
| 243 stream->Add(" == \"%s\" then B%d else B%d", | 247 stream->Add(" == \"%s\" then B%d else B%d", |
| 244 *hydrogen()->type_literal()->ToCString(), | 248 *hydrogen()->type_literal()->ToCString(), |
| 245 true_block_id(), false_block_id()); | 249 true_block_id(), false_block_id()); |
| 246 } | 250 } |
| 247 | 251 |
| 248 | 252 |
| 249 void LCallConstantFunction::PrintDataTo(StringStream* stream) { | 253 void LCallConstantFunction::PrintDataTo(StringStream* stream) { |
| 250 stream->Add("#%d / ", arity()); | 254 stream->Add("#%d / ", arity()); |
| 251 } | 255 } |
| 252 | 256 |
| 253 | 257 |
| 254 void LUnaryMathOperation::PrintDataTo(StringStream* stream) { | 258 void LUnaryMathOperation::PrintDataTo(StringStream* stream) { |
| 255 stream->Add("/%s ", hydrogen()->OpName()); | 259 stream->Add("/%s ", hydrogen()->OpName()); |
| 256 input()->PrintTo(stream); | 260 InputAt(0)->PrintTo(stream); |
| 261 } |
| 262 |
| 263 |
| 264 void LLoadContextSlot::PrintDataTo(StringStream* stream) { |
| 265 stream->Add("(%d, %d)", context_chain_length(), slot_index()); |
| 257 } | 266 } |
| 258 | 267 |
| 259 | 268 |
| 260 void LCallKeyed::PrintDataTo(StringStream* stream) { | 269 void LCallKeyed::PrintDataTo(StringStream* stream) { |
| 261 stream->Add("[ecx] #%d / ", arity()); | 270 stream->Add("[ecx] #%d / ", arity()); |
| 262 } | 271 } |
| 263 | 272 |
| 264 | 273 |
| 265 void LCallNamed::PrintDataTo(StringStream* stream) { | 274 void LCallNamed::PrintDataTo(StringStream* stream) { |
| 266 SmartPointer<char> name_string = name()->ToCString(); | 275 SmartPointer<char> name_string = name()->ToCString(); |
| 267 stream->Add("%s #%d / ", *name_string, arity()); | 276 stream->Add("%s #%d / ", *name_string, arity()); |
| 268 } | 277 } |
| 269 | 278 |
| 270 | 279 |
| 271 void LCallGlobal::PrintDataTo(StringStream* stream) { | 280 void LCallGlobal::PrintDataTo(StringStream* stream) { |
| 272 SmartPointer<char> name_string = name()->ToCString(); | 281 SmartPointer<char> name_string = name()->ToCString(); |
| 273 stream->Add("%s #%d / ", *name_string, arity()); | 282 stream->Add("%s #%d / ", *name_string, arity()); |
| 274 } | 283 } |
| 275 | 284 |
| 276 | 285 |
| 277 void LCallKnownGlobal::PrintDataTo(StringStream* stream) { | 286 void LCallKnownGlobal::PrintDataTo(StringStream* stream) { |
| 278 stream->Add("#%d / ", arity()); | 287 stream->Add("#%d / ", arity()); |
| 279 } | 288 } |
| 280 | 289 |
| 281 | 290 |
| 282 void LCallNew::PrintDataTo(StringStream* stream) { | 291 void LCallNew::PrintDataTo(StringStream* stream) { |
| 283 stream->Add("= "); | 292 stream->Add("= "); |
| 284 input()->PrintTo(stream); | 293 InputAt(0)->PrintTo(stream); |
| 285 stream->Add(" #%d / ", arity()); | 294 stream->Add(" #%d / ", arity()); |
| 286 } | 295 } |
| 287 | 296 |
| 288 | 297 |
| 289 void LClassOfTest::PrintDataTo(StringStream* stream) { | 298 void LClassOfTest::PrintDataTo(StringStream* stream) { |
| 290 stream->Add("= class_of_test("); | 299 stream->Add("= class_of_test("); |
| 291 input()->PrintTo(stream); | 300 InputAt(0)->PrintTo(stream); |
| 292 stream->Add(", \"%o\")", *hydrogen()->class_name()); | 301 stream->Add(", \"%o\")", *hydrogen()->class_name()); |
| 293 } | 302 } |
| 294 | 303 |
| 295 | 304 |
| 296 void LAccessArgumentsAt::PrintDataTo(StringStream* stream) { | 305 void LAccessArgumentsAt::PrintDataTo(StringStream* stream) { |
| 297 arguments()->PrintTo(stream); | 306 arguments()->PrintTo(stream); |
| 298 | 307 |
| 299 stream->Add(" length "); | 308 stream->Add(" length "); |
| 300 length()->PrintTo(stream); | 309 length()->PrintTo(stream); |
| 301 | 310 |
| 302 stream->Add(" index "); | 311 stream->Add(" index "); |
| 303 index()->PrintTo(stream); | 312 index()->PrintTo(stream); |
| 304 } | 313 } |
| 305 | 314 |
| 306 | 315 |
| 307 int LChunk::GetNextSpillIndex(bool is_double) { | 316 int LChunk::GetNextSpillIndex(bool is_double) { |
| 308 // Need to consider what index means: Is it 32 bit or 64 bit index? | 317 return spill_slot_count_++; |
| 309 UNIMPLEMENTED(); | |
| 310 return 0; | |
| 311 } | 318 } |
| 312 | 319 |
| 313 | 320 |
| 314 LOperand* LChunk::GetNextSpillSlot(bool is_double) { | 321 LOperand* LChunk::GetNextSpillSlot(bool is_double) { |
| 315 UNIMPLEMENTED(); | 322 // All stack slots are Double stack slots on x64. |
| 316 return NULL; | 323 // Alternatively, at some point, start using half-size |
| 324 // stack slots for int32 values. |
| 325 int index = GetNextSpillIndex(is_double); |
| 326 if (is_double) { |
| 327 return LDoubleStackSlot::Create(index); |
| 328 } else { |
| 329 return LStackSlot::Create(index); |
| 330 } |
| 317 } | 331 } |
| 318 | 332 |
| 319 | 333 |
| 320 void LChunk::MarkEmptyBlocks() { | 334 void LChunk::MarkEmptyBlocks() { |
| 321 HPhase phase("Mark empty blocks", this); | 335 HPhase phase("Mark empty blocks", this); |
| 322 for (int i = 0; i < graph()->blocks()->length(); ++i) { | 336 for (int i = 0; i < graph()->blocks()->length(); ++i) { |
| 323 HBasicBlock* block = graph()->blocks()->at(i); | 337 HBasicBlock* block = graph()->blocks()->at(i); |
| 324 int first = block->first_instruction_index(); | 338 int first = block->first_instruction_index(); |
| 325 int last = block->last_instruction_index(); | 339 int last = block->last_instruction_index(); |
| 326 LInstruction* first_instr = instructions()->at(first); | 340 LInstruction* first_instr = instructions()->at(first); |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 554 } | 568 } |
| 555 | 569 |
| 556 | 570 |
| 557 LOperand* LChunkBuilder::UseRegisterOrConstantAtStart(HValue* value) { | 571 LOperand* LChunkBuilder::UseRegisterOrConstantAtStart(HValue* value) { |
| 558 return value->IsConstant() | 572 return value->IsConstant() |
| 559 ? chunk_->DefineConstantOperand(HConstant::cast(value)) | 573 ? chunk_->DefineConstantOperand(HConstant::cast(value)) |
| 560 : UseRegisterAtStart(value); | 574 : UseRegisterAtStart(value); |
| 561 } | 575 } |
| 562 | 576 |
| 563 | 577 |
| 578 LOperand* LChunkBuilder::UseAny(HValue* value) { |
| 579 return value->IsConstant() |
| 580 ? chunk_->DefineConstantOperand(HConstant::cast(value)) |
| 581 : Use(value, new LUnallocated(LUnallocated::ANY)); |
| 582 } |
| 583 |
| 584 |
| 564 LOperand* LChunkBuilder::Use(HValue* value, LUnallocated* operand) { | 585 LOperand* LChunkBuilder::Use(HValue* value, LUnallocated* operand) { |
| 565 if (value->EmitAtUses()) { | 586 if (value->EmitAtUses()) { |
| 566 HInstruction* instr = HInstruction::cast(value); | 587 HInstruction* instr = HInstruction::cast(value); |
| 567 VisitInstruction(instr); | 588 VisitInstruction(instr); |
| 568 } | 589 } |
| 569 allocator_->RecordUse(value, operand); | 590 allocator_->RecordUse(value, operand); |
| 570 return operand; | 591 return operand; |
| 571 } | 592 } |
| 572 | 593 |
| 573 | 594 |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 726 | 747 |
| 727 LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op, | 748 LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op, |
| 728 HArithmeticBinaryOperation* instr) { | 749 HArithmeticBinaryOperation* instr) { |
| 729 Abort("Unimplemented: %s", "DoArithmeticD"); | 750 Abort("Unimplemented: %s", "DoArithmeticD"); |
| 730 return NULL; | 751 return NULL; |
| 731 } | 752 } |
| 732 | 753 |
| 733 | 754 |
| 734 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, | 755 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, |
| 735 HArithmeticBinaryOperation* instr) { | 756 HArithmeticBinaryOperation* instr) { |
| 736 Abort("Unimplemented: %s", "DoArithmeticT"); | 757 ASSERT(op == Token::ADD || |
| 737 return NULL; | 758 op == Token::DIV || |
| 738 } | 759 op == Token::MOD || |
| 739 | 760 op == Token::MUL || |
| 740 void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) { | 761 op == Token::SUB); |
| 741 Abort("Unimplemented: %s", "DoBasicBlock"); | 762 HValue* left = instr->left(); |
| 763 HValue* right = instr->right(); |
| 764 ASSERT(left->representation().IsTagged()); |
| 765 ASSERT(right->representation().IsTagged()); |
| 766 LOperand* left_operand = UseFixed(left, rdx); |
| 767 LOperand* right_operand = UseFixed(right, rax); |
| 768 LArithmeticT* result = new LArithmeticT(op, left_operand, right_operand); |
| 769 return MarkAsCall(DefineFixed(result, rax), instr); |
| 742 } | 770 } |
| 743 | 771 |
| 744 | 772 |
| 773 void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) { |
| 774 ASSERT(is_building()); |
| 775 current_block_ = block; |
| 776 next_block_ = next_block; |
| 777 if (block->IsStartBlock()) { |
| 778 block->UpdateEnvironment(graph_->start_environment()); |
| 779 argument_count_ = 0; |
| 780 } else if (block->predecessors()->length() == 1) { |
| 781 // We have a single predecessor => copy environment and outgoing |
| 782 // argument count from the predecessor. |
| 783 ASSERT(block->phis()->length() == 0); |
| 784 HBasicBlock* pred = block->predecessors()->at(0); |
| 785 HEnvironment* last_environment = pred->last_environment(); |
| 786 ASSERT(last_environment != NULL); |
| 787 // Only copy the environment, if it is later used again. |
| 788 if (pred->end()->SecondSuccessor() == NULL) { |
| 789 ASSERT(pred->end()->FirstSuccessor() == block); |
| 790 } else { |
| 791 if (pred->end()->FirstSuccessor()->block_id() > block->block_id() || |
| 792 pred->end()->SecondSuccessor()->block_id() > block->block_id()) { |
| 793 last_environment = last_environment->Copy(); |
| 794 } |
| 795 } |
| 796 block->UpdateEnvironment(last_environment); |
| 797 ASSERT(pred->argument_count() >= 0); |
| 798 argument_count_ = pred->argument_count(); |
| 799 } else { |
| 800 // We are at a state join => process phis. |
| 801 HBasicBlock* pred = block->predecessors()->at(0); |
| 802 // No need to copy the environment, it cannot be used later. |
| 803 HEnvironment* last_environment = pred->last_environment(); |
| 804 for (int i = 0; i < block->phis()->length(); ++i) { |
| 805 HPhi* phi = block->phis()->at(i); |
| 806 last_environment->SetValueAt(phi->merged_index(), phi); |
| 807 } |
| 808 for (int i = 0; i < block->deleted_phis()->length(); ++i) { |
| 809 last_environment->SetValueAt(block->deleted_phis()->at(i), |
| 810 graph_->GetConstantUndefined()); |
| 811 } |
| 812 block->UpdateEnvironment(last_environment); |
| 813 // Pick up the outgoing argument count of one of the predecessors. |
| 814 argument_count_ = pred->argument_count(); |
| 815 } |
| 816 HInstruction* current = block->first(); |
| 817 int start = chunk_->instructions()->length(); |
| 818 while (current != NULL && !is_aborted()) { |
| 819 // Code for constants in registers is generated lazily. |
| 820 if (!current->EmitAtUses()) { |
| 821 VisitInstruction(current); |
| 822 } |
| 823 current = current->next(); |
| 824 } |
| 825 int end = chunk_->instructions()->length() - 1; |
| 826 if (end >= start) { |
| 827 block->set_first_instruction_index(start); |
| 828 block->set_last_instruction_index(end); |
| 829 } |
| 830 block->set_argument_count(argument_count_); |
| 831 next_block_ = NULL; |
| 832 current_block_ = NULL; |
| 833 } |
| 834 |
| 835 |
| 745 void LChunkBuilder::VisitInstruction(HInstruction* current) { | 836 void LChunkBuilder::VisitInstruction(HInstruction* current) { |
| 746 HInstruction* old_current = current_instruction_; | 837 HInstruction* old_current = current_instruction_; |
| 747 current_instruction_ = current; | 838 current_instruction_ = current; |
| 748 allocator_->BeginInstruction(); | 839 allocator_->BeginInstruction(); |
| 749 if (current->has_position()) position_ = current->position(); | 840 if (current->has_position()) position_ = current->position(); |
| 750 LInstruction* instr = current->CompileToLithium(this); | 841 LInstruction* instr = current->CompileToLithium(this); |
| 751 | 842 |
| 752 if (instr != NULL) { | 843 if (instr != NULL) { |
| 753 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { | 844 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { |
| 754 instr = AssignPointerMap(instr); | 845 instr = AssignPointerMap(instr); |
| 755 } | 846 } |
| 756 if (FLAG_stress_environments && !instr->HasEnvironment()) { | 847 if (FLAG_stress_environments && !instr->HasEnvironment()) { |
| 757 instr = AssignEnvironment(instr); | 848 instr = AssignEnvironment(instr); |
| 758 } | 849 } |
| 759 if (current->IsBranch()) { | 850 if (current->IsTest() && !instr->IsGoto()) { |
| 760 instr->set_hydrogen_value(HBranch::cast(current)->value()); | 851 ASSERT(instr->IsControl()); |
| 852 HTest* test = HTest::cast(current); |
| 853 instr->set_hydrogen_value(test->value()); |
| 854 HBasicBlock* first = test->FirstSuccessor(); |
| 855 HBasicBlock* second = test->SecondSuccessor(); |
| 856 ASSERT(first != NULL && second != NULL); |
| 857 instr->SetBranchTargets(first->block_id(), second->block_id()); |
| 761 } else { | 858 } else { |
| 762 instr->set_hydrogen_value(current); | 859 instr->set_hydrogen_value(current); |
| 763 } | 860 } |
| 764 | 861 |
| 765 int index = chunk_->AddInstruction(instr, current_block_); | 862 int index = chunk_->AddInstruction(instr, current_block_); |
| 766 allocator_->SummarizeInstruction(index); | 863 allocator_->SummarizeInstruction(index); |
| 767 } else { | 864 } else { |
| 768 // This instruction should be omitted. | 865 // This instruction should be omitted. |
| 769 allocator_->OmitInstruction(); | 866 allocator_->OmitInstruction(); |
| 770 } | 867 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 787 outer); | 884 outer); |
| 788 int argument_index = 0; | 885 int argument_index = 0; |
| 789 for (int i = 0; i < value_count; ++i) { | 886 for (int i = 0; i < value_count; ++i) { |
| 790 HValue* value = hydrogen_env->values()->at(i); | 887 HValue* value = hydrogen_env->values()->at(i); |
| 791 LOperand* op = NULL; | 888 LOperand* op = NULL; |
| 792 if (value->IsArgumentsObject()) { | 889 if (value->IsArgumentsObject()) { |
| 793 op = NULL; | 890 op = NULL; |
| 794 } else if (value->IsPushArgument()) { | 891 } else if (value->IsPushArgument()) { |
| 795 op = new LArgument(argument_index++); | 892 op = new LArgument(argument_index++); |
| 796 } else { | 893 } else { |
| 797 op = UseOrConstant(value); | 894 op = UseAny(value); |
| 798 if (op->IsUnallocated()) { | |
| 799 LUnallocated* unalloc = LUnallocated::cast(op); | |
| 800 unalloc->set_policy(LUnallocated::ANY); | |
| 801 } | |
| 802 } | 895 } |
| 803 result->AddValue(op, value->representation()); | 896 result->AddValue(op, value->representation()); |
| 804 } | 897 } |
| 805 | 898 |
| 806 return result; | 899 return result; |
| 807 } | 900 } |
| 808 | 901 |
| 809 | 902 |
| 810 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) { | 903 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) { |
| 811 Abort("Unimplemented: %s", "DoGoto"); | 904 LGoto* result = new LGoto(instr->FirstSuccessor()->block_id(), |
| 905 instr->include_stack_check()); |
| 906 return (instr->include_stack_check()) |
| 907 ? AssignPointerMap(result) |
| 908 : result; |
| 909 } |
| 910 |
| 911 |
| 912 LInstruction* LChunkBuilder::DoTest(HTest* instr) { |
| 913 HValue* v = instr->value(); |
| 914 if (v->EmitAtUses()) { |
| 915 if (v->IsClassOfTest()) { |
| 916 HClassOfTest* compare = HClassOfTest::cast(v); |
| 917 ASSERT(compare->value()->representation().IsTagged()); |
| 918 |
| 919 return new LClassOfTestAndBranch(UseTempRegister(compare->value()), |
| 920 TempRegister()); |
| 921 } else if (v->IsCompare()) { |
| 922 HCompare* compare = HCompare::cast(v); |
| 923 Token::Value op = compare->token(); |
| 924 HValue* left = compare->left(); |
| 925 HValue* right = compare->right(); |
| 926 Representation r = compare->GetInputRepresentation(); |
| 927 if (r.IsInteger32()) { |
| 928 ASSERT(left->representation().IsInteger32()); |
| 929 ASSERT(right->representation().IsInteger32()); |
| 930 |
| 931 return new LCmpIDAndBranch(UseRegisterAtStart(left), |
| 932 UseOrConstantAtStart(right)); |
| 933 } else if (r.IsDouble()) { |
| 934 ASSERT(left->representation().IsDouble()); |
| 935 ASSERT(right->representation().IsDouble()); |
| 936 |
| 937 return new LCmpIDAndBranch(UseRegisterAtStart(left), |
| 938 UseRegisterAtStart(right)); |
| 939 } else { |
| 940 ASSERT(left->representation().IsTagged()); |
| 941 ASSERT(right->representation().IsTagged()); |
| 942 bool reversed = op == Token::GT || op == Token::LTE; |
| 943 LOperand* left_operand = UseFixed(left, reversed ? rax : rdx); |
| 944 LOperand* right_operand = UseFixed(right, reversed ? rdx : rax); |
| 945 LCmpTAndBranch* result = new LCmpTAndBranch(left_operand, |
| 946 right_operand); |
| 947 return MarkAsCall(result, instr); |
| 948 } |
| 949 } else if (v->IsIsSmi()) { |
| 950 HIsSmi* compare = HIsSmi::cast(v); |
| 951 ASSERT(compare->value()->representation().IsTagged()); |
| 952 |
| 953 return new LIsSmiAndBranch(Use(compare->value())); |
| 954 } else if (v->IsHasInstanceType()) { |
| 955 HHasInstanceType* compare = HHasInstanceType::cast(v); |
| 956 ASSERT(compare->value()->representation().IsTagged()); |
| 957 |
| 958 return new LHasInstanceTypeAndBranch( |
| 959 UseRegisterAtStart(compare->value())); |
| 960 } else if (v->IsHasCachedArrayIndex()) { |
| 961 HHasCachedArrayIndex* compare = HHasCachedArrayIndex::cast(v); |
| 962 ASSERT(compare->value()->representation().IsTagged()); |
| 963 |
| 964 return new LHasCachedArrayIndexAndBranch( |
| 965 UseRegisterAtStart(compare->value())); |
| 966 } else if (v->IsIsNull()) { |
| 967 HIsNull* compare = HIsNull::cast(v); |
| 968 ASSERT(compare->value()->representation().IsTagged()); |
| 969 |
| 970 // We only need a temp register for non-strict compare. |
| 971 LOperand* temp = compare->is_strict() ? NULL : TempRegister(); |
| 972 return new LIsNullAndBranch(UseRegisterAtStart(compare->value()), |
| 973 temp); |
| 974 } else if (v->IsIsObject()) { |
| 975 HIsObject* compare = HIsObject::cast(v); |
| 976 ASSERT(compare->value()->representation().IsTagged()); |
| 977 return new LIsObjectAndBranch(UseRegisterAtStart(compare->value())); |
| 978 } else if (v->IsCompareJSObjectEq()) { |
| 979 HCompareJSObjectEq* compare = HCompareJSObjectEq::cast(v); |
| 980 return new LCmpJSObjectEqAndBranch(UseRegisterAtStart(compare->left()), |
| 981 UseRegisterAtStart(compare->right())); |
| 982 } else if (v->IsInstanceOf()) { |
| 983 HInstanceOf* instance_of = HInstanceOf::cast(v); |
| 984 LInstanceOfAndBranch* result = |
| 985 new LInstanceOfAndBranch( |
| 986 UseFixed(instance_of->left(), InstanceofStub::left()), |
| 987 UseFixed(instance_of->right(), InstanceofStub::right())); |
| 988 return MarkAsCall(result, instr); |
| 989 } else if (v->IsTypeofIs()) { |
| 990 HTypeofIs* typeof_is = HTypeofIs::cast(v); |
| 991 return new LTypeofIsAndBranch(UseTempRegister(typeof_is->value())); |
| 992 } else { |
| 993 if (v->IsConstant()) { |
| 994 if (HConstant::cast(v)->handle()->IsTrue()) { |
| 995 return new LGoto(instr->FirstSuccessor()->block_id()); |
| 996 } else if (HConstant::cast(v)->handle()->IsFalse()) { |
| 997 return new LGoto(instr->SecondSuccessor()->block_id()); |
| 998 } |
| 999 } |
| 1000 Abort("Undefined compare before branch"); |
| 1001 return NULL; |
| 1002 } |
| 1003 } |
| 1004 return new LBranch(UseRegisterAtStart(v)); |
| 1005 } |
| 1006 |
| 1007 |
| 1008 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) { |
| 1009 Abort("Unimplemented: %s", "DoCompareMap"); |
| 812 return NULL; | 1010 return NULL; |
| 813 } | 1011 } |
| 814 | 1012 |
| 815 | |
| 816 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { | |
| 817 Abort("Unimplemented: %s", "DoBranch"); | |
| 818 return NULL; | |
| 819 } | |
| 820 | |
| 821 | |
| 822 LInstruction* LChunkBuilder::DoCompareMapAndBranch( | |
| 823 HCompareMapAndBranch* instr) { | |
| 824 Abort("Unimplemented: %s", "DoCompareMapAndBranch"); | |
| 825 return NULL; | |
| 826 } | |
| 827 | |
| 828 | 1013 |
| 829 LInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* length) { | 1014 LInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* length) { |
| 830 Abort("Unimplemented: %s", "DoArgumentsLength"); | 1015 Abort("Unimplemented: %s", "DoArgumentsLength"); |
| 831 return NULL; | 1016 return NULL; |
| 832 } | 1017 } |
| 833 | 1018 |
| 834 | 1019 |
| 835 LInstruction* LChunkBuilder::DoArgumentsElements(HArgumentsElements* elems) { | 1020 LInstruction* LChunkBuilder::DoArgumentsElements(HArgumentsElements* elems) { |
| 836 Abort("Unimplemented: %s", "DoArgumentsElements"); | 1021 Abort("Unimplemented: %s", "DoArgumentsElements"); |
| 837 return NULL; | 1022 return NULL; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 857 } | 1042 } |
| 858 | 1043 |
| 859 | 1044 |
| 860 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) { | 1045 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) { |
| 861 Abort("Unimplemented: %s", "DoPushArgument"); | 1046 Abort("Unimplemented: %s", "DoPushArgument"); |
| 862 return NULL; | 1047 return NULL; |
| 863 } | 1048 } |
| 864 | 1049 |
| 865 | 1050 |
| 866 LInstruction* LChunkBuilder::DoGlobalObject(HGlobalObject* instr) { | 1051 LInstruction* LChunkBuilder::DoGlobalObject(HGlobalObject* instr) { |
| 867 Abort("Unimplemented: %s", "DoGlobalObject"); | 1052 return DefineAsRegister(new LGlobalObject); |
| 868 return NULL; | |
| 869 } | 1053 } |
| 870 | 1054 |
| 871 | 1055 |
| 872 LInstruction* LChunkBuilder::DoGlobalReceiver(HGlobalReceiver* instr) { | 1056 LInstruction* LChunkBuilder::DoGlobalReceiver(HGlobalReceiver* instr) { |
| 873 Abort("Unimplemented: %s", "DoGlobalReceiver"); | 1057 Abort("Unimplemented: %s", "DoGlobalReceiver"); |
| 874 return NULL; | 1058 return NULL; |
| 875 } | 1059 } |
| 876 | 1060 |
| 877 | 1061 |
| 878 LInstruction* LChunkBuilder::DoCallConstantFunction( | 1062 LInstruction* LChunkBuilder::DoCallConstantFunction( |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 984 } | 1168 } |
| 985 | 1169 |
| 986 | 1170 |
| 987 LInstruction* LChunkBuilder::DoMul(HMul* instr) { | 1171 LInstruction* LChunkBuilder::DoMul(HMul* instr) { |
| 988 Abort("Unimplemented: %s", "DoMul"); | 1172 Abort("Unimplemented: %s", "DoMul"); |
| 989 return NULL; | 1173 return NULL; |
| 990 } | 1174 } |
| 991 | 1175 |
| 992 | 1176 |
| 993 LInstruction* LChunkBuilder::DoSub(HSub* instr) { | 1177 LInstruction* LChunkBuilder::DoSub(HSub* instr) { |
| 994 Abort("Unimplemented: %s", "DoSub"); | 1178 if (instr->representation().IsInteger32()) { |
| 995 return NULL; | 1179 ASSERT(instr->left()->representation().IsInteger32()); |
| 1180 ASSERT(instr->right()->representation().IsInteger32()); |
| 1181 LOperand* left = UseRegisterAtStart(instr->left()); |
| 1182 LOperand* right = UseOrConstantAtStart(instr->right()); |
| 1183 LSubI* sub = new LSubI(left, right); |
| 1184 LInstruction* result = DefineSameAsFirst(sub); |
| 1185 if (instr->CheckFlag(HValue::kCanOverflow)) { |
| 1186 result = AssignEnvironment(result); |
| 1187 } |
| 1188 return result; |
| 1189 } else if (instr->representation().IsDouble()) { |
| 1190 return DoArithmeticD(Token::SUB, instr); |
| 1191 } else { |
| 1192 ASSERT(instr->representation().IsTagged()); |
| 1193 return DoArithmeticT(Token::SUB, instr); |
| 1194 } |
| 996 } | 1195 } |
| 997 | 1196 |
| 998 | 1197 |
| 999 LInstruction* LChunkBuilder::DoAdd(HAdd* instr) { | 1198 LInstruction* LChunkBuilder::DoAdd(HAdd* instr) { |
| 1000 Abort("Unimplemented: %s", "DoAdd"); | 1199 if (instr->representation().IsInteger32()) { |
| 1200 ASSERT(instr->left()->representation().IsInteger32()); |
| 1201 ASSERT(instr->right()->representation().IsInteger32()); |
| 1202 LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand()); |
| 1203 LOperand* right = UseOrConstantAtStart(instr->MostConstantOperand()); |
| 1204 LAddI* add = new LAddI(left, right); |
| 1205 LInstruction* result = DefineSameAsFirst(add); |
| 1206 if (instr->CheckFlag(HValue::kCanOverflow)) { |
| 1207 result = AssignEnvironment(result); |
| 1208 } |
| 1209 return result; |
| 1210 } else if (instr->representation().IsDouble()) { |
| 1211 Abort("Unimplemented: %s", "DoAdd on Doubles"); |
| 1212 } else { |
| 1213 ASSERT(instr->representation().IsTagged()); |
| 1214 return DoArithmeticT(Token::ADD, instr); |
| 1215 } |
| 1001 return NULL; | 1216 return NULL; |
| 1002 } | 1217 } |
| 1003 | 1218 |
| 1004 | 1219 |
| 1005 LInstruction* LChunkBuilder::DoPower(HPower* instr) { | 1220 LInstruction* LChunkBuilder::DoPower(HPower* instr) { |
| 1006 Abort("Unimplemented: %s", "DoPower"); | 1221 Abort("Unimplemented: %s", "DoPower"); |
| 1007 return NULL; | 1222 return NULL; |
| 1008 } | 1223 } |
| 1009 | 1224 |
| 1010 | 1225 |
| 1011 LInstruction* LChunkBuilder::DoCompare(HCompare* instr) { | 1226 LInstruction* LChunkBuilder::DoCompare(HCompare* instr) { |
| 1012 Abort("Unimplemented: %s", "DoCompare"); | 1227 Token::Value op = instr->token(); |
| 1013 return NULL; | 1228 Representation r = instr->GetInputRepresentation(); |
| 1229 if (r.IsInteger32()) { |
| 1230 ASSERT(instr->left()->representation().IsInteger32()); |
| 1231 ASSERT(instr->right()->representation().IsInteger32()); |
| 1232 LOperand* left = UseRegisterAtStart(instr->left()); |
| 1233 LOperand* right = UseOrConstantAtStart(instr->right()); |
| 1234 return DefineAsRegister(new LCmpID(left, right)); |
| 1235 } else if (r.IsDouble()) { |
| 1236 ASSERT(instr->left()->representation().IsDouble()); |
| 1237 ASSERT(instr->right()->representation().IsDouble()); |
| 1238 LOperand* left = UseRegisterAtStart(instr->left()); |
| 1239 LOperand* right = UseRegisterAtStart(instr->right()); |
| 1240 return DefineAsRegister(new LCmpID(left, right)); |
| 1241 } else { |
| 1242 ASSERT(instr->left()->representation().IsTagged()); |
| 1243 ASSERT(instr->right()->representation().IsTagged()); |
| 1244 bool reversed = (op == Token::GT || op == Token::LTE); |
| 1245 LOperand* left = UseFixed(instr->left(), reversed ? rax : rdx); |
| 1246 LOperand* right = UseFixed(instr->right(), reversed ? rdx : rax); |
| 1247 LCmpT* result = new LCmpT(left, right); |
| 1248 return MarkAsCall(DefineFixed(result, rax), instr); |
| 1249 } |
| 1014 } | 1250 } |
| 1015 | 1251 |
| 1016 | 1252 |
| 1017 LInstruction* LChunkBuilder::DoCompareJSObjectEq( | 1253 LInstruction* LChunkBuilder::DoCompareJSObjectEq( |
| 1018 HCompareJSObjectEq* instr) { | 1254 HCompareJSObjectEq* instr) { |
| 1019 Abort("Unimplemented: %s", "DoCompareJSObjectEq"); | 1255 LOperand* left = UseRegisterAtStart(instr->left()); |
| 1020 return NULL; | 1256 LOperand* right = UseRegisterAtStart(instr->right()); |
| 1257 LCmpJSObjectEq* result = new LCmpJSObjectEq(left, right); |
| 1258 return DefineAsRegister(result); |
| 1021 } | 1259 } |
| 1022 | 1260 |
| 1023 | 1261 |
| 1024 LInstruction* LChunkBuilder::DoIsNull(HIsNull* instr) { | 1262 LInstruction* LChunkBuilder::DoIsNull(HIsNull* instr) { |
| 1025 Abort("Unimplemented: %s", "DoIsNull"); | 1263 ASSERT(instr->value()->representation().IsTagged()); |
| 1026 return NULL; | 1264 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1265 |
| 1266 return DefineAsRegister(new LIsNull(value)); |
| 1027 } | 1267 } |
| 1028 | 1268 |
| 1029 | 1269 |
| 1030 LInstruction* LChunkBuilder::DoIsObject(HIsObject* instr) { | 1270 LInstruction* LChunkBuilder::DoIsObject(HIsObject* instr) { |
| 1031 Abort("Unimplemented: %s", "DoIsObject"); | 1271 ASSERT(instr->value()->representation().IsTagged()); |
| 1032 return NULL; | 1272 LOperand* value = UseRegister(instr->value()); |
| 1273 |
| 1274 return DefineAsRegister(new LIsObject(value)); |
| 1033 } | 1275 } |
| 1034 | 1276 |
| 1035 | 1277 |
| 1036 LInstruction* LChunkBuilder::DoIsSmi(HIsSmi* instr) { | 1278 LInstruction* LChunkBuilder::DoIsSmi(HIsSmi* instr) { |
| 1037 Abort("Unimplemented: %s", "DoIsSmi"); | 1279 ASSERT(instr->value()->representation().IsTagged()); |
| 1038 return NULL; | 1280 LOperand* value = UseAtStart(instr->value()); |
| 1281 |
| 1282 return DefineAsRegister(new LIsSmi(value)); |
| 1039 } | 1283 } |
| 1040 | 1284 |
| 1041 | 1285 |
| 1042 LInstruction* LChunkBuilder::DoHasInstanceType(HHasInstanceType* instr) { | 1286 LInstruction* LChunkBuilder::DoHasInstanceType(HHasInstanceType* instr) { |
| 1043 Abort("Unimplemented: %s", "DoHasInstanceType"); | 1287 Abort("Unimplemented: %s", "DoHasInstanceType"); |
| 1044 return NULL; | 1288 return NULL; |
| 1045 } | 1289 } |
| 1046 | 1290 |
| 1047 | 1291 |
| 1048 LInstruction* LChunkBuilder::DoHasCachedArrayIndex( | 1292 LInstruction* LChunkBuilder::DoHasCachedArrayIndex( |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1082 } | 1326 } |
| 1083 | 1327 |
| 1084 | 1328 |
| 1085 LInstruction* LChunkBuilder::DoThrow(HThrow* instr) { | 1329 LInstruction* LChunkBuilder::DoThrow(HThrow* instr) { |
| 1086 Abort("Unimplemented: %s", "DoThrow"); | 1330 Abort("Unimplemented: %s", "DoThrow"); |
| 1087 return NULL; | 1331 return NULL; |
| 1088 } | 1332 } |
| 1089 | 1333 |
| 1090 | 1334 |
| 1091 LInstruction* LChunkBuilder::DoChange(HChange* instr) { | 1335 LInstruction* LChunkBuilder::DoChange(HChange* instr) { |
| 1092 Abort("Unimplemented: %s", "DoChange"); | 1336 Representation from = instr->from(); |
| 1337 Representation to = instr->to(); |
| 1338 if (from.IsTagged()) { |
| 1339 if (to.IsDouble()) { |
| 1340 LOperand* value = UseRegister(instr->value()); |
| 1341 LNumberUntagD* res = new LNumberUntagD(value); |
| 1342 return AssignEnvironment(DefineAsRegister(res)); |
| 1343 } else { |
| 1344 ASSERT(to.IsInteger32()); |
| 1345 LOperand* value = UseRegister(instr->value()); |
| 1346 bool needs_check = !instr->value()->type().IsSmi(); |
| 1347 if (needs_check) { |
| 1348 LOperand* xmm_temp = |
| 1349 (instr->CanTruncateToInt32() && |
| 1350 Isolate::Current()->cpu_features()->IsSupported(SSE3)) |
| 1351 ? NULL |
| 1352 : FixedTemp(xmm1); |
| 1353 LTaggedToI* res = new LTaggedToI(value, xmm_temp); |
| 1354 return AssignEnvironment(DefineSameAsFirst(res)); |
| 1355 } else { |
| 1356 return DefineSameAsFirst(new LSmiUntag(value, needs_check)); |
| 1357 } |
| 1358 } |
| 1359 } else if (from.IsDouble()) { |
| 1360 if (to.IsTagged()) { |
| 1361 LOperand* value = UseRegister(instr->value()); |
| 1362 LOperand* temp = TempRegister(); |
| 1363 |
| 1364 // Make sure that temp and result_temp are different registers. |
| 1365 LUnallocated* result_temp = TempRegister(); |
| 1366 LNumberTagD* result = new LNumberTagD(value, temp); |
| 1367 return AssignPointerMap(Define(result, result_temp)); |
| 1368 } else { |
| 1369 ASSERT(to.IsInteger32()); |
| 1370 bool needs_temp = instr->CanTruncateToInt32() && |
| 1371 !Isolate::Current()->cpu_features()->IsSupported(SSE3); |
| 1372 LOperand* value = needs_temp ? |
| 1373 UseTempRegister(instr->value()) : UseRegister(instr->value()); |
| 1374 LOperand* temp = needs_temp ? TempRegister() : NULL; |
| 1375 return AssignEnvironment(DefineAsRegister(new LDoubleToI(value, temp))); |
| 1376 } |
| 1377 } else if (from.IsInteger32()) { |
| 1378 if (to.IsTagged()) { |
| 1379 HValue* val = instr->value(); |
| 1380 LOperand* value = UseRegister(val); |
| 1381 if (val->HasRange() && val->range()->IsInSmiRange()) { |
| 1382 return DefineSameAsFirst(new LSmiTag(value)); |
| 1383 } else { |
| 1384 LNumberTagI* result = new LNumberTagI(value); |
| 1385 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result))); |
| 1386 } |
| 1387 } else { |
| 1388 ASSERT(to.IsDouble()); |
| 1389 return DefineAsRegister(new LInteger32ToDouble(Use(instr->value()))); |
| 1390 } |
| 1391 } |
| 1392 UNREACHABLE(); |
| 1093 return NULL; | 1393 return NULL; |
| 1094 } | 1394 } |
| 1095 | 1395 |
| 1096 | 1396 |
| 1097 LInstruction* LChunkBuilder::DoCheckNonSmi(HCheckNonSmi* instr) { | 1397 LInstruction* LChunkBuilder::DoCheckNonSmi(HCheckNonSmi* instr) { |
| 1098 Abort("Unimplemented: %s", "DoCheckNonSmi"); | 1398 Abort("Unimplemented: %s", "DoCheckNonSmi"); |
| 1099 return NULL; | 1399 return NULL; |
| 1100 } | 1400 } |
| 1101 | 1401 |
| 1102 | 1402 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1124 } | 1424 } |
| 1125 | 1425 |
| 1126 | 1426 |
| 1127 LInstruction* LChunkBuilder::DoCheckMap(HCheckMap* instr) { | 1427 LInstruction* LChunkBuilder::DoCheckMap(HCheckMap* instr) { |
| 1128 Abort("Unimplemented: %s", "DoCheckMap"); | 1428 Abort("Unimplemented: %s", "DoCheckMap"); |
| 1129 return NULL; | 1429 return NULL; |
| 1130 } | 1430 } |
| 1131 | 1431 |
| 1132 | 1432 |
| 1133 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) { | 1433 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) { |
| 1134 Abort("Unimplemented: %s", "DoReturn"); | 1434 return new LReturn(UseFixed(instr->value(), rax)); |
| 1135 return NULL; | |
| 1136 } | 1435 } |
| 1137 | 1436 |
| 1138 | 1437 |
| 1139 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { | 1438 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { |
| 1140 Abort("Unimplemented: %s", "DoConstant"); | 1439 Representation r = instr->representation(); |
| 1141 return NULL; | 1440 if (r.IsInteger32()) { |
| 1441 int32_t value = instr->Integer32Value(); |
| 1442 return DefineAsRegister(new LConstantI(value)); |
| 1443 } else if (r.IsDouble()) { |
| 1444 double value = instr->DoubleValue(); |
| 1445 LOperand* temp = TempRegister(); |
| 1446 return DefineAsRegister(new LConstantD(value, temp)); |
| 1447 } else if (r.IsTagged()) { |
| 1448 return DefineAsRegister(new LConstantT(instr->handle())); |
| 1449 } else { |
| 1450 UNREACHABLE(); |
| 1451 return NULL; |
| 1452 } |
| 1142 } | 1453 } |
| 1143 | 1454 |
| 1144 | 1455 |
| 1145 LInstruction* LChunkBuilder::DoLoadGlobal(HLoadGlobal* instr) { | 1456 LInstruction* LChunkBuilder::DoLoadGlobal(HLoadGlobal* instr) { |
| 1146 Abort("Unimplemented: %s", "DoLoadGlobal"); | 1457 Abort("Unimplemented: %s", "DoLoadGlobal"); |
| 1147 return NULL; | 1458 return NULL; |
| 1148 } | 1459 } |
| 1149 | 1460 |
| 1150 | 1461 |
| 1151 LInstruction* LChunkBuilder::DoStoreGlobal(HStoreGlobal* instr) { | 1462 LInstruction* LChunkBuilder::DoStoreGlobal(HStoreGlobal* instr) { |
| 1152 Abort("Unimplemented: %s", "DoStoreGlobal"); | 1463 Abort("Unimplemented: %s", "DoStoreGlobal"); |
| 1153 return NULL; | 1464 return NULL; |
| 1154 } | 1465 } |
| 1155 | 1466 |
| 1156 | 1467 |
| 1468 LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) { |
| 1469 Abort("Unimplemented: %s", "DoLoadContextSlot"); |
| 1470 return NULL; |
| 1471 } |
| 1472 |
| 1473 |
| 1157 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) { | 1474 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) { |
| 1158 Abort("Unimplemented: %s", "DoLoadNamedField"); | 1475 Abort("Unimplemented: %s", "DoLoadNamedField"); |
| 1159 return NULL; | 1476 return NULL; |
| 1160 } | 1477 } |
| 1161 | 1478 |
| 1162 | 1479 |
| 1163 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) { | 1480 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) { |
| 1164 Abort("Unimplemented: %s", "DoLoadNamedGeneric"); | 1481 Abort("Unimplemented: %s", "DoLoadNamedGeneric"); |
| 1165 return NULL; | 1482 return NULL; |
| 1166 } | 1483 } |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1210 return NULL; | 1527 return NULL; |
| 1211 } | 1528 } |
| 1212 | 1529 |
| 1213 | 1530 |
| 1214 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) { | 1531 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) { |
| 1215 Abort("Unimplemented: %s", "DoStoreNamedGeneric"); | 1532 Abort("Unimplemented: %s", "DoStoreNamedGeneric"); |
| 1216 return NULL; | 1533 return NULL; |
| 1217 } | 1534 } |
| 1218 | 1535 |
| 1219 | 1536 |
| 1537 LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) { |
| 1538 Abort("Unimplemented: %s", "DoStringCharCodeAt"); |
| 1539 return NULL; |
| 1540 } |
| 1541 |
| 1542 |
| 1543 LInstruction* LChunkBuilder::DoStringLength(HStringLength* instr) { |
| 1544 Abort("Unimplemented: %s", "DoStringLength"); |
| 1545 return NULL; |
| 1546 } |
| 1547 |
| 1548 |
| 1220 LInstruction* LChunkBuilder::DoArrayLiteral(HArrayLiteral* instr) { | 1549 LInstruction* LChunkBuilder::DoArrayLiteral(HArrayLiteral* instr) { |
| 1221 Abort("Unimplemented: %s", "DoArrayLiteral"); | 1550 Abort("Unimplemented: %s", "DoArrayLiteral"); |
| 1222 return NULL; | 1551 return NULL; |
| 1223 } | 1552 } |
| 1224 | 1553 |
| 1225 | 1554 |
| 1226 LInstruction* LChunkBuilder::DoObjectLiteral(HObjectLiteral* instr) { | 1555 LInstruction* LChunkBuilder::DoObjectLiteral(HObjectLiteral* instr) { |
| 1227 Abort("Unimplemented: %s", "DoObjectLiteral"); | 1556 Abort("Unimplemented: %s", "DoObjectLiteral"); |
| 1228 return NULL; | 1557 return NULL; |
| 1229 } | 1558 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1247 } | 1576 } |
| 1248 | 1577 |
| 1249 | 1578 |
| 1250 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) { | 1579 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) { |
| 1251 Abort("Unimplemented: %s", "DoOsrEntry"); | 1580 Abort("Unimplemented: %s", "DoOsrEntry"); |
| 1252 return NULL; | 1581 return NULL; |
| 1253 } | 1582 } |
| 1254 | 1583 |
| 1255 | 1584 |
| 1256 LInstruction* LChunkBuilder::DoParameter(HParameter* instr) { | 1585 LInstruction* LChunkBuilder::DoParameter(HParameter* instr) { |
| 1257 Abort("Unimplemented: %s", "DoParameter"); | 1586 int spill_index = chunk()->GetParameterStackSlot(instr->index()); |
| 1258 return NULL; | 1587 return DefineAsSpilled(new LParameter, spill_index); |
| 1259 } | 1588 } |
| 1260 | 1589 |
| 1261 | 1590 |
| 1262 LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) { | 1591 LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) { |
| 1263 Abort("Unimplemented: %s", "DoUnknownOSRValue"); | 1592 Abort("Unimplemented: %s", "DoUnknownOSRValue"); |
| 1264 return NULL; | 1593 return NULL; |
| 1265 } | 1594 } |
| 1266 | 1595 |
| 1267 | 1596 |
| 1268 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) { | 1597 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1288 return NULL; | 1617 return NULL; |
| 1289 } | 1618 } |
| 1290 | 1619 |
| 1291 | 1620 |
| 1292 LInstruction* LChunkBuilder::DoTypeofIs(HTypeofIs* instr) { | 1621 LInstruction* LChunkBuilder::DoTypeofIs(HTypeofIs* instr) { |
| 1293 Abort("Unimplemented: %s", "DoTypeofIs"); | 1622 Abort("Unimplemented: %s", "DoTypeofIs"); |
| 1294 return NULL; | 1623 return NULL; |
| 1295 } | 1624 } |
| 1296 | 1625 |
| 1297 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) { | 1626 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) { |
| 1298 Abort("Unimplemented: %s", "DoSimulate"); | 1627 HEnvironment* env = current_block_->last_environment(); |
| 1628 ASSERT(env != NULL); |
| 1629 |
| 1630 env->set_ast_id(instr->ast_id()); |
| 1631 |
| 1632 env->Drop(instr->pop_count()); |
| 1633 for (int i = 0; i < instr->values()->length(); ++i) { |
| 1634 HValue* value = instr->values()->at(i); |
| 1635 if (instr->HasAssignedIndexAt(i)) { |
| 1636 env->Bind(instr->GetAssignedIndexAt(i), value); |
| 1637 } else { |
| 1638 env->Push(value); |
| 1639 } |
| 1640 } |
| 1641 ASSERT(env->length() == instr->environment_length()); |
| 1642 |
| 1643 // If there is an instruction pending deoptimization environment create a |
| 1644 // lazy bailout instruction to capture the environment. |
| 1645 if (pending_deoptimization_ast_id_ == instr->ast_id()) { |
| 1646 LLazyBailout* lazy_bailout = new LLazyBailout; |
| 1647 LInstruction* result = AssignEnvironment(lazy_bailout); |
| 1648 instructions_pending_deoptimization_environment_-> |
| 1649 set_deoptimization_environment(result->environment()); |
| 1650 ClearInstructionPendingDeoptimizationEnvironment(); |
| 1651 return result; |
| 1652 } |
| 1653 |
| 1299 return NULL; | 1654 return NULL; |
| 1300 } | 1655 } |
| 1301 | 1656 |
| 1302 | 1657 |
| 1303 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) { | 1658 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) { |
| 1304 Abort("Unimplemented: %s", "DoStackCheck"); | 1659 return MarkAsCall(new LStackCheck, instr); |
| 1305 return NULL; | |
| 1306 } | 1660 } |
| 1307 | 1661 |
| 1308 | 1662 |
| 1309 LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) { | 1663 LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) { |
| 1310 Abort("Unimplemented: %s", "DoEnterInlined"); | 1664 Abort("Unimplemented: %s", "DoEnterInlined"); |
| 1311 return NULL; | 1665 return NULL; |
| 1312 } | 1666 } |
| 1313 | 1667 |
| 1314 | 1668 |
| 1315 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { | 1669 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { |
| 1316 Abort("Unimplemented: %s", "DoLeaveInlined"); | 1670 Abort("Unimplemented: %s", "DoLeaveInlined"); |
| 1317 return NULL; | 1671 return NULL; |
| 1318 } | 1672 } |
| 1319 | 1673 |
| 1320 } } // namespace v8::internal | 1674 } } // namespace v8::internal |
| 1321 | 1675 |
| 1322 #endif // V8_TARGET_ARCH_X64 | 1676 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |