| 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 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 151 } | 155 } |
| 152 | 156 |
| 153 | 157 |
| 154 const char* LArithmeticT::Mnemonic() const { | 158 const char* LArithmeticT::Mnemonic() const { |
| 155 switch (op()) { | 159 switch (op()) { |
| 156 case Token::ADD: return "add-t"; | 160 case Token::ADD: return "add-t"; |
| 157 case Token::SUB: return "sub-t"; | 161 case Token::SUB: return "sub-t"; |
| 158 case Token::MUL: return "mul-t"; | 162 case Token::MUL: return "mul-t"; |
| 159 case Token::MOD: return "mod-t"; | 163 case Token::MOD: return "mod-t"; |
| 160 case Token::DIV: return "div-t"; | 164 case Token::DIV: return "div-t"; |
| 165 case Token::BIT_AND: return "bit-and-t"; |
| 166 case Token::BIT_OR: return "bit-or-t"; |
| 167 case Token::BIT_XOR: return "bit-xor-t"; |
| 168 case Token::SHL: return "sal-t"; |
| 169 case Token::SAR: return "sar-t"; |
| 170 case Token::SHR: return "shr-t"; |
| 161 default: | 171 default: |
| 162 UNREACHABLE(); | 172 UNREACHABLE(); |
| 163 return NULL; | 173 return NULL; |
| 164 } | 174 } |
| 165 } | 175 } |
| 166 | 176 |
| 167 | 177 |
| 168 void LGoto::PrintDataTo(StringStream* stream) { | 178 void LGoto::PrintDataTo(StringStream* stream) { |
| 169 stream->Add("B%d", block_id()); | 179 stream->Add("B%d", block_id()); |
| 170 } | 180 } |
| 171 | 181 |
| 172 | 182 |
| 173 void LBranch::PrintDataTo(StringStream* stream) { | 183 void LBranch::PrintDataTo(StringStream* stream) { |
| 174 stream->Add("B%d | B%d on ", true_block_id(), false_block_id()); | 184 stream->Add("B%d | B%d on ", true_block_id(), false_block_id()); |
| 175 input()->PrintTo(stream); | 185 InputAt(0)->PrintTo(stream); |
| 176 } | 186 } |
| 177 | 187 |
| 178 | 188 |
| 179 void LCmpIDAndBranch::PrintDataTo(StringStream* stream) { | 189 void LCmpIDAndBranch::PrintDataTo(StringStream* stream) { |
| 180 stream->Add("if "); | 190 stream->Add("if "); |
| 181 left()->PrintTo(stream); | 191 InputAt(0)->PrintTo(stream); |
| 182 stream->Add(" %s ", Token::String(op())); | 192 stream->Add(" %s ", Token::String(op())); |
| 183 right()->PrintTo(stream); | 193 InputAt(1)->PrintTo(stream); |
| 184 stream->Add(" then B%d else B%d", true_block_id(), false_block_id()); | 194 stream->Add(" then B%d else B%d", true_block_id(), false_block_id()); |
| 185 } | 195 } |
| 186 | 196 |
| 187 | 197 |
| 188 void LIsNullAndBranch::PrintDataTo(StringStream* stream) { | 198 void LIsNullAndBranch::PrintDataTo(StringStream* stream) { |
| 189 stream->Add("if "); | 199 stream->Add("if "); |
| 190 input()->PrintTo(stream); | 200 InputAt(0)->PrintTo(stream); |
| 191 stream->Add(is_strict() ? " === null" : " == null"); | 201 stream->Add(is_strict() ? " === null" : " == null"); |
| 192 stream->Add(" then B%d else B%d", true_block_id(), false_block_id()); | 202 stream->Add(" then B%d else B%d", true_block_id(), false_block_id()); |
| 193 } | 203 } |
| 194 | 204 |
| 195 | 205 |
| 196 void LIsObjectAndBranch::PrintDataTo(StringStream* stream) { | 206 void LIsObjectAndBranch::PrintDataTo(StringStream* stream) { |
| 197 stream->Add("if is_object("); | 207 stream->Add("if is_object("); |
| 198 input()->PrintTo(stream); | 208 InputAt(0)->PrintTo(stream); |
| 199 stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); | 209 stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); |
| 200 } | 210 } |
| 201 | 211 |
| 202 | 212 |
| 203 void LIsSmiAndBranch::PrintDataTo(StringStream* stream) { | 213 void LIsSmiAndBranch::PrintDataTo(StringStream* stream) { |
| 204 stream->Add("if is_smi("); | 214 stream->Add("if is_smi("); |
| 205 input()->PrintTo(stream); | 215 InputAt(0)->PrintTo(stream); |
| 206 stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); | 216 stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); |
| 207 } | 217 } |
| 208 | 218 |
| 209 | 219 |
| 210 void LHasInstanceTypeAndBranch::PrintDataTo(StringStream* stream) { | 220 void LHasInstanceTypeAndBranch::PrintDataTo(StringStream* stream) { |
| 211 stream->Add("if has_instance_type("); | 221 stream->Add("if has_instance_type("); |
| 212 input()->PrintTo(stream); | 222 InputAt(0)->PrintTo(stream); |
| 213 stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); | 223 stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); |
| 214 } | 224 } |
| 215 | 225 |
| 216 | 226 |
| 217 void LHasCachedArrayIndexAndBranch::PrintDataTo(StringStream* stream) { | 227 void LHasCachedArrayIndexAndBranch::PrintDataTo(StringStream* stream) { |
| 218 stream->Add("if has_cached_array_index("); | 228 stream->Add("if has_cached_array_index("); |
| 219 input()->PrintTo(stream); | 229 InputAt(0)->PrintTo(stream); |
| 220 stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); | 230 stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); |
| 221 } | 231 } |
| 222 | 232 |
| 223 | 233 |
| 224 void LClassOfTestAndBranch::PrintDataTo(StringStream* stream) { | 234 void LClassOfTestAndBranch::PrintDataTo(StringStream* stream) { |
| 225 stream->Add("if class_of_test("); | 235 stream->Add("if class_of_test("); |
| 226 input()->PrintTo(stream); | 236 InputAt(0)->PrintTo(stream); |
| 227 stream->Add(", \"%o\") then B%d else B%d", | 237 stream->Add(", \"%o\") then B%d else B%d", |
| 228 *hydrogen()->class_name(), | 238 *hydrogen()->class_name(), |
| 229 true_block_id(), | 239 true_block_id(), |
| 230 false_block_id()); | 240 false_block_id()); |
| 231 } | 241 } |
| 232 | 242 |
| 233 | 243 |
| 234 void LTypeofIs::PrintDataTo(StringStream* stream) { | 244 void LTypeofIs::PrintDataTo(StringStream* stream) { |
| 235 input()->PrintTo(stream); | 245 InputAt(0)->PrintTo(stream); |
| 236 stream->Add(" == \"%s\"", *hydrogen()->type_literal()->ToCString()); | 246 stream->Add(" == \"%s\"", *hydrogen()->type_literal()->ToCString()); |
| 237 } | 247 } |
| 238 | 248 |
| 239 | 249 |
| 240 void LTypeofIsAndBranch::PrintDataTo(StringStream* stream) { | 250 void LTypeofIsAndBranch::PrintDataTo(StringStream* stream) { |
| 241 stream->Add("if typeof "); | 251 stream->Add("if typeof "); |
| 242 input()->PrintTo(stream); | 252 InputAt(0)->PrintTo(stream); |
| 243 stream->Add(" == \"%s\" then B%d else B%d", | 253 stream->Add(" == \"%s\" then B%d else B%d", |
| 244 *hydrogen()->type_literal()->ToCString(), | 254 *hydrogen()->type_literal()->ToCString(), |
| 245 true_block_id(), false_block_id()); | 255 true_block_id(), false_block_id()); |
| 246 } | 256 } |
| 247 | 257 |
| 248 | 258 |
| 249 void LCallConstantFunction::PrintDataTo(StringStream* stream) { | 259 void LCallConstantFunction::PrintDataTo(StringStream* stream) { |
| 250 stream->Add("#%d / ", arity()); | 260 stream->Add("#%d / ", arity()); |
| 251 } | 261 } |
| 252 | 262 |
| 253 | 263 |
| 254 void LUnaryMathOperation::PrintDataTo(StringStream* stream) { | 264 void LUnaryMathOperation::PrintDataTo(StringStream* stream) { |
| 255 stream->Add("/%s ", hydrogen()->OpName()); | 265 stream->Add("/%s ", hydrogen()->OpName()); |
| 256 input()->PrintTo(stream); | 266 InputAt(0)->PrintTo(stream); |
| 267 } |
| 268 |
| 269 |
| 270 void LLoadContextSlot::PrintDataTo(StringStream* stream) { |
| 271 stream->Add("(%d, %d)", context_chain_length(), slot_index()); |
| 257 } | 272 } |
| 258 | 273 |
| 259 | 274 |
| 260 void LCallKeyed::PrintDataTo(StringStream* stream) { | 275 void LCallKeyed::PrintDataTo(StringStream* stream) { |
| 261 stream->Add("[ecx] #%d / ", arity()); | 276 stream->Add("[ecx] #%d / ", arity()); |
| 262 } | 277 } |
| 263 | 278 |
| 264 | 279 |
| 265 void LCallNamed::PrintDataTo(StringStream* stream) { | 280 void LCallNamed::PrintDataTo(StringStream* stream) { |
| 266 SmartPointer<char> name_string = name()->ToCString(); | 281 SmartPointer<char> name_string = name()->ToCString(); |
| 267 stream->Add("%s #%d / ", *name_string, arity()); | 282 stream->Add("%s #%d / ", *name_string, arity()); |
| 268 } | 283 } |
| 269 | 284 |
| 270 | 285 |
| 271 void LCallGlobal::PrintDataTo(StringStream* stream) { | 286 void LCallGlobal::PrintDataTo(StringStream* stream) { |
| 272 SmartPointer<char> name_string = name()->ToCString(); | 287 SmartPointer<char> name_string = name()->ToCString(); |
| 273 stream->Add("%s #%d / ", *name_string, arity()); | 288 stream->Add("%s #%d / ", *name_string, arity()); |
| 274 } | 289 } |
| 275 | 290 |
| 276 | 291 |
| 277 void LCallKnownGlobal::PrintDataTo(StringStream* stream) { | 292 void LCallKnownGlobal::PrintDataTo(StringStream* stream) { |
| 278 stream->Add("#%d / ", arity()); | 293 stream->Add("#%d / ", arity()); |
| 279 } | 294 } |
| 280 | 295 |
| 281 | 296 |
| 282 void LCallNew::PrintDataTo(StringStream* stream) { | 297 void LCallNew::PrintDataTo(StringStream* stream) { |
| 283 stream->Add("= "); | 298 stream->Add("= "); |
| 284 input()->PrintTo(stream); | 299 InputAt(0)->PrintTo(stream); |
| 285 stream->Add(" #%d / ", arity()); | 300 stream->Add(" #%d / ", arity()); |
| 286 } | 301 } |
| 287 | 302 |
| 288 | 303 |
| 289 void LClassOfTest::PrintDataTo(StringStream* stream) { | 304 void LClassOfTest::PrintDataTo(StringStream* stream) { |
| 290 stream->Add("= class_of_test("); | 305 stream->Add("= class_of_test("); |
| 291 input()->PrintTo(stream); | 306 InputAt(0)->PrintTo(stream); |
| 292 stream->Add(", \"%o\")", *hydrogen()->class_name()); | 307 stream->Add(", \"%o\")", *hydrogen()->class_name()); |
| 293 } | 308 } |
| 294 | 309 |
| 295 | 310 |
| 296 void LAccessArgumentsAt::PrintDataTo(StringStream* stream) { | 311 void LAccessArgumentsAt::PrintDataTo(StringStream* stream) { |
| 297 arguments()->PrintTo(stream); | 312 arguments()->PrintTo(stream); |
| 298 | 313 |
| 299 stream->Add(" length "); | 314 stream->Add(" length "); |
| 300 length()->PrintTo(stream); | 315 length()->PrintTo(stream); |
| 301 | 316 |
| 302 stream->Add(" index "); | 317 stream->Add(" index "); |
| 303 index()->PrintTo(stream); | 318 index()->PrintTo(stream); |
| 304 } | 319 } |
| 305 | 320 |
| 306 | 321 |
| 307 int LChunk::GetNextSpillIndex(bool is_double) { | 322 int LChunk::GetNextSpillIndex(bool is_double) { |
| 308 // Skip a slot if for a double-width slot. | 323 // Skip a slot if for a double-width slot. |
| 309 if (is_double) spill_slot_count_++; | 324 if (is_double) spill_slot_count_++; |
| 310 return spill_slot_count_++; | 325 return spill_slot_count_++; |
| 311 } | 326 } |
| 312 | 327 |
| 313 | 328 |
| 314 LOperand* LChunk::GetNextSpillSlot(bool is_double) { | 329 LOperand* LChunk::GetNextSpillSlot(bool is_double) { |
| 315 int index = GetNextSpillIndex(is_double); | 330 int index = GetNextSpillIndex(is_double); |
| 316 if (is_double) { | 331 if (is_double) { |
| 317 return LDoubleStackSlot::Create(index); | 332 return LDoubleStackSlot::Create(index); |
| 318 } else { | 333 } else { |
| 319 return LStackSlot::Create(index); | 334 return LStackSlot::Create(index); |
| 320 } | 335 } |
| 321 } | 336 } |
| 322 | 337 |
| 323 | 338 |
| 324 void LChunk::MarkEmptyBlocks() { | 339 void LChunk::MarkEmptyBlocks() { |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 558 } | 573 } |
| 559 | 574 |
| 560 | 575 |
| 561 LOperand* LChunkBuilder::UseRegisterOrConstantAtStart(HValue* value) { | 576 LOperand* LChunkBuilder::UseRegisterOrConstantAtStart(HValue* value) { |
| 562 return value->IsConstant() | 577 return value->IsConstant() |
| 563 ? chunk_->DefineConstantOperand(HConstant::cast(value)) | 578 ? chunk_->DefineConstantOperand(HConstant::cast(value)) |
| 564 : UseRegisterAtStart(value); | 579 : UseRegisterAtStart(value); |
| 565 } | 580 } |
| 566 | 581 |
| 567 | 582 |
| 583 LOperand* LChunkBuilder::UseAny(HValue* value) { |
| 584 return value->IsConstant() |
| 585 ? chunk_->DefineConstantOperand(HConstant::cast(value)) |
| 586 : Use(value, new LUnallocated(LUnallocated::ANY)); |
| 587 } |
| 588 |
| 589 |
| 568 LOperand* LChunkBuilder::Use(HValue* value, LUnallocated* operand) { | 590 LOperand* LChunkBuilder::Use(HValue* value, LUnallocated* operand) { |
| 569 if (value->EmitAtUses()) { | 591 if (value->EmitAtUses()) { |
| 570 HInstruction* instr = HInstruction::cast(value); | 592 HInstruction* instr = HInstruction::cast(value); |
| 571 VisitInstruction(instr); | 593 VisitInstruction(instr); |
| 572 } | 594 } |
| 573 allocator_->RecordUse(value, operand); | 595 allocator_->RecordUse(value, operand); |
| 574 return operand; | 596 return operand; |
| 575 } | 597 } |
| 576 | 598 |
| 577 | 599 |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 716 } | 738 } |
| 717 | 739 |
| 718 | 740 |
| 719 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) { | 741 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) { |
| 720 return AssignEnvironment(new LDeoptimize); | 742 return AssignEnvironment(new LDeoptimize); |
| 721 } | 743 } |
| 722 | 744 |
| 723 | 745 |
| 724 LInstruction* LChunkBuilder::DoBit(Token::Value op, | 746 LInstruction* LChunkBuilder::DoBit(Token::Value op, |
| 725 HBitwiseBinaryOperation* instr) { | 747 HBitwiseBinaryOperation* instr) { |
| 726 ASSERT(instr->representation().IsInteger32()); | 748 if (instr->representation().IsInteger32()) { |
| 727 ASSERT(instr->left()->representation().IsInteger32()); | 749 ASSERT(instr->left()->representation().IsInteger32()); |
| 728 ASSERT(instr->right()->representation().IsInteger32()); | 750 ASSERT(instr->right()->representation().IsInteger32()); |
| 729 | 751 |
| 730 LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand()); | 752 LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand()); |
| 731 LOperand* right = UseOrConstantAtStart(instr->MostConstantOperand()); | 753 LOperand* right = UseOrConstantAtStart(instr->MostConstantOperand()); |
| 732 return DefineSameAsFirst(new LBitI(op, left, right)); | 754 return DefineSameAsFirst(new LBitI(op, left, right)); |
| 755 } else { |
| 756 ASSERT(instr->representation().IsTagged()); |
| 757 ASSERT(instr->left()->representation().IsTagged()); |
| 758 ASSERT(instr->right()->representation().IsTagged()); |
| 759 |
| 760 LOperand* left = UseFixed(instr->left(), edx); |
| 761 LOperand* right = UseFixed(instr->right(), eax); |
| 762 LArithmeticT* result = new LArithmeticT(op, left, right); |
| 763 return MarkAsCall(DefineFixed(result, eax), instr); |
| 764 } |
| 733 } | 765 } |
| 734 | 766 |
| 735 | 767 |
| 736 LInstruction* LChunkBuilder::DoShift(Token::Value op, | 768 LInstruction* LChunkBuilder::DoShift(Token::Value op, |
| 737 HBitwiseBinaryOperation* instr) { | 769 HBitwiseBinaryOperation* instr) { |
| 770 if (instr->representation().IsTagged()) { |
| 771 ASSERT(instr->left()->representation().IsTagged()); |
| 772 ASSERT(instr->right()->representation().IsTagged()); |
| 773 |
| 774 LOperand* left = UseFixed(instr->left(), edx); |
| 775 LOperand* right = UseFixed(instr->right(), eax); |
| 776 LArithmeticT* result = new LArithmeticT(op, left, right); |
| 777 return MarkAsCall(DefineFixed(result, eax), instr); |
| 778 } |
| 779 |
| 738 ASSERT(instr->representation().IsInteger32()); | 780 ASSERT(instr->representation().IsInteger32()); |
| 739 ASSERT(instr->OperandAt(0)->representation().IsInteger32()); | 781 ASSERT(instr->OperandAt(0)->representation().IsInteger32()); |
| 740 ASSERT(instr->OperandAt(1)->representation().IsInteger32()); | 782 ASSERT(instr->OperandAt(1)->representation().IsInteger32()); |
| 741 LOperand* left = UseRegisterAtStart(instr->OperandAt(0)); | 783 LOperand* left = UseRegisterAtStart(instr->OperandAt(0)); |
| 742 | 784 |
| 743 HValue* right_value = instr->OperandAt(1); | 785 HValue* right_value = instr->OperandAt(1); |
| 744 LOperand* right = NULL; | 786 LOperand* right = NULL; |
| 745 int constant_value = 0; | 787 int constant_value = 0; |
| 746 if (right_value->IsConstant()) { | 788 if (right_value->IsConstant()) { |
| 747 HConstant* constant = HConstant::cast(right_value); | 789 HConstant* constant = HConstant::cast(right_value); |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 871 if (current->has_position()) position_ = current->position(); | 913 if (current->has_position()) position_ = current->position(); |
| 872 LInstruction* instr = current->CompileToLithium(this); | 914 LInstruction* instr = current->CompileToLithium(this); |
| 873 | 915 |
| 874 if (instr != NULL) { | 916 if (instr != NULL) { |
| 875 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { | 917 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { |
| 876 instr = AssignPointerMap(instr); | 918 instr = AssignPointerMap(instr); |
| 877 } | 919 } |
| 878 if (FLAG_stress_environments && !instr->HasEnvironment()) { | 920 if (FLAG_stress_environments && !instr->HasEnvironment()) { |
| 879 instr = AssignEnvironment(instr); | 921 instr = AssignEnvironment(instr); |
| 880 } | 922 } |
| 881 if (current->IsBranch()) { | 923 if (current->IsTest() && !instr->IsGoto()) { |
| 882 instr->set_hydrogen_value(HBranch::cast(current)->value()); | 924 ASSERT(instr->IsControl()); |
| 925 HTest* test = HTest::cast(current); |
| 926 instr->set_hydrogen_value(test->value()); |
| 927 HBasicBlock* first = test->FirstSuccessor(); |
| 928 HBasicBlock* second = test->SecondSuccessor(); |
| 929 ASSERT(first != NULL && second != NULL); |
| 930 instr->SetBranchTargets(first->block_id(), second->block_id()); |
| 883 } else { | 931 } else { |
| 884 instr->set_hydrogen_value(current); | 932 instr->set_hydrogen_value(current); |
| 885 } | 933 } |
| 886 | 934 |
| 887 int index = chunk_->AddInstruction(instr, current_block_); | 935 int index = chunk_->AddInstruction(instr, current_block_); |
| 888 allocator_->SummarizeInstruction(index); | 936 allocator_->SummarizeInstruction(index); |
| 889 } else { | 937 } else { |
| 890 // This instruction should be omitted. | 938 // This instruction should be omitted. |
| 891 allocator_->OmitInstruction(); | 939 allocator_->OmitInstruction(); |
| 892 } | 940 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 909 outer); | 957 outer); |
| 910 int argument_index = 0; | 958 int argument_index = 0; |
| 911 for (int i = 0; i < value_count; ++i) { | 959 for (int i = 0; i < value_count; ++i) { |
| 912 HValue* value = hydrogen_env->values()->at(i); | 960 HValue* value = hydrogen_env->values()->at(i); |
| 913 LOperand* op = NULL; | 961 LOperand* op = NULL; |
| 914 if (value->IsArgumentsObject()) { | 962 if (value->IsArgumentsObject()) { |
| 915 op = NULL; | 963 op = NULL; |
| 916 } else if (value->IsPushArgument()) { | 964 } else if (value->IsPushArgument()) { |
| 917 op = new LArgument(argument_index++); | 965 op = new LArgument(argument_index++); |
| 918 } else { | 966 } else { |
| 919 op = UseOrConstant(value); | 967 op = UseAny(value); |
| 920 if (op->IsUnallocated()) { | |
| 921 LUnallocated* unalloc = LUnallocated::cast(op); | |
| 922 unalloc->set_policy(LUnallocated::ANY); | |
| 923 } | |
| 924 } | 968 } |
| 925 result->AddValue(op, value->representation()); | 969 result->AddValue(op, value->representation()); |
| 926 } | 970 } |
| 927 | 971 |
| 928 return result; | 972 return result; |
| 929 } | 973 } |
| 930 | 974 |
| 931 | 975 |
| 932 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) { | 976 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) { |
| 933 LGoto* result = new LGoto(instr->FirstSuccessor()->block_id(), | 977 LGoto* result = new LGoto(instr->FirstSuccessor()->block_id(), |
| 934 instr->include_stack_check()); | 978 instr->include_stack_check()); |
| 935 return (instr->include_stack_check()) | 979 return (instr->include_stack_check()) |
| 936 ? AssignPointerMap(result) | 980 ? AssignPointerMap(result) |
| 937 : result; | 981 : result; |
| 938 } | 982 } |
| 939 | 983 |
| 940 | 984 |
| 941 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { | 985 LInstruction* LChunkBuilder::DoTest(HTest* instr) { |
| 942 HValue* v = instr->value(); | 986 HValue* v = instr->value(); |
| 943 HBasicBlock* first = instr->FirstSuccessor(); | |
| 944 HBasicBlock* second = instr->SecondSuccessor(); | |
| 945 ASSERT(first != NULL && second != NULL); | |
| 946 int first_id = first->block_id(); | |
| 947 int second_id = second->block_id(); | |
| 948 | |
| 949 if (v->EmitAtUses()) { | 987 if (v->EmitAtUses()) { |
| 950 if (v->IsClassOfTest()) { | 988 if (v->IsClassOfTest()) { |
| 951 HClassOfTest* compare = HClassOfTest::cast(v); | 989 HClassOfTest* compare = HClassOfTest::cast(v); |
| 952 ASSERT(compare->value()->representation().IsTagged()); | 990 ASSERT(compare->value()->representation().IsTagged()); |
| 953 | 991 |
| 954 return new LClassOfTestAndBranch(UseTempRegister(compare->value()), | 992 return new LClassOfTestAndBranch(UseTempRegister(compare->value()), |
| 955 TempRegister(), | 993 TempRegister(), |
| 956 TempRegister(), | 994 TempRegister()); |
| 957 first_id, | |
| 958 second_id); | |
| 959 } else if (v->IsCompare()) { | 995 } else if (v->IsCompare()) { |
| 960 HCompare* compare = HCompare::cast(v); | 996 HCompare* compare = HCompare::cast(v); |
| 961 Token::Value op = compare->token(); | 997 Token::Value op = compare->token(); |
| 962 HValue* left = compare->left(); | 998 HValue* left = compare->left(); |
| 963 HValue* right = compare->right(); | 999 HValue* right = compare->right(); |
| 964 Representation r = compare->GetInputRepresentation(); | 1000 Representation r = compare->GetInputRepresentation(); |
| 965 if (r.IsInteger32()) { | 1001 if (r.IsInteger32()) { |
| 966 ASSERT(left->representation().IsInteger32()); | 1002 ASSERT(left->representation().IsInteger32()); |
| 967 ASSERT(right->representation().IsInteger32()); | 1003 ASSERT(right->representation().IsInteger32()); |
| 968 | 1004 |
| 969 return new LCmpIDAndBranch(UseRegisterAtStart(left), | 1005 return new LCmpIDAndBranch(UseRegisterAtStart(left), |
| 970 UseOrConstantAtStart(right), | 1006 UseOrConstantAtStart(right)); |
| 971 first_id, | |
| 972 second_id); | |
| 973 } else if (r.IsDouble()) { | 1007 } else if (r.IsDouble()) { |
| 974 ASSERT(left->representation().IsDouble()); | 1008 ASSERT(left->representation().IsDouble()); |
| 975 ASSERT(right->representation().IsDouble()); | 1009 ASSERT(right->representation().IsDouble()); |
| 976 | 1010 |
| 977 return new LCmpIDAndBranch(UseRegisterAtStart(left), | 1011 return new LCmpIDAndBranch(UseRegisterAtStart(left), |
| 978 UseRegisterAtStart(right), | 1012 UseRegisterAtStart(right)); |
| 979 first_id, | |
| 980 second_id); | |
| 981 } else { | 1013 } else { |
| 982 ASSERT(left->representation().IsTagged()); | 1014 ASSERT(left->representation().IsTagged()); |
| 983 ASSERT(right->representation().IsTagged()); | 1015 ASSERT(right->representation().IsTagged()); |
| 984 bool reversed = op == Token::GT || op == Token::LTE; | 1016 bool reversed = op == Token::GT || op == Token::LTE; |
| 985 LOperand* left_operand = UseFixed(left, reversed ? eax : edx); | 1017 LOperand* left_operand = UseFixed(left, reversed ? eax : edx); |
| 986 LOperand* right_operand = UseFixed(right, reversed ? edx : eax); | 1018 LOperand* right_operand = UseFixed(right, reversed ? edx : eax); |
| 987 LCmpTAndBranch* result = new LCmpTAndBranch(left_operand, | 1019 LCmpTAndBranch* result = new LCmpTAndBranch(left_operand, |
| 988 right_operand, | 1020 right_operand); |
| 989 first_id, | |
| 990 second_id); | |
| 991 return MarkAsCall(result, instr); | 1021 return MarkAsCall(result, instr); |
| 992 } | 1022 } |
| 993 } else if (v->IsIsSmi()) { | 1023 } else if (v->IsIsSmi()) { |
| 994 HIsSmi* compare = HIsSmi::cast(v); | 1024 HIsSmi* compare = HIsSmi::cast(v); |
| 995 ASSERT(compare->value()->representation().IsTagged()); | 1025 ASSERT(compare->value()->representation().IsTagged()); |
| 996 | 1026 |
| 997 return new LIsSmiAndBranch(Use(compare->value()), | 1027 return new LIsSmiAndBranch(Use(compare->value())); |
| 998 first_id, | |
| 999 second_id); | |
| 1000 } else if (v->IsHasInstanceType()) { | 1028 } else if (v->IsHasInstanceType()) { |
| 1001 HHasInstanceType* compare = HHasInstanceType::cast(v); | 1029 HHasInstanceType* compare = HHasInstanceType::cast(v); |
| 1002 ASSERT(compare->value()->representation().IsTagged()); | 1030 ASSERT(compare->value()->representation().IsTagged()); |
| 1003 | 1031 |
| 1004 return new LHasInstanceTypeAndBranch(UseRegisterAtStart(compare->value()), | 1032 return new LHasInstanceTypeAndBranch(UseRegisterAtStart(compare->value()), |
| 1005 TempRegister(), | 1033 TempRegister()); |
| 1006 first_id, | |
| 1007 second_id); | |
| 1008 } else if (v->IsHasCachedArrayIndex()) { | 1034 } else if (v->IsHasCachedArrayIndex()) { |
| 1009 HHasCachedArrayIndex* compare = HHasCachedArrayIndex::cast(v); | 1035 HHasCachedArrayIndex* compare = HHasCachedArrayIndex::cast(v); |
| 1010 ASSERT(compare->value()->representation().IsTagged()); | 1036 ASSERT(compare->value()->representation().IsTagged()); |
| 1011 | 1037 |
| 1012 return new LHasCachedArrayIndexAndBranch( | 1038 return new LHasCachedArrayIndexAndBranch( |
| 1013 UseRegisterAtStart(compare->value()), first_id, second_id); | 1039 UseRegisterAtStart(compare->value())); |
| 1014 } else if (v->IsIsNull()) { | 1040 } else if (v->IsIsNull()) { |
| 1015 HIsNull* compare = HIsNull::cast(v); | 1041 HIsNull* compare = HIsNull::cast(v); |
| 1016 ASSERT(compare->value()->representation().IsTagged()); | 1042 ASSERT(compare->value()->representation().IsTagged()); |
| 1017 | 1043 |
| 1018 // We only need a temp register for non-strict compare. | 1044 // We only need a temp register for non-strict compare. |
| 1019 LOperand* temp = compare->is_strict() ? NULL : TempRegister(); | 1045 LOperand* temp = compare->is_strict() ? NULL : TempRegister(); |
| 1020 return new LIsNullAndBranch(UseRegisterAtStart(compare->value()), | 1046 return new LIsNullAndBranch(UseRegisterAtStart(compare->value()), |
| 1021 temp, | 1047 temp); |
| 1022 first_id, | |
| 1023 second_id); | |
| 1024 } else if (v->IsIsObject()) { | 1048 } else if (v->IsIsObject()) { |
| 1025 HIsObject* compare = HIsObject::cast(v); | 1049 HIsObject* compare = HIsObject::cast(v); |
| 1026 ASSERT(compare->value()->representation().IsTagged()); | 1050 ASSERT(compare->value()->representation().IsTagged()); |
| 1027 | 1051 |
| 1028 LOperand* temp1 = TempRegister(); | 1052 LOperand* temp1 = TempRegister(); |
| 1029 LOperand* temp2 = TempRegister(); | 1053 LOperand* temp2 = TempRegister(); |
| 1030 return new LIsObjectAndBranch(UseRegisterAtStart(compare->value()), | 1054 return new LIsObjectAndBranch(UseRegisterAtStart(compare->value()), |
| 1031 temp1, | 1055 temp1, |
| 1032 temp2, | 1056 temp2); |
| 1033 first_id, | |
| 1034 second_id); | |
| 1035 } else if (v->IsCompareJSObjectEq()) { | 1057 } else if (v->IsCompareJSObjectEq()) { |
| 1036 HCompareJSObjectEq* compare = HCompareJSObjectEq::cast(v); | 1058 HCompareJSObjectEq* compare = HCompareJSObjectEq::cast(v); |
| 1037 return new LCmpJSObjectEqAndBranch(UseRegisterAtStart(compare->left()), | 1059 return new LCmpJSObjectEqAndBranch(UseRegisterAtStart(compare->left()), |
| 1038 UseRegisterAtStart(compare->right()), | 1060 UseRegisterAtStart(compare->right())); |
| 1039 first_id, | |
| 1040 second_id); | |
| 1041 } else if (v->IsInstanceOf()) { | 1061 } else if (v->IsInstanceOf()) { |
| 1042 HInstanceOf* instance_of = HInstanceOf::cast(v); | 1062 HInstanceOf* instance_of = HInstanceOf::cast(v); |
| 1043 LInstanceOfAndBranch* result = | 1063 LInstanceOfAndBranch* result = |
| 1044 new LInstanceOfAndBranch( | 1064 new LInstanceOfAndBranch( |
| 1045 UseFixed(instance_of->left(), InstanceofStub::left()), | 1065 UseFixed(instance_of->left(), InstanceofStub::left()), |
| 1046 UseFixed(instance_of->right(), InstanceofStub::right()), | 1066 UseFixed(instance_of->right(), InstanceofStub::right())); |
| 1047 first_id, | |
| 1048 second_id); | |
| 1049 return MarkAsCall(result, instr); | 1067 return MarkAsCall(result, instr); |
| 1050 } else if (v->IsTypeofIs()) { | 1068 } else if (v->IsTypeofIs()) { |
| 1051 HTypeofIs* typeof_is = HTypeofIs::cast(v); | 1069 HTypeofIs* typeof_is = HTypeofIs::cast(v); |
| 1052 return new LTypeofIsAndBranch(UseTempRegister(typeof_is->value()), | 1070 return new LTypeofIsAndBranch(UseTempRegister(typeof_is->value())); |
| 1053 first_id, | |
| 1054 second_id); | |
| 1055 } else { | 1071 } else { |
| 1056 if (v->IsConstant()) { | 1072 if (v->IsConstant()) { |
| 1057 if (HConstant::cast(v)->handle()->IsTrue()) { | 1073 if (HConstant::cast(v)->handle()->IsTrue()) { |
| 1058 return new LGoto(first_id); | 1074 return new LGoto(instr->FirstSuccessor()->block_id()); |
| 1059 } else if (HConstant::cast(v)->handle()->IsFalse()) { | 1075 } else if (HConstant::cast(v)->handle()->IsFalse()) { |
| 1060 return new LGoto(second_id); | 1076 return new LGoto(instr->SecondSuccessor()->block_id()); |
| 1061 } | 1077 } |
| 1062 } | 1078 } |
| 1063 Abort("Undefined compare before branch"); | 1079 Abort("Undefined compare before branch"); |
| 1064 return NULL; | 1080 return NULL; |
| 1065 } | 1081 } |
| 1066 } | 1082 } |
| 1067 return new LBranch(UseRegisterAtStart(v), first_id, second_id); | 1083 return new LBranch(UseRegisterAtStart(v)); |
| 1068 } | 1084 } |
| 1069 | 1085 |
| 1070 | 1086 |
| 1071 LInstruction* LChunkBuilder::DoCompareMapAndBranch( | 1087 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) { |
| 1072 HCompareMapAndBranch* instr) { | |
| 1073 ASSERT(instr->value()->representation().IsTagged()); | 1088 ASSERT(instr->value()->representation().IsTagged()); |
| 1074 LOperand* value = UseRegisterAtStart(instr->value()); | 1089 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1075 return new LCmpMapAndBranch(value); | 1090 return new LCmpMapAndBranch(value); |
| 1076 } | 1091 } |
| 1077 | 1092 |
| 1078 | 1093 |
| 1079 LInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* length) { | 1094 LInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* length) { |
| 1080 return DefineAsRegister(new LArgumentsLength(Use(length->value()))); | 1095 return DefineAsRegister(new LArgumentsLength(Use(length->value()))); |
| 1081 } | 1096 } |
| 1082 | 1097 |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1166 UNREACHABLE(); | 1181 UNREACHABLE(); |
| 1167 return NULL; | 1182 return NULL; |
| 1168 } | 1183 } |
| 1169 } | 1184 } |
| 1170 } | 1185 } |
| 1171 | 1186 |
| 1172 | 1187 |
| 1173 LInstruction* LChunkBuilder::DoCallKeyed(HCallKeyed* instr) { | 1188 LInstruction* LChunkBuilder::DoCallKeyed(HCallKeyed* instr) { |
| 1174 ASSERT(instr->key()->representation().IsTagged()); | 1189 ASSERT(instr->key()->representation().IsTagged()); |
| 1175 argument_count_ -= instr->argument_count(); | 1190 argument_count_ -= instr->argument_count(); |
| 1176 UseFixed(instr->key(), ecx); | 1191 LOperand* key = UseFixed(instr->key(), ecx); |
| 1177 return MarkAsCall(DefineFixed(new LCallKeyed, eax), instr); | 1192 return MarkAsCall(DefineFixed(new LCallKeyed(key), eax), instr); |
| 1178 } | 1193 } |
| 1179 | 1194 |
| 1180 | 1195 |
| 1181 LInstruction* LChunkBuilder::DoCallNamed(HCallNamed* instr) { | 1196 LInstruction* LChunkBuilder::DoCallNamed(HCallNamed* instr) { |
| 1182 argument_count_ -= instr->argument_count(); | 1197 argument_count_ -= instr->argument_count(); |
| 1183 return MarkAsCall(DefineFixed(new LCallNamed, eax), instr); | 1198 return MarkAsCall(DefineFixed(new LCallNamed, eax), instr); |
| 1184 } | 1199 } |
| 1185 | 1200 |
| 1186 | 1201 |
| 1187 LInstruction* LChunkBuilder::DoCallGlobal(HCallGlobal* instr) { | 1202 LInstruction* LChunkBuilder::DoCallGlobal(HCallGlobal* instr) { |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1254 return DoBit(Token::BIT_XOR, instr); | 1269 return DoBit(Token::BIT_XOR, instr); |
| 1255 } | 1270 } |
| 1256 | 1271 |
| 1257 | 1272 |
| 1258 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { | 1273 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { |
| 1259 if (instr->representation().IsDouble()) { | 1274 if (instr->representation().IsDouble()) { |
| 1260 return DoArithmeticD(Token::DIV, instr); | 1275 return DoArithmeticD(Token::DIV, instr); |
| 1261 } else if (instr->representation().IsInteger32()) { | 1276 } else if (instr->representation().IsInteger32()) { |
| 1262 // The temporary operand is necessary to ensure that right is not allocated | 1277 // The temporary operand is necessary to ensure that right is not allocated |
| 1263 // into edx. | 1278 // into edx. |
| 1264 FixedTemp(edx); | 1279 LOperand* temp = FixedTemp(edx); |
| 1265 LOperand* value = UseFixed(instr->left(), eax); | 1280 LOperand* value = UseFixed(instr->left(), eax); |
| 1266 LOperand* divisor = UseRegister(instr->right()); | 1281 LOperand* divisor = UseRegister(instr->right()); |
| 1267 return AssignEnvironment(DefineFixed(new LDivI(value, divisor), eax)); | 1282 LDivI* result = new LDivI(value, divisor, temp); |
| 1283 return AssignEnvironment(DefineFixed(result, eax)); |
| 1268 } else { | 1284 } else { |
| 1269 ASSERT(instr->representation().IsTagged()); | 1285 ASSERT(instr->representation().IsTagged()); |
| 1270 return DoArithmeticT(Token::DIV, instr); | 1286 return DoArithmeticT(Token::DIV, instr); |
| 1271 } | 1287 } |
| 1272 } | 1288 } |
| 1273 | 1289 |
| 1274 | 1290 |
| 1275 LInstruction* LChunkBuilder::DoMod(HMod* instr) { | 1291 LInstruction* LChunkBuilder::DoMod(HMod* instr) { |
| 1276 if (instr->representation().IsInteger32()) { | 1292 if (instr->representation().IsInteger32()) { |
| 1277 ASSERT(instr->left()->representation().IsInteger32()); | 1293 ASSERT(instr->left()->representation().IsInteger32()); |
| 1278 ASSERT(instr->right()->representation().IsInteger32()); | 1294 ASSERT(instr->right()->representation().IsInteger32()); |
| 1279 // The temporary operand is necessary to ensure that right is not allocated | 1295 // The temporary operand is necessary to ensure that right is not allocated |
| 1280 // into edx. | 1296 // into edx. |
| 1281 FixedTemp(edx); | 1297 LOperand* temp = FixedTemp(edx); |
| 1282 LOperand* value = UseFixed(instr->left(), eax); | 1298 LOperand* value = UseFixed(instr->left(), eax); |
| 1283 LOperand* divisor = UseRegister(instr->right()); | 1299 LOperand* divisor = UseRegister(instr->right()); |
| 1284 LModI* mod = new LModI(value, divisor); | 1300 LModI* mod = new LModI(value, divisor, temp); |
| 1285 LInstruction* result = DefineFixed(mod, edx); | 1301 LInstruction* result = DefineFixed(mod, edx); |
| 1286 return (instr->CheckFlag(HValue::kBailoutOnMinusZero) || | 1302 return (instr->CheckFlag(HValue::kBailoutOnMinusZero) || |
| 1287 instr->CheckFlag(HValue::kCanBeDivByZero)) | 1303 instr->CheckFlag(HValue::kCanBeDivByZero)) |
| 1288 ? AssignEnvironment(result) | 1304 ? AssignEnvironment(result) |
| 1289 : result; | 1305 : result; |
| 1290 } else if (instr->representation().IsTagged()) { | 1306 } else if (instr->representation().IsTagged()) { |
| 1291 return DoArithmeticT(Token::MOD, instr); | 1307 return DoArithmeticT(Token::MOD, instr); |
| 1292 } else { | 1308 } else { |
| 1293 ASSERT(instr->representation().IsDouble()); | 1309 ASSERT(instr->representation().IsDouble()); |
| 1294 // We call a C function for double modulo. It can't trigger a GC. | 1310 // We call a C function for double modulo. It can't trigger a GC. |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1320 ASSERT(instr->representation().IsTagged()); | 1336 ASSERT(instr->representation().IsTagged()); |
| 1321 return DoArithmeticT(Token::MUL, instr); | 1337 return DoArithmeticT(Token::MUL, instr); |
| 1322 } | 1338 } |
| 1323 } | 1339 } |
| 1324 | 1340 |
| 1325 | 1341 |
| 1326 LInstruction* LChunkBuilder::DoSub(HSub* instr) { | 1342 LInstruction* LChunkBuilder::DoSub(HSub* instr) { |
| 1327 if (instr->representation().IsInteger32()) { | 1343 if (instr->representation().IsInteger32()) { |
| 1328 ASSERT(instr->left()->representation().IsInteger32()); | 1344 ASSERT(instr->left()->representation().IsInteger32()); |
| 1329 ASSERT(instr->right()->representation().IsInteger32()); | 1345 ASSERT(instr->right()->representation().IsInteger32()); |
| 1330 LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand()); | 1346 LOperand* left = UseRegisterAtStart(instr->left()); |
| 1331 LOperand* right = UseOrConstantAtStart(instr->MostConstantOperand()); | 1347 LOperand* right = UseOrConstantAtStart(instr->right()); |
| 1332 LSubI* sub = new LSubI(left, right); | 1348 LSubI* sub = new LSubI(left, right); |
| 1333 LInstruction* result = DefineSameAsFirst(sub); | 1349 LInstruction* result = DefineSameAsFirst(sub); |
| 1334 if (instr->CheckFlag(HValue::kCanOverflow)) { | 1350 if (instr->CheckFlag(HValue::kCanOverflow)) { |
| 1335 result = AssignEnvironment(result); | 1351 result = AssignEnvironment(result); |
| 1336 } | 1352 } |
| 1337 return result; | 1353 return result; |
| 1338 } else if (instr->representation().IsDouble()) { | 1354 } else if (instr->representation().IsDouble()) { |
| 1339 return DoArithmeticD(Token::SUB, instr); | 1355 return DoArithmeticD(Token::SUB, instr); |
| 1340 } else { | 1356 } else { |
| 1341 ASSERT(instr->representation().IsTagged()); | 1357 ASSERT(instr->representation().IsTagged()); |
| (...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1608 Representation r = instr->representation(); | 1624 Representation r = instr->representation(); |
| 1609 if (r.IsInteger32()) { | 1625 if (r.IsInteger32()) { |
| 1610 int32_t value = instr->Integer32Value(); | 1626 int32_t value = instr->Integer32Value(); |
| 1611 return DefineAsRegister(new LConstantI(value)); | 1627 return DefineAsRegister(new LConstantI(value)); |
| 1612 } else if (r.IsDouble()) { | 1628 } else if (r.IsDouble()) { |
| 1613 double value = instr->DoubleValue(); | 1629 double value = instr->DoubleValue(); |
| 1614 return DefineAsRegister(new LConstantD(value)); | 1630 return DefineAsRegister(new LConstantD(value)); |
| 1615 } else if (r.IsTagged()) { | 1631 } else if (r.IsTagged()) { |
| 1616 return DefineAsRegister(new LConstantT(instr->handle())); | 1632 return DefineAsRegister(new LConstantT(instr->handle())); |
| 1617 } else { | 1633 } else { |
| 1618 Abort("unsupported constant of type double"); | 1634 UNREACHABLE(); |
| 1619 return NULL; | 1635 return NULL; |
| 1620 } | 1636 } |
| 1621 } | 1637 } |
| 1622 | 1638 |
| 1623 | 1639 |
| 1624 LInstruction* LChunkBuilder::DoLoadGlobal(HLoadGlobal* instr) { | 1640 LInstruction* LChunkBuilder::DoLoadGlobal(HLoadGlobal* instr) { |
| 1625 LLoadGlobal* result = new LLoadGlobal; | 1641 LLoadGlobal* result = new LLoadGlobal; |
| 1626 return instr->check_hole_value() | 1642 return instr->check_hole_value() |
| 1627 ? AssignEnvironment(DefineAsRegister(result)) | 1643 ? AssignEnvironment(DefineAsRegister(result)) |
| 1628 : DefineAsRegister(result); | 1644 : DefineAsRegister(result); |
| 1629 } | 1645 } |
| 1630 | 1646 |
| 1631 | 1647 |
| 1632 LInstruction* LChunkBuilder::DoStoreGlobal(HStoreGlobal* instr) { | 1648 LInstruction* LChunkBuilder::DoStoreGlobal(HStoreGlobal* instr) { |
| 1633 return new LStoreGlobal(UseRegisterAtStart(instr->value())); | 1649 return new LStoreGlobal(UseRegisterAtStart(instr->value())); |
| 1634 } | 1650 } |
| 1635 | 1651 |
| 1636 | 1652 |
| 1653 LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) { |
| 1654 return DefineAsRegister(new LLoadContextSlot); |
| 1655 } |
| 1656 |
| 1657 |
| 1637 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) { | 1658 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) { |
| 1638 ASSERT(instr->representation().IsTagged()); | 1659 ASSERT(instr->representation().IsTagged()); |
| 1639 LOperand* obj = UseRegisterAtStart(instr->object()); | 1660 LOperand* obj = UseRegisterAtStart(instr->object()); |
| 1640 return DefineAsRegister(new LLoadNamedField(obj)); | 1661 return DefineAsRegister(new LLoadNamedField(obj)); |
| 1641 } | 1662 } |
| 1642 | 1663 |
| 1643 | 1664 |
| 1644 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) { | 1665 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) { |
| 1645 LOperand* object = UseFixed(instr->object(), eax); | 1666 LOperand* object = UseFixed(instr->object(), eax); |
| 1646 LLoadNamedGeneric* result = new LLoadNamedGeneric(object); | 1667 LLoadNamedGeneric* result = new LLoadNamedGeneric(object); |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1736 | 1757 |
| 1737 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) { | 1758 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) { |
| 1738 LOperand* obj = UseFixed(instr->object(), edx); | 1759 LOperand* obj = UseFixed(instr->object(), edx); |
| 1739 LOperand* val = UseFixed(instr->value(), eax); | 1760 LOperand* val = UseFixed(instr->value(), eax); |
| 1740 | 1761 |
| 1741 LStoreNamedGeneric* result = new LStoreNamedGeneric(obj, val); | 1762 LStoreNamedGeneric* result = new LStoreNamedGeneric(obj, val); |
| 1742 return MarkAsCall(result, instr); | 1763 return MarkAsCall(result, instr); |
| 1743 } | 1764 } |
| 1744 | 1765 |
| 1745 | 1766 |
| 1767 LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) { |
| 1768 LOperand* string = UseRegister(instr->string()); |
| 1769 LOperand* index = UseRegisterOrConstant(instr->index()); |
| 1770 LStringCharCodeAt* result = new LStringCharCodeAt(string, index); |
| 1771 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); |
| 1772 } |
| 1773 |
| 1774 |
| 1775 LInstruction* LChunkBuilder::DoStringLength(HStringLength* instr) { |
| 1776 LOperand* string = UseRegisterAtStart(instr->value()); |
| 1777 return DefineAsRegister(new LStringLength(string)); |
| 1778 } |
| 1779 |
| 1780 |
| 1746 LInstruction* LChunkBuilder::DoArrayLiteral(HArrayLiteral* instr) { | 1781 LInstruction* LChunkBuilder::DoArrayLiteral(HArrayLiteral* instr) { |
| 1747 return MarkAsCall(DefineFixed(new LArrayLiteral, eax), instr); | 1782 return MarkAsCall(DefineFixed(new LArrayLiteral, eax), instr); |
| 1748 } | 1783 } |
| 1749 | 1784 |
| 1750 | 1785 |
| 1751 LInstruction* LChunkBuilder::DoObjectLiteral(HObjectLiteral* instr) { | 1786 LInstruction* LChunkBuilder::DoObjectLiteral(HObjectLiteral* instr) { |
| 1752 return MarkAsCall(DefineFixed(new LObjectLiteral, eax), instr); | 1787 return MarkAsCall(DefineFixed(new LObjectLiteral, eax), instr); |
| 1753 } | 1788 } |
| 1754 | 1789 |
| 1755 | 1790 |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1874 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { | 1909 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { |
| 1875 HEnvironment* outer = current_block_->last_environment()->outer(); | 1910 HEnvironment* outer = current_block_->last_environment()->outer(); |
| 1876 current_block_->UpdateEnvironment(outer); | 1911 current_block_->UpdateEnvironment(outer); |
| 1877 return NULL; | 1912 return NULL; |
| 1878 } | 1913 } |
| 1879 | 1914 |
| 1880 | 1915 |
| 1881 } } // namespace v8::internal | 1916 } } // namespace v8::internal |
| 1882 | 1917 |
| 1883 #endif // V8_TARGET_ARCH_IA32 | 1918 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |