| 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 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 57 | 57 |
| 58 | 58 |
| 59 void LOsrEntry::MarkSpilledDoubleRegister(int allocation_index, | 59 void LOsrEntry::MarkSpilledDoubleRegister(int allocation_index, |
| 60 LOperand* spill_operand) { | 60 LOperand* spill_operand) { |
| 61 ASSERT(spill_operand->IsDoubleStackSlot()); | 61 ASSERT(spill_operand->IsDoubleStackSlot()); |
| 62 ASSERT(double_register_spills_[allocation_index] == NULL); | 62 ASSERT(double_register_spills_[allocation_index] == NULL); |
| 63 double_register_spills_[allocation_index] = spill_operand; | 63 double_register_spills_[allocation_index] = spill_operand; |
| 64 } | 64 } |
| 65 | 65 |
| 66 | 66 |
| 67 void LInstruction::PrintTo(StringStream* stream) const { | 67 void LInstruction::PrintTo(StringStream* stream) { |
| 68 stream->Add("%s ", this->Mnemonic()); | 68 stream->Add("%s ", this->Mnemonic()); |
| 69 if (HasResult()) { | 69 if (HasResult()) { |
| 70 result()->PrintTo(stream); | 70 LTemplateInstruction<1>::cast(this)->result()->PrintTo(stream); |
| 71 stream->Add(" "); | 71 stream->Add(" "); |
| 72 } | 72 } |
| 73 PrintDataTo(stream); | 73 PrintDataTo(stream); |
| 74 | 74 |
| 75 if (HasEnvironment()) { | 75 if (HasEnvironment()) { |
| 76 stream->Add(" "); | 76 stream->Add(" "); |
| 77 environment()->PrintTo(stream); | 77 environment()->PrintTo(stream); |
| 78 } | 78 } |
| 79 | 79 |
| 80 if (HasPointerMap()) { | 80 if (HasPointerMap()) { |
| 81 stream->Add(" "); | 81 stream->Add(" "); |
| 82 pointer_map()->PrintTo(stream); | 82 pointer_map()->PrintTo(stream); |
| 83 } | 83 } |
| 84 } | 84 } |
| 85 | 85 |
| 86 | 86 |
| 87 void LLabel::PrintDataTo(StringStream* stream) const { | 87 void LLabel::PrintDataTo(StringStream* stream) { |
| 88 LGap::PrintDataTo(stream); | 88 LGap::PrintDataTo(stream); |
| 89 LLabel* rep = replacement(); | 89 LLabel* rep = replacement(); |
| 90 if (rep != NULL) { | 90 if (rep != NULL) { |
| 91 stream->Add(" Dead block replaced with B%d", rep->block_id()); | 91 stream->Add(" Dead block replaced with B%d", rep->block_id()); |
| 92 } | 92 } |
| 93 } | 93 } |
| 94 | 94 |
| 95 | 95 |
| 96 bool LParallelMove::IsRedundant() const { | 96 bool LParallelMove::IsRedundant() const { |
| 97 for (int i = 0; i < move_operands_.length(); ++i) { | 97 for (int i = 0; i < move_operands_.length(); ++i) { |
| 98 if (!move_operands_[i].IsRedundant()) return false; | 98 if (!move_operands_[i].IsRedundant()) return false; |
| 99 } | 99 } |
| 100 return true; | 100 return true; |
| 101 } | 101 } |
| 102 | 102 |
| 103 | 103 |
| 104 void LParallelMove::PrintDataTo(StringStream* stream) const { | 104 void LParallelMove::PrintDataTo(StringStream* stream) { |
| 105 for (int i = move_operands_.length() - 1; i >= 0; --i) { | 105 for (int i = move_operands_.length() - 1; i >= 0; --i) { |
| 106 if (!move_operands_[i].IsEliminated()) { | 106 if (!move_operands_[i].IsEliminated()) { |
| 107 LOperand* from = move_operands_[i].from(); | 107 LOperand* from = move_operands_[i].from(); |
| 108 LOperand* to = move_operands_[i].to(); | 108 LOperand* to = move_operands_[i].to(); |
| 109 if (from->Equals(to)) { | 109 if (from->Equals(to)) { |
| 110 to->PrintTo(stream); | 110 to->PrintTo(stream); |
| 111 } else { | 111 } else { |
| 112 to->PrintTo(stream); | 112 to->PrintTo(stream); |
| 113 stream->Add(" = "); | 113 stream->Add(" = "); |
| 114 from->PrintTo(stream); | 114 from->PrintTo(stream); |
| 115 } | 115 } |
| 116 stream->Add("; "); | 116 stream->Add("; "); |
| 117 } | 117 } |
| 118 } | 118 } |
| 119 } | 119 } |
| 120 | 120 |
| 121 | 121 |
| 122 bool LGap::IsRedundant() const { | 122 bool LGap::IsRedundant() const { |
| 123 for (int i = 0; i < 4; i++) { | 123 for (int i = 0; i < 4; i++) { |
| 124 if (parallel_moves_[i] != NULL && !parallel_moves_[i]->IsRedundant()) { | 124 if (parallel_moves_[i] != NULL && !parallel_moves_[i]->IsRedundant()) { |
| 125 return false; | 125 return false; |
| 126 } | 126 } |
| 127 } | 127 } |
| 128 | 128 |
| 129 return true; | 129 return true; |
| 130 } | 130 } |
| 131 | 131 |
| 132 | 132 |
| 133 void LGap::PrintDataTo(StringStream* stream) const { | 133 void LGap::PrintDataTo(StringStream* stream) { |
| 134 for (int i = 0; i < 4; i++) { | 134 for (int i = 0; i < 4; i++) { |
| 135 stream->Add("("); | 135 stream->Add("("); |
| 136 if (parallel_moves_[i] != NULL) { | 136 if (parallel_moves_[i] != NULL) { |
| 137 parallel_moves_[i]->PrintDataTo(stream); | 137 parallel_moves_[i]->PrintDataTo(stream); |
| 138 } | 138 } |
| 139 stream->Add(") "); | 139 stream->Add(") "); |
| 140 } | 140 } |
| 141 } | 141 } |
| 142 | 142 |
| 143 | 143 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 163 case Token::MOD: return "mod-t"; | 163 case Token::MOD: return "mod-t"; |
| 164 case Token::DIV: return "div-t"; | 164 case Token::DIV: return "div-t"; |
| 165 default: | 165 default: |
| 166 UNREACHABLE(); | 166 UNREACHABLE(); |
| 167 return NULL; | 167 return NULL; |
| 168 } | 168 } |
| 169 } | 169 } |
| 170 | 170 |
| 171 | 171 |
| 172 | 172 |
| 173 void LBinaryOperation::PrintDataTo(StringStream* stream) const { | 173 void LBinaryOperation::PrintDataTo(StringStream* stream) { |
| 174 stream->Add("= "); | 174 stream->Add("= "); |
| 175 left()->PrintTo(stream); | 175 left()->PrintTo(stream); |
| 176 stream->Add(" "); | 176 stream->Add(" "); |
| 177 right()->PrintTo(stream); | 177 right()->PrintTo(stream); |
| 178 } | 178 } |
| 179 | 179 |
| 180 | 180 |
| 181 void LGoto::PrintDataTo(StringStream* stream) const { | 181 void LGoto::PrintDataTo(StringStream* stream) { |
| 182 stream->Add("B%d", block_id()); | 182 stream->Add("B%d", block_id()); |
| 183 } | 183 } |
| 184 | 184 |
| 185 | 185 |
| 186 void LBranch::PrintDataTo(StringStream* stream) const { | 186 void LBranch::PrintDataTo(StringStream* stream) { |
| 187 stream->Add("B%d | B%d on ", true_block_id(), false_block_id()); | 187 stream->Add("B%d | B%d on ", true_block_id(), false_block_id()); |
| 188 input()->PrintTo(stream); | 188 input()->PrintTo(stream); |
| 189 } | 189 } |
| 190 | 190 |
| 191 | 191 |
| 192 void LCmpIDAndBranch::PrintDataTo(StringStream* stream) const { | 192 void LCmpIDAndBranch::PrintDataTo(StringStream* stream) { |
| 193 stream->Add("if "); | 193 stream->Add("if "); |
| 194 left()->PrintTo(stream); | 194 left()->PrintTo(stream); |
| 195 stream->Add(" %s ", Token::String(op())); | 195 stream->Add(" %s ", Token::String(op())); |
| 196 right()->PrintTo(stream); | 196 right()->PrintTo(stream); |
| 197 stream->Add(" then B%d else B%d", true_block_id(), false_block_id()); | 197 stream->Add(" then B%d else B%d", true_block_id(), false_block_id()); |
| 198 } | 198 } |
| 199 | 199 |
| 200 | 200 |
| 201 void LIsNullAndBranch::PrintDataTo(StringStream* stream) const { | 201 void LIsNullAndBranch::PrintDataTo(StringStream* stream) { |
| 202 stream->Add("if "); | 202 stream->Add("if "); |
| 203 input()->PrintTo(stream); | 203 input()->PrintTo(stream); |
| 204 stream->Add(is_strict() ? " === null" : " == null"); | 204 stream->Add(is_strict() ? " === null" : " == null"); |
| 205 stream->Add(" then B%d else B%d", true_block_id(), false_block_id()); | 205 stream->Add(" then B%d else B%d", true_block_id(), false_block_id()); |
| 206 } | 206 } |
| 207 | 207 |
| 208 | 208 |
| 209 void LIsObjectAndBranch::PrintDataTo(StringStream* stream) const { | 209 void LIsObjectAndBranch::PrintDataTo(StringStream* stream) { |
| 210 stream->Add("if is_object("); | 210 stream->Add("if is_object("); |
| 211 input()->PrintTo(stream); | 211 input()->PrintTo(stream); |
| 212 stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); | 212 stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); |
| 213 } | 213 } |
| 214 | 214 |
| 215 | 215 |
| 216 void LIsSmiAndBranch::PrintDataTo(StringStream* stream) const { | 216 void LIsSmiAndBranch::PrintDataTo(StringStream* stream) { |
| 217 stream->Add("if is_smi("); | 217 stream->Add("if is_smi("); |
| 218 input()->PrintTo(stream); | 218 input()->PrintTo(stream); |
| 219 stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); | 219 stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); |
| 220 } | 220 } |
| 221 | 221 |
| 222 | 222 |
| 223 void LHasInstanceTypeAndBranch::PrintDataTo(StringStream* stream) const { | 223 void LHasInstanceTypeAndBranch::PrintDataTo(StringStream* stream) { |
| 224 stream->Add("if has_instance_type("); | 224 stream->Add("if has_instance_type("); |
| 225 input()->PrintTo(stream); | 225 input()->PrintTo(stream); |
| 226 stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); | 226 stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); |
| 227 } | 227 } |
| 228 | 228 |
| 229 | 229 |
| 230 void LHasCachedArrayIndexAndBranch::PrintDataTo(StringStream* stream) const { | 230 void LHasCachedArrayIndexAndBranch::PrintDataTo(StringStream* stream) { |
| 231 stream->Add("if has_cached_array_index("); | 231 stream->Add("if has_cached_array_index("); |
| 232 input()->PrintTo(stream); | 232 input()->PrintTo(stream); |
| 233 stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); | 233 stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); |
| 234 } | 234 } |
| 235 | 235 |
| 236 | 236 |
| 237 void LClassOfTestAndBranch::PrintDataTo(StringStream* stream) const { | 237 void LClassOfTestAndBranch::PrintDataTo(StringStream* stream) { |
| 238 stream->Add("if class_of_test("); | 238 stream->Add("if class_of_test("); |
| 239 input()->PrintTo(stream); | 239 input()->PrintTo(stream); |
| 240 stream->Add(", \"%o\") then B%d else B%d", | 240 stream->Add(", \"%o\") then B%d else B%d", |
| 241 *hydrogen()->class_name(), | 241 *hydrogen()->class_name(), |
| 242 true_block_id(), | 242 true_block_id(), |
| 243 false_block_id()); | 243 false_block_id()); |
| 244 } | 244 } |
| 245 | 245 |
| 246 | 246 |
| 247 void LTypeofIs::PrintDataTo(StringStream* stream) const { | 247 void LTypeofIs::PrintDataTo(StringStream* stream) { |
| 248 input()->PrintTo(stream); | 248 input()->PrintTo(stream); |
| 249 stream->Add(" == \"%s\"", *hydrogen()->type_literal()->ToCString()); | 249 stream->Add(" == \"%s\"", *hydrogen()->type_literal()->ToCString()); |
| 250 } | 250 } |
| 251 | 251 |
| 252 | 252 |
| 253 void LTypeofIsAndBranch::PrintDataTo(StringStream* stream) const { | 253 void LTypeofIsAndBranch::PrintDataTo(StringStream* stream) { |
| 254 stream->Add("if typeof "); | 254 stream->Add("if typeof "); |
| 255 input()->PrintTo(stream); | 255 input()->PrintTo(stream); |
| 256 stream->Add(" == \"%s\" then B%d else B%d", | 256 stream->Add(" == \"%s\" then B%d else B%d", |
| 257 *hydrogen()->type_literal()->ToCString(), | 257 *hydrogen()->type_literal()->ToCString(), |
| 258 true_block_id(), false_block_id()); | 258 true_block_id(), false_block_id()); |
| 259 } | 259 } |
| 260 | 260 |
| 261 | 261 |
| 262 void LCallConstantFunction::PrintDataTo(StringStream* stream) const { | 262 void LCallConstantFunction::PrintDataTo(StringStream* stream) { |
| 263 stream->Add("#%d / ", arity()); | 263 stream->Add("#%d / ", arity()); |
| 264 } | 264 } |
| 265 | 265 |
| 266 | 266 |
| 267 void LUnaryMathOperation::PrintDataTo(StringStream* stream) const { | 267 void LUnaryMathOperation::PrintDataTo(StringStream* stream) { |
| 268 stream->Add("/%s ", hydrogen()->OpName()); | 268 stream->Add("/%s ", hydrogen()->OpName()); |
| 269 input()->PrintTo(stream); | 269 input()->PrintTo(stream); |
| 270 } | 270 } |
| 271 | 271 |
| 272 | 272 |
| 273 void LCallKeyed::PrintDataTo(StringStream* stream) const { | 273 void LCallKeyed::PrintDataTo(StringStream* stream) { |
| 274 stream->Add("[ecx] #%d / ", arity()); | 274 stream->Add("[ecx] #%d / ", arity()); |
| 275 } | 275 } |
| 276 | 276 |
| 277 | 277 |
| 278 void LCallNamed::PrintDataTo(StringStream* stream) const { | 278 void LCallNamed::PrintDataTo(StringStream* stream) { |
| 279 SmartPointer<char> name_string = name()->ToCString(); | 279 SmartPointer<char> name_string = name()->ToCString(); |
| 280 stream->Add("%s #%d / ", *name_string, arity()); | 280 stream->Add("%s #%d / ", *name_string, arity()); |
| 281 } | 281 } |
| 282 | 282 |
| 283 | 283 |
| 284 void LCallGlobal::PrintDataTo(StringStream* stream) const { | 284 void LCallGlobal::PrintDataTo(StringStream* stream) { |
| 285 SmartPointer<char> name_string = name()->ToCString(); | 285 SmartPointer<char> name_string = name()->ToCString(); |
| 286 stream->Add("%s #%d / ", *name_string, arity()); | 286 stream->Add("%s #%d / ", *name_string, arity()); |
| 287 } | 287 } |
| 288 | 288 |
| 289 | 289 |
| 290 void LCallKnownGlobal::PrintDataTo(StringStream* stream) const { | 290 void LCallKnownGlobal::PrintDataTo(StringStream* stream) { |
| 291 stream->Add("#%d / ", arity()); | 291 stream->Add("#%d / ", arity()); |
| 292 } | 292 } |
| 293 | 293 |
| 294 | 294 |
| 295 void LCallNew::PrintDataTo(StringStream* stream) const { | 295 void LCallNew::PrintDataTo(StringStream* stream) { |
| 296 LUnaryOperation::PrintDataTo(stream); | 296 LUnaryOperation<1>::PrintDataTo(stream); |
| 297 stream->Add(" #%d / ", arity()); | 297 stream->Add(" #%d / ", arity()); |
| 298 } | 298 } |
| 299 | 299 |
| 300 | 300 |
| 301 void LClassOfTest::PrintDataTo(StringStream* stream) const { | 301 void LClassOfTest::PrintDataTo(StringStream* stream) { |
| 302 stream->Add("= class_of_test("); | 302 stream->Add("= class_of_test("); |
| 303 input()->PrintTo(stream); | 303 input()->PrintTo(stream); |
| 304 stream->Add(", \"%o\")", *hydrogen()->class_name()); | 304 stream->Add(", \"%o\")", *hydrogen()->class_name()); |
| 305 } | 305 } |
| 306 | 306 |
| 307 | 307 |
| 308 void LUnaryOperation::PrintDataTo(StringStream* stream) const { | 308 template <int R> |
| 309 void LUnaryOperation<R>::PrintDataTo(StringStream* stream) { |
| 309 stream->Add("= "); | 310 stream->Add("= "); |
| 310 input()->PrintTo(stream); | 311 input()->PrintTo(stream); |
| 311 } | 312 } |
| 312 | 313 |
| 313 | 314 |
| 314 void LAccessArgumentsAt::PrintDataTo(StringStream* stream) const { | 315 void LAccessArgumentsAt::PrintDataTo(StringStream* stream) { |
| 315 arguments()->PrintTo(stream); | 316 arguments()->PrintTo(stream); |
| 316 | 317 |
| 317 stream->Add(" length "); | 318 stream->Add(" length "); |
| 318 length()->PrintTo(stream); | 319 length()->PrintTo(stream); |
| 319 | 320 |
| 320 stream->Add(" index "); | 321 stream->Add(" index "); |
| 321 index()->PrintTo(stream); | 322 index()->PrintTo(stream); |
| 322 } | 323 } |
| 323 | 324 |
| 324 | 325 |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 374 | 375 |
| 375 if (can_eliminate) { | 376 if (can_eliminate) { |
| 376 label->set_replacement(GetLabel(goto_instr->block_id())); | 377 label->set_replacement(GetLabel(goto_instr->block_id())); |
| 377 } | 378 } |
| 378 } | 379 } |
| 379 } | 380 } |
| 380 } | 381 } |
| 381 } | 382 } |
| 382 | 383 |
| 383 | 384 |
| 384 void LStoreNamed::PrintDataTo(StringStream* stream) const { | 385 void LStoreNamed::PrintDataTo(StringStream* stream) { |
| 385 object()->PrintTo(stream); | 386 object()->PrintTo(stream); |
| 386 stream->Add("."); | 387 stream->Add("."); |
| 387 stream->Add(*String::cast(*name())->ToCString()); | 388 stream->Add(*String::cast(*name())->ToCString()); |
| 388 stream->Add(" <- "); | 389 stream->Add(" <- "); |
| 389 value()->PrintTo(stream); | 390 value()->PrintTo(stream); |
| 390 } | 391 } |
| 391 | 392 |
| 392 | 393 |
| 393 void LStoreKeyed::PrintDataTo(StringStream* stream) const { | 394 void LStoreKeyed::PrintDataTo(StringStream* stream) { |
| 394 object()->PrintTo(stream); | 395 object()->PrintTo(stream); |
| 395 stream->Add("["); | 396 stream->Add("["); |
| 396 key()->PrintTo(stream); | 397 key()->PrintTo(stream); |
| 397 stream->Add("] <- "); | 398 stream->Add("] <- "); |
| 398 value()->PrintTo(stream); | 399 value()->PrintTo(stream); |
| 399 } | 400 } |
| 400 | 401 |
| 401 | 402 |
| 402 int LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) { | 403 int LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) { |
| 403 LGap* gap = new LGap(block); | 404 LGap* gap = new LGap(block); |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 591 LOperand* LChunkBuilder::Use(HValue* value, LUnallocated* operand) { | 592 LOperand* LChunkBuilder::Use(HValue* value, LUnallocated* operand) { |
| 592 if (value->EmitAtUses()) { | 593 if (value->EmitAtUses()) { |
| 593 HInstruction* instr = HInstruction::cast(value); | 594 HInstruction* instr = HInstruction::cast(value); |
| 594 VisitInstruction(instr); | 595 VisitInstruction(instr); |
| 595 } | 596 } |
| 596 allocator_->RecordUse(value, operand); | 597 allocator_->RecordUse(value, operand); |
| 597 return operand; | 598 return operand; |
| 598 } | 599 } |
| 599 | 600 |
| 600 | 601 |
| 601 LInstruction* LChunkBuilder::Define(LInstruction* instr) { | 602 LInstruction* LChunkBuilder::Define(LTemplateInstruction<1>* instr) { |
| 602 return Define(instr, new LUnallocated(LUnallocated::NONE)); | 603 return Define(instr, new LUnallocated(LUnallocated::NONE)); |
| 603 } | 604 } |
| 604 | 605 |
| 605 | 606 |
| 606 LInstruction* LChunkBuilder::DefineAsRegister(LInstruction* instr) { | 607 LInstruction* LChunkBuilder::DefineAsRegister(LTemplateInstruction<1>* instr) { |
| 607 return Define(instr, new LUnallocated(LUnallocated::MUST_HAVE_REGISTER)); | 608 return Define(instr, new LUnallocated(LUnallocated::MUST_HAVE_REGISTER)); |
| 608 } | 609 } |
| 609 | 610 |
| 610 | 611 |
| 611 LInstruction* LChunkBuilder::DefineAsSpilled(LInstruction* instr, int index) { | 612 LInstruction* LChunkBuilder::DefineAsSpilled(LTemplateInstruction<1>* instr, |
| 613 int index) { |
| 612 return Define(instr, new LUnallocated(LUnallocated::FIXED_SLOT, index)); | 614 return Define(instr, new LUnallocated(LUnallocated::FIXED_SLOT, index)); |
| 613 } | 615 } |
| 614 | 616 |
| 615 | 617 |
| 616 LInstruction* LChunkBuilder::DefineSameAsFirst(LInstruction* instr) { | 618 LInstruction* LChunkBuilder::DefineSameAsFirst(LTemplateInstruction<1>* instr) { |
| 617 return Define(instr, new LUnallocated(LUnallocated::SAME_AS_FIRST_INPUT)); | 619 return Define(instr, new LUnallocated(LUnallocated::SAME_AS_FIRST_INPUT)); |
| 618 } | 620 } |
| 619 | 621 |
| 620 | 622 |
| 621 LInstruction* LChunkBuilder::DefineFixed(LInstruction* instr, Register reg) { | 623 LInstruction* LChunkBuilder::DefineFixed(LTemplateInstruction<1>* instr, |
| 624 Register reg) { |
| 622 return Define(instr, ToUnallocated(reg)); | 625 return Define(instr, ToUnallocated(reg)); |
| 623 } | 626 } |
| 624 | 627 |
| 625 | 628 |
| 626 LInstruction* LChunkBuilder::DefineFixedDouble(LInstruction* instr, | 629 LInstruction* LChunkBuilder::DefineFixedDouble(LTemplateInstruction<1>* instr, |
| 627 XMMRegister reg) { | 630 XMMRegister reg) { |
| 628 return Define(instr, ToUnallocated(reg)); | 631 return Define(instr, ToUnallocated(reg)); |
| 629 } | 632 } |
| 630 | 633 |
| 631 | 634 |
| 632 LInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) { | 635 LInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) { |
| 633 HEnvironment* hydrogen_env = current_block_->last_environment(); | 636 HEnvironment* hydrogen_env = current_block_->last_environment(); |
| 634 instr->set_environment(CreateEnvironment(hydrogen_env)); | 637 instr->set_environment(CreateEnvironment(hydrogen_env)); |
| 635 return instr; | 638 return instr; |
| 636 } | 639 } |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 685 } | 688 } |
| 686 | 689 |
| 687 | 690 |
| 688 LInstruction* LChunkBuilder::AssignPointerMap(LInstruction* instr) { | 691 LInstruction* LChunkBuilder::AssignPointerMap(LInstruction* instr) { |
| 689 ASSERT(!instr->HasPointerMap()); | 692 ASSERT(!instr->HasPointerMap()); |
| 690 instr->set_pointer_map(new LPointerMap(position_)); | 693 instr->set_pointer_map(new LPointerMap(position_)); |
| 691 return instr; | 694 return instr; |
| 692 } | 695 } |
| 693 | 696 |
| 694 | 697 |
| 695 LInstruction* LChunkBuilder::Define(LInstruction* instr, LUnallocated* result) { | 698 LInstruction* LChunkBuilder::Define(LTemplateInstruction<1>* instr, |
| 699 LUnallocated* result) { |
| 696 allocator_->RecordDefinition(current_instruction_, result); | 700 allocator_->RecordDefinition(current_instruction_, result); |
| 697 instr->set_result(result); | 701 instr->set_result(result); |
| 698 return instr; | 702 return instr; |
| 699 } | 703 } |
| 700 | 704 |
| 701 | 705 |
| 702 LOperand* LChunkBuilder::Temp() { | 706 LOperand* LChunkBuilder::Temp() { |
| 703 LUnallocated* operand = new LUnallocated(LUnallocated::NONE); | 707 LUnallocated* operand = new LUnallocated(LUnallocated::NONE); |
| 704 allocator_->RecordTemporary(operand); | 708 allocator_->RecordTemporary(operand); |
| 705 return operand; | 709 return operand; |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 774 bool can_truncate = true; | 778 bool can_truncate = true; |
| 775 for (int i = 0; i < instr->uses()->length(); i++) { | 779 for (int i = 0; i < instr->uses()->length(); i++) { |
| 776 if (!instr->uses()->at(i)->CheckFlag(HValue::kTruncatingToInt32)) { | 780 if (!instr->uses()->at(i)->CheckFlag(HValue::kTruncatingToInt32)) { |
| 777 can_truncate = false; | 781 can_truncate = false; |
| 778 break; | 782 break; |
| 779 } | 783 } |
| 780 } | 784 } |
| 781 can_deopt = !can_truncate; | 785 can_deopt = !can_truncate; |
| 782 } | 786 } |
| 783 | 787 |
| 784 LInstruction* result = | 788 LShiftI* result = new LShiftI(op, left, right, can_deopt); |
| 785 DefineSameAsFirst(new LShiftI(op, left, right, can_deopt)); | 789 return can_deopt |
| 786 if (can_deopt) AssignEnvironment(result); | 790 ? AssignEnvironment(DefineSameAsFirst(result)) |
| 787 return result; | 791 : DefineSameAsFirst(result); |
| 788 } | 792 } |
| 789 | 793 |
| 790 | 794 |
| 791 LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op, | 795 LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op, |
| 792 HArithmeticBinaryOperation* instr) { | 796 HArithmeticBinaryOperation* instr) { |
| 793 ASSERT(instr->representation().IsDouble()); | 797 ASSERT(instr->representation().IsDouble()); |
| 794 ASSERT(instr->left()->representation().IsDouble()); | 798 ASSERT(instr->left()->representation().IsDouble()); |
| 795 ASSERT(instr->right()->representation().IsDouble()); | 799 ASSERT(instr->right()->representation().IsDouble()); |
| 796 LOperand* left = UseRegisterAtStart(instr->left()); | 800 LOperand* left = UseRegisterAtStart(instr->left()); |
| 797 LOperand* right = UseRegisterAtStart(instr->right()); | 801 LOperand* right = UseRegisterAtStart(instr->right()); |
| 798 LArithmeticD* result = new LArithmeticD(op, left, right); | 802 LArithmeticD* result = new LArithmeticD(op, left, right); |
| 799 return DefineSameAsFirst(result); | 803 return DefineSameAsFirst(result); |
| 800 } | 804 } |
| 801 | 805 |
| 802 | 806 |
| 803 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, | 807 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, |
| 804 HArithmeticBinaryOperation* instr) { | 808 HArithmeticBinaryOperation* instr) { |
| 805 ASSERT(op == Token::ADD || | 809 ASSERT(op == Token::ADD || |
| 806 op == Token::DIV || | 810 op == Token::DIV || |
| 807 op == Token::MOD || | 811 op == Token::MOD || |
| 808 op == Token::MUL || | 812 op == Token::MUL || |
| 809 op == Token::SUB); | 813 op == Token::SUB); |
| 810 HValue* left = instr->left(); | 814 HValue* left = instr->left(); |
| 811 HValue* right = instr->right(); | 815 HValue* right = instr->right(); |
| 812 ASSERT(left->representation().IsTagged()); | 816 ASSERT(left->representation().IsTagged()); |
| 813 ASSERT(right->representation().IsTagged()); | 817 ASSERT(right->representation().IsTagged()); |
| 814 LOperand* left_operand = UseFixed(left, edx); | 818 LOperand* left_operand = UseFixed(left, edx); |
| 815 LOperand* right_operand = UseFixed(right, eax); | 819 LOperand* right_operand = UseFixed(right, eax); |
| 816 LInstruction* result = new LArithmeticT(op, left_operand, right_operand); | 820 LArithmeticT* result = new LArithmeticT(op, left_operand, right_operand); |
| 817 return MarkAsCall(DefineFixed(result, eax), instr); | 821 return MarkAsCall(DefineFixed(result, eax), instr); |
| 818 } | 822 } |
| 819 | 823 |
| 820 void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) { | 824 void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) { |
| 821 ASSERT(is_building()); | 825 ASSERT(is_building()); |
| 822 current_block_ = block; | 826 current_block_ = block; |
| 823 next_block_ = next_block; | 827 next_block_ = next_block; |
| 824 if (block->IsStartBlock()) { | 828 if (block->IsStartBlock()) { |
| 825 block->UpdateEnvironment(graph_->start_environment()); | 829 block->UpdateEnvironment(graph_->start_environment()); |
| 826 argument_count_ = 0; | 830 argument_count_ = 0; |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 940 spilled_double_registers_[value->index()], | 944 spilled_double_registers_[value->index()], |
| 941 false); | 945 false); |
| 942 } | 946 } |
| 943 } | 947 } |
| 944 | 948 |
| 945 cgen->AddToTranslation(translation, value, HasTaggedValueAt(i)); | 949 cgen->AddToTranslation(translation, value, HasTaggedValueAt(i)); |
| 946 } | 950 } |
| 947 } | 951 } |
| 948 | 952 |
| 949 | 953 |
| 950 void LEnvironment::PrintTo(StringStream* stream) const { | 954 void LEnvironment::PrintTo(StringStream* stream) { |
| 951 stream->Add("[id=%d|", ast_id()); | 955 stream->Add("[id=%d|", ast_id()); |
| 952 stream->Add("[parameters=%d|", parameter_count()); | 956 stream->Add("[parameters=%d|", parameter_count()); |
| 953 stream->Add("[arguments_stack_height=%d|", arguments_stack_height()); | 957 stream->Add("[arguments_stack_height=%d|", arguments_stack_height()); |
| 954 for (int i = 0; i < values_.length(); ++i) { | 958 for (int i = 0; i < values_.length(); ++i) { |
| 955 if (i != 0) stream->Add(";"); | 959 if (i != 0) stream->Add(";"); |
| 956 if (values_[i] == NULL) { | 960 if (values_[i] == NULL) { |
| 957 stream->Add("[hole]"); | 961 stream->Add("[hole]"); |
| 958 } else { | 962 } else { |
| 959 values_[i]->PrintTo(stream); | 963 values_[i]->PrintTo(stream); |
| 960 } | 964 } |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 992 } | 996 } |
| 993 } | 997 } |
| 994 result->AddValue(op, value->representation()); | 998 result->AddValue(op, value->representation()); |
| 995 } | 999 } |
| 996 | 1000 |
| 997 return result; | 1001 return result; |
| 998 } | 1002 } |
| 999 | 1003 |
| 1000 | 1004 |
| 1001 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) { | 1005 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) { |
| 1002 LInstruction* result = new LGoto(instr->FirstSuccessor()->block_id(), | 1006 LGoto* result = new LGoto(instr->FirstSuccessor()->block_id(), |
| 1003 instr->include_stack_check()); | 1007 instr->include_stack_check()); |
| 1004 if (instr->include_stack_check()) result = AssignPointerMap(result); | 1008 return (instr->include_stack_check()) |
| 1005 return result; | 1009 ? AssignPointerMap(result) |
| 1010 : result; |
| 1006 } | 1011 } |
| 1007 | 1012 |
| 1008 | 1013 |
| 1009 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { | 1014 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { |
| 1010 HValue* v = instr->value(); | 1015 HValue* v = instr->value(); |
| 1011 HBasicBlock* first = instr->FirstSuccessor(); | 1016 HBasicBlock* first = instr->FirstSuccessor(); |
| 1012 HBasicBlock* second = instr->SecondSuccessor(); | 1017 HBasicBlock* second = instr->SecondSuccessor(); |
| 1013 ASSERT(first != NULL && second != NULL); | 1018 ASSERT(first != NULL && second != NULL); |
| 1014 int first_id = first->block_id(); | 1019 int first_id = first->block_id(); |
| 1015 int second_id = second->block_id(); | 1020 int second_id = second->block_id(); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1044 UseRegisterAtStart(right), | 1049 UseRegisterAtStart(right), |
| 1045 first_id, | 1050 first_id, |
| 1046 second_id, | 1051 second_id, |
| 1047 true); | 1052 true); |
| 1048 } else { | 1053 } else { |
| 1049 ASSERT(left->representation().IsTagged()); | 1054 ASSERT(left->representation().IsTagged()); |
| 1050 ASSERT(right->representation().IsTagged()); | 1055 ASSERT(right->representation().IsTagged()); |
| 1051 bool reversed = op == Token::GT || op == Token::LTE; | 1056 bool reversed = op == Token::GT || op == Token::LTE; |
| 1052 LOperand* left_operand = UseFixed(left, reversed ? eax : edx); | 1057 LOperand* left_operand = UseFixed(left, reversed ? eax : edx); |
| 1053 LOperand* right_operand = UseFixed(right, reversed ? edx : eax); | 1058 LOperand* right_operand = UseFixed(right, reversed ? edx : eax); |
| 1054 LInstruction* result = new LCmpTAndBranch(left_operand, | 1059 LCmpTAndBranch* result = new LCmpTAndBranch(left_operand, |
| 1055 right_operand, | 1060 right_operand, |
| 1056 first_id, | 1061 first_id, |
| 1057 second_id); | 1062 second_id); |
| 1058 return MarkAsCall(result, instr); | 1063 return MarkAsCall(result, instr); |
| 1059 } | 1064 } |
| 1060 } else if (v->IsIsSmi()) { | 1065 } else if (v->IsIsSmi()) { |
| 1061 HIsSmi* compare = HIsSmi::cast(v); | 1066 HIsSmi* compare = HIsSmi::cast(v); |
| 1062 ASSERT(compare->value()->representation().IsTagged()); | 1067 ASSERT(compare->value()->representation().IsTagged()); |
| 1063 | 1068 |
| 1064 return new LIsSmiAndBranch(Use(compare->value()), | 1069 return new LIsSmiAndBranch(Use(compare->value()), |
| 1065 first_id, | 1070 first_id, |
| 1066 second_id); | 1071 second_id); |
| 1067 } else if (v->IsHasInstanceType()) { | 1072 } else if (v->IsHasInstanceType()) { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1101 first_id, | 1106 first_id, |
| 1102 second_id); | 1107 second_id); |
| 1103 } else if (v->IsCompareJSObjectEq()) { | 1108 } else if (v->IsCompareJSObjectEq()) { |
| 1104 HCompareJSObjectEq* compare = HCompareJSObjectEq::cast(v); | 1109 HCompareJSObjectEq* compare = HCompareJSObjectEq::cast(v); |
| 1105 return new LCmpJSObjectEqAndBranch(UseRegisterAtStart(compare->left()), | 1110 return new LCmpJSObjectEqAndBranch(UseRegisterAtStart(compare->left()), |
| 1106 UseRegisterAtStart(compare->right()), | 1111 UseRegisterAtStart(compare->right()), |
| 1107 first_id, | 1112 first_id, |
| 1108 second_id); | 1113 second_id); |
| 1109 } else if (v->IsInstanceOf()) { | 1114 } else if (v->IsInstanceOf()) { |
| 1110 HInstanceOf* instance_of = HInstanceOf::cast(v); | 1115 HInstanceOf* instance_of = HInstanceOf::cast(v); |
| 1111 LInstruction* result = | 1116 LInstanceOfAndBranch* result = |
| 1112 new LInstanceOfAndBranch( | 1117 new LInstanceOfAndBranch( |
| 1113 UseFixed(instance_of->left(), InstanceofStub::left()), | 1118 UseFixed(instance_of->left(), InstanceofStub::left()), |
| 1114 UseFixed(instance_of->right(), InstanceofStub::right()), | 1119 UseFixed(instance_of->right(), InstanceofStub::right()), |
| 1115 first_id, | 1120 first_id, |
| 1116 second_id); | 1121 second_id); |
| 1117 return MarkAsCall(result, instr); | 1122 return MarkAsCall(result, instr); |
| 1118 } else if (v->IsTypeofIs()) { | 1123 } else if (v->IsTypeofIs()) { |
| 1119 HTypeofIs* typeof_is = HTypeofIs::cast(v); | 1124 HTypeofIs* typeof_is = HTypeofIs::cast(v); |
| 1120 return new LTypeofIsAndBranch(UseTempRegister(typeof_is->value()), | 1125 return new LTypeofIsAndBranch(UseTempRegister(typeof_is->value()), |
| 1121 first_id, | 1126 first_id, |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1148 return DefineAsRegister(new LArgumentsLength(Use(length->value()))); | 1153 return DefineAsRegister(new LArgumentsLength(Use(length->value()))); |
| 1149 } | 1154 } |
| 1150 | 1155 |
| 1151 | 1156 |
| 1152 LInstruction* LChunkBuilder::DoArgumentsElements(HArgumentsElements* elems) { | 1157 LInstruction* LChunkBuilder::DoArgumentsElements(HArgumentsElements* elems) { |
| 1153 return DefineAsRegister(new LArgumentsElements); | 1158 return DefineAsRegister(new LArgumentsElements); |
| 1154 } | 1159 } |
| 1155 | 1160 |
| 1156 | 1161 |
| 1157 LInstruction* LChunkBuilder::DoInstanceOf(HInstanceOf* instr) { | 1162 LInstruction* LChunkBuilder::DoInstanceOf(HInstanceOf* instr) { |
| 1158 LInstruction* result = | 1163 LInstanceOf* result = |
| 1159 new LInstanceOf(UseFixed(instr->left(), InstanceofStub::left()), | 1164 new LInstanceOf(UseFixed(instr->left(), InstanceofStub::left()), |
| 1160 UseFixed(instr->right(), InstanceofStub::right())); | 1165 UseFixed(instr->right(), InstanceofStub::right())); |
| 1161 return MarkAsCall(DefineFixed(result, eax), instr); | 1166 return MarkAsCall(DefineFixed(result, eax), instr); |
| 1162 } | 1167 } |
| 1163 | 1168 |
| 1164 | 1169 |
| 1165 LInstruction* LChunkBuilder::DoInstanceOfKnownGlobal( | 1170 LInstruction* LChunkBuilder::DoInstanceOfKnownGlobal( |
| 1166 HInstanceOfKnownGlobal* instr) { | 1171 HInstanceOfKnownGlobal* instr) { |
| 1167 LInstruction* result = | 1172 LInstanceOfKnownGlobal* result = |
| 1168 new LInstanceOfKnownGlobal( | 1173 new LInstanceOfKnownGlobal( |
| 1169 UseFixed(instr->value(), InstanceofStub::left()), | 1174 UseFixed(instr->value(), InstanceofStub::left()), |
| 1170 FixedTemp(edi)); | 1175 FixedTemp(edi)); |
| 1171 MarkAsSaveDoubles(result); | 1176 MarkAsSaveDoubles(result); |
| 1172 return AssignEnvironment(AssignPointerMap(DefineFixed(result, eax))); | 1177 return AssignEnvironment(AssignPointerMap(DefineFixed(result, eax))); |
| 1173 } | 1178 } |
| 1174 | 1179 |
| 1175 | 1180 |
| 1176 LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) { | 1181 LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) { |
| 1177 LOperand* function = UseFixed(instr->function(), edi); | 1182 LOperand* function = UseFixed(instr->function(), edi); |
| 1178 LOperand* receiver = UseFixed(instr->receiver(), eax); | 1183 LOperand* receiver = UseFixed(instr->receiver(), eax); |
| 1179 LOperand* length = UseRegisterAtStart(instr->length()); | 1184 LOperand* length = UseRegisterAtStart(instr->length()); |
| 1180 LOperand* elements = UseRegisterAtStart(instr->elements()); | 1185 LOperand* elements = UseRegisterAtStart(instr->elements()); |
| 1181 LInstruction* result = new LApplyArguments(function, | 1186 LApplyArguments* result = new LApplyArguments(function, |
| 1182 receiver, | 1187 receiver, |
| 1183 length, | 1188 length, |
| 1184 elements); | 1189 elements); |
| 1185 return MarkAsCall(DefineFixed(result, eax), instr, CAN_DEOPTIMIZE_EAGERLY); | 1190 return MarkAsCall(DefineFixed(result, eax), instr, CAN_DEOPTIMIZE_EAGERLY); |
| 1186 } | 1191 } |
| 1187 | 1192 |
| 1188 | 1193 |
| 1189 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) { | 1194 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) { |
| 1190 ++argument_count_; | 1195 ++argument_count_; |
| 1191 LOperand* argument = UseOrConstant(instr->argument()); | 1196 LOperand* argument = UseOrConstant(instr->argument()); |
| 1192 return new LPushArgument(argument); | 1197 return new LPushArgument(argument); |
| 1193 } | 1198 } |
| 1194 | 1199 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1207 HCallConstantFunction* instr) { | 1212 HCallConstantFunction* instr) { |
| 1208 argument_count_ -= instr->argument_count(); | 1213 argument_count_ -= instr->argument_count(); |
| 1209 return MarkAsCall(DefineFixed(new LCallConstantFunction, eax), instr); | 1214 return MarkAsCall(DefineFixed(new LCallConstantFunction, eax), instr); |
| 1210 } | 1215 } |
| 1211 | 1216 |
| 1212 | 1217 |
| 1213 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { | 1218 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { |
| 1214 BuiltinFunctionId op = instr->op(); | 1219 BuiltinFunctionId op = instr->op(); |
| 1215 if (op == kMathLog || op == kMathSin || op == kMathCos) { | 1220 if (op == kMathLog || op == kMathSin || op == kMathCos) { |
| 1216 LOperand* input = UseFixedDouble(instr->value(), xmm1); | 1221 LOperand* input = UseFixedDouble(instr->value(), xmm1); |
| 1217 LInstruction* result = new LUnaryMathOperation(input); | 1222 LUnaryMathOperation* result = new LUnaryMathOperation(input); |
| 1218 return MarkAsCall(DefineFixedDouble(result, xmm1), instr); | 1223 return MarkAsCall(DefineFixedDouble(result, xmm1), instr); |
| 1219 } else { | 1224 } else { |
| 1220 LOperand* input = UseRegisterAtStart(instr->value()); | 1225 LOperand* input = UseRegisterAtStart(instr->value()); |
| 1221 LInstruction* result = new LUnaryMathOperation(input); | 1226 LUnaryMathOperation* result = new LUnaryMathOperation(input); |
| 1222 switch (op) { | 1227 switch (op) { |
| 1223 case kMathAbs: | 1228 case kMathAbs: |
| 1224 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result))); | 1229 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result))); |
| 1225 case kMathFloor: | 1230 case kMathFloor: |
| 1226 return AssignEnvironment(DefineAsRegister(result)); | 1231 return AssignEnvironment(DefineAsRegister(result)); |
| 1227 case kMathRound: | 1232 case kMathRound: |
| 1228 return AssignEnvironment(DefineAsRegister(result)); | 1233 return AssignEnvironment(DefineAsRegister(result)); |
| 1229 case kMathSqrt: | 1234 case kMathSqrt: |
| 1230 return DefineSameAsFirst(result); | 1235 return DefineSameAsFirst(result); |
| 1231 case kMathPowHalf: | 1236 case kMathPowHalf: |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1260 | 1265 |
| 1261 LInstruction* LChunkBuilder::DoCallKnownGlobal(HCallKnownGlobal* instr) { | 1266 LInstruction* LChunkBuilder::DoCallKnownGlobal(HCallKnownGlobal* instr) { |
| 1262 argument_count_ -= instr->argument_count(); | 1267 argument_count_ -= instr->argument_count(); |
| 1263 return MarkAsCall(DefineFixed(new LCallKnownGlobal, eax), instr); | 1268 return MarkAsCall(DefineFixed(new LCallKnownGlobal, eax), instr); |
| 1264 } | 1269 } |
| 1265 | 1270 |
| 1266 | 1271 |
| 1267 LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) { | 1272 LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) { |
| 1268 LOperand* constructor = UseFixed(instr->constructor(), edi); | 1273 LOperand* constructor = UseFixed(instr->constructor(), edi); |
| 1269 argument_count_ -= instr->argument_count(); | 1274 argument_count_ -= instr->argument_count(); |
| 1270 LInstruction* result = new LCallNew(constructor); | 1275 LCallNew* result = new LCallNew(constructor); |
| 1271 return MarkAsCall(DefineFixed(result, eax), instr); | 1276 return MarkAsCall(DefineFixed(result, eax), instr); |
| 1272 } | 1277 } |
| 1273 | 1278 |
| 1274 | 1279 |
| 1275 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) { | 1280 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) { |
| 1276 argument_count_ -= instr->argument_count(); | 1281 argument_count_ -= instr->argument_count(); |
| 1277 return MarkAsCall(DefineFixed(new LCallFunction, eax), instr); | 1282 return MarkAsCall(DefineFixed(new LCallFunction, eax), instr); |
| 1278 } | 1283 } |
| 1279 | 1284 |
| 1280 | 1285 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1340 | 1345 |
| 1341 LInstruction* LChunkBuilder::DoMod(HMod* instr) { | 1346 LInstruction* LChunkBuilder::DoMod(HMod* instr) { |
| 1342 if (instr->representation().IsInteger32()) { | 1347 if (instr->representation().IsInteger32()) { |
| 1343 ASSERT(instr->left()->representation().IsInteger32()); | 1348 ASSERT(instr->left()->representation().IsInteger32()); |
| 1344 ASSERT(instr->right()->representation().IsInteger32()); | 1349 ASSERT(instr->right()->representation().IsInteger32()); |
| 1345 // The temporary operand is necessary to ensure that right is not allocated | 1350 // The temporary operand is necessary to ensure that right is not allocated |
| 1346 // into edx. | 1351 // into edx. |
| 1347 FixedTemp(edx); | 1352 FixedTemp(edx); |
| 1348 LOperand* value = UseFixed(instr->left(), eax); | 1353 LOperand* value = UseFixed(instr->left(), eax); |
| 1349 LOperand* divisor = UseRegister(instr->right()); | 1354 LOperand* divisor = UseRegister(instr->right()); |
| 1350 LInstruction* result = DefineFixed(new LModI(value, divisor), edx); | 1355 LModI* mod = new LModI(value, divisor); |
| 1351 if (instr->CheckFlag(HValue::kBailoutOnMinusZero) || | 1356 LInstruction* result = DefineFixed(mod, edx); |
| 1352 instr->CheckFlag(HValue::kCanBeDivByZero)) { | 1357 return (instr->CheckFlag(HValue::kBailoutOnMinusZero) || |
| 1353 result = AssignEnvironment(result); | 1358 instr->CheckFlag(HValue::kCanBeDivByZero)) |
| 1354 } | 1359 ? AssignEnvironment(result) |
| 1355 return result; | 1360 : result; |
| 1356 } else if (instr->representation().IsTagged()) { | 1361 } else if (instr->representation().IsTagged()) { |
| 1357 return DoArithmeticT(Token::MOD, instr); | 1362 return DoArithmeticT(Token::MOD, instr); |
| 1358 } else { | 1363 } else { |
| 1359 ASSERT(instr->representation().IsDouble()); | 1364 ASSERT(instr->representation().IsDouble()); |
| 1360 // We call a C function for double modulo. It can't trigger a GC. | 1365 // We call a C function for double modulo. It can't trigger a GC. |
| 1361 // We need to use fixed result register for the call. | 1366 // We need to use fixed result register for the call. |
| 1362 // TODO(fschneider): Allow any register as input registers. | 1367 // TODO(fschneider): Allow any register as input registers. |
| 1363 LOperand* left = UseFixedDouble(instr->left(), xmm1); | 1368 LOperand* left = UseFixedDouble(instr->left(), xmm1); |
| 1364 LOperand* right = UseFixedDouble(instr->right(), xmm2); | 1369 LOperand* right = UseFixedDouble(instr->right(), xmm2); |
| 1365 LArithmeticD* result = new LArithmeticD(Token::MOD, left, right); | 1370 LArithmeticD* result = new LArithmeticD(Token::MOD, left, right); |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1456 return DefineAsRegister(new LCmpID(op, left, right, false)); | 1461 return DefineAsRegister(new LCmpID(op, left, right, false)); |
| 1457 } else if (instr->left()->representation().IsDouble()) { | 1462 } else if (instr->left()->representation().IsDouble()) { |
| 1458 ASSERT(instr->right()->representation().IsDouble()); | 1463 ASSERT(instr->right()->representation().IsDouble()); |
| 1459 LOperand* left = UseRegisterAtStart(instr->left()); | 1464 LOperand* left = UseRegisterAtStart(instr->left()); |
| 1460 LOperand* right = UseRegisterAtStart(instr->right()); | 1465 LOperand* right = UseRegisterAtStart(instr->right()); |
| 1461 return DefineAsRegister(new LCmpID(op, left, right, true)); | 1466 return DefineAsRegister(new LCmpID(op, left, right, true)); |
| 1462 } else { | 1467 } else { |
| 1463 bool reversed = (op == Token::GT || op == Token::LTE); | 1468 bool reversed = (op == Token::GT || op == Token::LTE); |
| 1464 LOperand* left = UseFixed(instr->left(), reversed ? eax : edx); | 1469 LOperand* left = UseFixed(instr->left(), reversed ? eax : edx); |
| 1465 LOperand* right = UseFixed(instr->right(), reversed ? edx : eax); | 1470 LOperand* right = UseFixed(instr->right(), reversed ? edx : eax); |
| 1466 LInstruction* result = new LCmpT(left, right); | 1471 LCmpT* result = new LCmpT(left, right); |
| 1467 return MarkAsCall(DefineFixed(result, eax), instr); | 1472 return MarkAsCall(DefineFixed(result, eax), instr); |
| 1468 } | 1473 } |
| 1469 } | 1474 } |
| 1470 | 1475 |
| 1471 | 1476 |
| 1472 LInstruction* LChunkBuilder::DoCompareJSObjectEq( | 1477 LInstruction* LChunkBuilder::DoCompareJSObjectEq( |
| 1473 HCompareJSObjectEq* instr) { | 1478 HCompareJSObjectEq* instr) { |
| 1474 LOperand* left = UseRegisterAtStart(instr->left()); | 1479 LOperand* left = UseRegisterAtStart(instr->left()); |
| 1475 LOperand* right = UseRegisterAtStart(instr->right()); | 1480 LOperand* right = UseRegisterAtStart(instr->right()); |
| 1476 LInstruction* result = new LCmpJSObjectEq(left, right); | 1481 LCmpJSObjectEq* result = new LCmpJSObjectEq(left, right); |
| 1477 return DefineAsRegister(result); | 1482 return DefineAsRegister(result); |
| 1478 } | 1483 } |
| 1479 | 1484 |
| 1480 | 1485 |
| 1481 LInstruction* LChunkBuilder::DoIsNull(HIsNull* instr) { | 1486 LInstruction* LChunkBuilder::DoIsNull(HIsNull* instr) { |
| 1482 ASSERT(instr->value()->representation().IsTagged()); | 1487 ASSERT(instr->value()->representation().IsTagged()); |
| 1483 LOperand* value = UseRegisterAtStart(instr->value()); | 1488 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1484 | 1489 |
| 1485 return DefineAsRegister(new LIsNull(value, | 1490 return DefineAsRegister(new LIsNull(value, |
| 1486 instr->is_strict())); | 1491 instr->is_strict())); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1535 | 1540 |
| 1536 | 1541 |
| 1537 LInstruction* LChunkBuilder::DoFixedArrayLength(HFixedArrayLength* instr) { | 1542 LInstruction* LChunkBuilder::DoFixedArrayLength(HFixedArrayLength* instr) { |
| 1538 LOperand* array = UseRegisterAtStart(instr->value()); | 1543 LOperand* array = UseRegisterAtStart(instr->value()); |
| 1539 return DefineAsRegister(new LFixedArrayLength(array)); | 1544 return DefineAsRegister(new LFixedArrayLength(array)); |
| 1540 } | 1545 } |
| 1541 | 1546 |
| 1542 | 1547 |
| 1543 LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) { | 1548 LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) { |
| 1544 LOperand* object = UseRegister(instr->value()); | 1549 LOperand* object = UseRegister(instr->value()); |
| 1545 LInstruction* result = new LValueOf(object, TempRegister()); | 1550 LValueOf* result = new LValueOf(object, TempRegister()); |
| 1546 return AssignEnvironment(DefineSameAsFirst(result)); | 1551 return AssignEnvironment(DefineSameAsFirst(result)); |
| 1547 } | 1552 } |
| 1548 | 1553 |
| 1549 | 1554 |
| 1550 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) { | 1555 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) { |
| 1551 return AssignEnvironment(new LBoundsCheck(UseRegisterAtStart(instr->index()), | 1556 return AssignEnvironment(new LBoundsCheck(UseRegisterAtStart(instr->index()), |
| 1552 Use(instr->length()))); | 1557 Use(instr->length()))); |
| 1553 } | 1558 } |
| 1554 | 1559 |
| 1555 | 1560 |
| 1556 LInstruction* LChunkBuilder::DoThrow(HThrow* instr) { | 1561 LInstruction* LChunkBuilder::DoThrow(HThrow* instr) { |
| 1557 LOperand* value = UseFixed(instr->value(), eax); | 1562 LOperand* value = UseFixed(instr->value(), eax); |
| 1558 return MarkAsCall(new LThrow(value), instr); | 1563 return MarkAsCall(new LThrow(value), instr); |
| 1559 } | 1564 } |
| 1560 | 1565 |
| 1561 | 1566 |
| 1562 LInstruction* LChunkBuilder::DoChange(HChange* instr) { | 1567 LInstruction* LChunkBuilder::DoChange(HChange* instr) { |
| 1563 Representation from = instr->from(); | 1568 Representation from = instr->from(); |
| 1564 Representation to = instr->to(); | 1569 Representation to = instr->to(); |
| 1565 if (from.IsTagged()) { | 1570 if (from.IsTagged()) { |
| 1566 if (to.IsDouble()) { | 1571 if (to.IsDouble()) { |
| 1567 LOperand* value = UseRegister(instr->value()); | 1572 LOperand* value = UseRegister(instr->value()); |
| 1568 LInstruction* res = new LNumberUntagD(value); | 1573 LNumberUntagD* res = new LNumberUntagD(value); |
| 1569 return AssignEnvironment(DefineAsRegister(res)); | 1574 return AssignEnvironment(DefineAsRegister(res)); |
| 1570 } else { | 1575 } else { |
| 1571 ASSERT(to.IsInteger32()); | 1576 ASSERT(to.IsInteger32()); |
| 1572 LOperand* value = UseRegister(instr->value()); | 1577 LOperand* value = UseRegister(instr->value()); |
| 1573 bool needs_check = !instr->value()->type().IsSmi(); | 1578 bool needs_check = !instr->value()->type().IsSmi(); |
| 1574 if (needs_check) { | 1579 if (needs_check) { |
| 1575 LOperand* xmm_temp = | 1580 LOperand* xmm_temp = |
| 1576 (instr->CanTruncateToInt32() && CpuFeatures::IsSupported(SSE3)) | 1581 (instr->CanTruncateToInt32() && CpuFeatures::IsSupported(SSE3)) |
| 1577 ? NULL | 1582 ? NULL |
| 1578 : FixedTemp(xmm1); | 1583 : FixedTemp(xmm1); |
| 1579 LInstruction* res = new LTaggedToI(value, xmm_temp); | 1584 LTaggedToI* res = new LTaggedToI(value, xmm_temp); |
| 1580 return AssignEnvironment(DefineSameAsFirst(res)); | 1585 return AssignEnvironment(DefineSameAsFirst(res)); |
| 1581 } else { | 1586 } else { |
| 1582 return DefineSameAsFirst(new LSmiUntag(value, needs_check)); | 1587 return DefineSameAsFirst(new LSmiUntag(value, needs_check)); |
| 1583 } | 1588 } |
| 1584 } | 1589 } |
| 1585 } else if (from.IsDouble()) { | 1590 } else if (from.IsDouble()) { |
| 1586 if (to.IsTagged()) { | 1591 if (to.IsTagged()) { |
| 1587 LOperand* value = UseRegister(instr->value()); | 1592 LOperand* value = UseRegister(instr->value()); |
| 1588 LOperand* temp = TempRegister(); | 1593 LOperand* temp = TempRegister(); |
| 1589 | 1594 |
| 1590 // Make sure that temp and result_temp are different registers. | 1595 // Make sure that temp and result_temp are different registers. |
| 1591 LUnallocated* result_temp = TempRegister(); | 1596 LUnallocated* result_temp = TempRegister(); |
| 1592 LInstruction* result = new LNumberTagD(value, temp); | 1597 LNumberTagD* result = new LNumberTagD(value, temp); |
| 1593 return AssignPointerMap(Define(result, result_temp)); | 1598 return AssignPointerMap(Define(result, result_temp)); |
| 1594 } else { | 1599 } else { |
| 1595 ASSERT(to.IsInteger32()); | 1600 ASSERT(to.IsInteger32()); |
| 1596 LOperand* value = UseRegister(instr->value()); | 1601 LOperand* value = UseRegister(instr->value()); |
| 1597 return AssignEnvironment(DefineAsRegister(new LDoubleToI(value))); | 1602 return AssignEnvironment(DefineAsRegister(new LDoubleToI(value))); |
| 1598 } | 1603 } |
| 1599 } else if (from.IsInteger32()) { | 1604 } else if (from.IsInteger32()) { |
| 1600 if (to.IsTagged()) { | 1605 if (to.IsTagged()) { |
| 1601 HValue* val = instr->value(); | 1606 HValue* val = instr->value(); |
| 1602 LOperand* value = UseRegister(val); | 1607 LOperand* value = UseRegister(val); |
| 1603 if (val->HasRange() && val->range()->IsInSmiRange()) { | 1608 if (val->HasRange() && val->range()->IsInSmiRange()) { |
| 1604 return DefineSameAsFirst(new LSmiTag(value)); | 1609 return DefineSameAsFirst(new LSmiTag(value)); |
| 1605 } else { | 1610 } else { |
| 1606 LInstruction* result = new LNumberTagI(value); | 1611 LNumberTagI* result = new LNumberTagI(value); |
| 1607 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result))); | 1612 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result))); |
| 1608 } | 1613 } |
| 1609 } else { | 1614 } else { |
| 1610 ASSERT(to.IsDouble()); | 1615 ASSERT(to.IsDouble()); |
| 1611 return DefineAsRegister(new LInteger32ToDouble(Use(instr->value()))); | 1616 return DefineAsRegister(new LInteger32ToDouble(Use(instr->value()))); |
| 1612 } | 1617 } |
| 1613 } | 1618 } |
| 1614 UNREACHABLE(); | 1619 UNREACHABLE(); |
| 1615 return NULL; | 1620 return NULL; |
| 1616 } | 1621 } |
| 1617 | 1622 |
| 1618 | 1623 |
| 1619 LInstruction* LChunkBuilder::DoCheckNonSmi(HCheckNonSmi* instr) { | 1624 LInstruction* LChunkBuilder::DoCheckNonSmi(HCheckNonSmi* instr) { |
| 1620 LOperand* value = UseRegisterAtStart(instr->value()); | 1625 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1621 return AssignEnvironment(new LCheckSmi(value, zero)); | 1626 return AssignEnvironment(new LCheckSmi(value, zero)); |
| 1622 } | 1627 } |
| 1623 | 1628 |
| 1624 | 1629 |
| 1625 LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) { | 1630 LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) { |
| 1626 LOperand* value = UseRegisterAtStart(instr->value()); | 1631 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1627 LOperand* temp = TempRegister(); | 1632 LOperand* temp = TempRegister(); |
| 1628 LInstruction* result = new LCheckInstanceType(value, temp); | 1633 LCheckInstanceType* result = new LCheckInstanceType(value, temp); |
| 1629 return AssignEnvironment(result); | 1634 return AssignEnvironment(result); |
| 1630 } | 1635 } |
| 1631 | 1636 |
| 1632 | 1637 |
| 1633 LInstruction* LChunkBuilder::DoCheckPrototypeMaps(HCheckPrototypeMaps* instr) { | 1638 LInstruction* LChunkBuilder::DoCheckPrototypeMaps(HCheckPrototypeMaps* instr) { |
| 1634 LOperand* temp = TempRegister(); | 1639 LOperand* temp = TempRegister(); |
| 1635 LInstruction* result = | 1640 LCheckPrototypeMaps* result = |
| 1636 new LCheckPrototypeMaps(temp, | 1641 new LCheckPrototypeMaps(temp, |
| 1637 instr->holder(), | 1642 instr->holder(), |
| 1638 instr->receiver_map()); | 1643 instr->receiver_map()); |
| 1639 return AssignEnvironment(result); | 1644 return AssignEnvironment(result); |
| 1640 } | 1645 } |
| 1641 | 1646 |
| 1642 | 1647 |
| 1643 LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) { | 1648 LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) { |
| 1644 LOperand* value = UseRegisterAtStart(instr->value()); | 1649 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1645 return AssignEnvironment(new LCheckSmi(value, not_zero)); | 1650 return AssignEnvironment(new LCheckSmi(value, not_zero)); |
| 1646 } | 1651 } |
| 1647 | 1652 |
| 1648 | 1653 |
| 1649 LInstruction* LChunkBuilder::DoCheckFunction(HCheckFunction* instr) { | 1654 LInstruction* LChunkBuilder::DoCheckFunction(HCheckFunction* instr) { |
| 1650 LOperand* value = UseRegisterAtStart(instr->value()); | 1655 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1651 return AssignEnvironment(new LCheckFunction(value)); | 1656 return AssignEnvironment(new LCheckFunction(value)); |
| 1652 } | 1657 } |
| 1653 | 1658 |
| 1654 | 1659 |
| 1655 LInstruction* LChunkBuilder::DoCheckMap(HCheckMap* instr) { | 1660 LInstruction* LChunkBuilder::DoCheckMap(HCheckMap* instr) { |
| 1656 LOperand* value = UseRegisterAtStart(instr->value()); | 1661 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1657 LInstruction* result = new LCheckMap(value); | 1662 LCheckMap* result = new LCheckMap(value); |
| 1658 return AssignEnvironment(result); | 1663 return AssignEnvironment(result); |
| 1659 } | 1664 } |
| 1660 | 1665 |
| 1661 | 1666 |
| 1662 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) { | 1667 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) { |
| 1663 return new LReturn(UseFixed(instr->value(), eax)); | 1668 return new LReturn(UseFixed(instr->value(), eax)); |
| 1664 } | 1669 } |
| 1665 | 1670 |
| 1666 | 1671 |
| 1667 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { | 1672 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { |
| 1668 Representation r = instr->representation(); | 1673 Representation r = instr->representation(); |
| 1669 if (r.IsInteger32()) { | 1674 if (r.IsInteger32()) { |
| 1670 int32_t value = instr->Integer32Value(); | 1675 int32_t value = instr->Integer32Value(); |
| 1671 return DefineAsRegister(new LConstantI(value)); | 1676 return DefineAsRegister(new LConstantI(value)); |
| 1672 } else if (r.IsDouble()) { | 1677 } else if (r.IsDouble()) { |
| 1673 double value = instr->DoubleValue(); | 1678 double value = instr->DoubleValue(); |
| 1674 return DefineAsRegister(new LConstantD(value)); | 1679 return DefineAsRegister(new LConstantD(value)); |
| 1675 } else if (r.IsTagged()) { | 1680 } else if (r.IsTagged()) { |
| 1676 return DefineAsRegister(new LConstantT(instr->handle())); | 1681 return DefineAsRegister(new LConstantT(instr->handle())); |
| 1677 } else { | 1682 } else { |
| 1678 Abort("unsupported constant of type double"); | 1683 Abort("unsupported constant of type double"); |
| 1679 return NULL; | 1684 return NULL; |
| 1680 } | 1685 } |
| 1681 } | 1686 } |
| 1682 | 1687 |
| 1683 | 1688 |
| 1684 LInstruction* LChunkBuilder::DoLoadGlobal(HLoadGlobal* instr) { | 1689 LInstruction* LChunkBuilder::DoLoadGlobal(HLoadGlobal* instr) { |
| 1685 LInstruction* result = new LLoadGlobal; | 1690 LLoadGlobal* result = new LLoadGlobal; |
| 1686 return instr->check_hole_value() | 1691 return instr->check_hole_value() |
| 1687 ? AssignEnvironment(DefineAsRegister(result)) | 1692 ? AssignEnvironment(DefineAsRegister(result)) |
| 1688 : DefineAsRegister(result); | 1693 : DefineAsRegister(result); |
| 1689 } | 1694 } |
| 1690 | 1695 |
| 1691 | 1696 |
| 1692 LInstruction* LChunkBuilder::DoStoreGlobal(HStoreGlobal* instr) { | 1697 LInstruction* LChunkBuilder::DoStoreGlobal(HStoreGlobal* instr) { |
| 1693 return new LStoreGlobal(UseRegisterAtStart(instr->value())); | 1698 return new LStoreGlobal(UseRegisterAtStart(instr->value())); |
| 1694 } | 1699 } |
| 1695 | 1700 |
| 1696 | 1701 |
| 1697 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) { | 1702 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) { |
| 1698 return DefineAsRegister( | 1703 return DefineAsRegister( |
| 1699 new LLoadNamedField(UseRegisterAtStart(instr->object()))); | 1704 new LLoadNamedField(UseRegisterAtStart(instr->object()))); |
| 1700 } | 1705 } |
| 1701 | 1706 |
| 1702 | 1707 |
| 1703 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) { | 1708 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) { |
| 1704 LOperand* object = UseFixed(instr->object(), eax); | 1709 LOperand* object = UseFixed(instr->object(), eax); |
| 1705 LInstruction* result = DefineFixed(new LLoadNamedGeneric(object), eax); | 1710 LLoadNamedGeneric* result = new LLoadNamedGeneric(object); |
| 1706 return MarkAsCall(result, instr); | 1711 return MarkAsCall(DefineFixed(result, eax), instr); |
| 1707 } | 1712 } |
| 1708 | 1713 |
| 1709 | 1714 |
| 1710 LInstruction* LChunkBuilder::DoLoadFunctionPrototype( | 1715 LInstruction* LChunkBuilder::DoLoadFunctionPrototype( |
| 1711 HLoadFunctionPrototype* instr) { | 1716 HLoadFunctionPrototype* instr) { |
| 1712 return AssignEnvironment(DefineAsRegister( | 1717 return AssignEnvironment(DefineAsRegister( |
| 1713 new LLoadFunctionPrototype(UseRegister(instr->function()), | 1718 new LLoadFunctionPrototype(UseRegister(instr->function()), |
| 1714 TempRegister()))); | 1719 TempRegister()))); |
| 1715 } | 1720 } |
| 1716 | 1721 |
| 1717 | 1722 |
| 1718 LInstruction* LChunkBuilder::DoLoadElements(HLoadElements* instr) { | 1723 LInstruction* LChunkBuilder::DoLoadElements(HLoadElements* instr) { |
| 1719 LOperand* input = UseRegisterAtStart(instr->value()); | 1724 LOperand* input = UseRegisterAtStart(instr->value()); |
| 1720 return DefineSameAsFirst(new LLoadElements(input)); | 1725 return DefineSameAsFirst(new LLoadElements(input)); |
| 1721 } | 1726 } |
| 1722 | 1727 |
| 1723 | 1728 |
| 1724 LInstruction* LChunkBuilder::DoLoadKeyedFastElement( | 1729 LInstruction* LChunkBuilder::DoLoadKeyedFastElement( |
| 1725 HLoadKeyedFastElement* instr) { | 1730 HLoadKeyedFastElement* instr) { |
| 1726 Representation r = instr->representation(); | 1731 Representation r = instr->representation(); |
| 1727 LOperand* obj = UseRegisterAtStart(instr->object()); | 1732 LOperand* obj = UseRegisterAtStart(instr->object()); |
| 1728 ASSERT(instr->key()->representation().IsInteger32()); | 1733 ASSERT(instr->key()->representation().IsInteger32()); |
| 1729 LOperand* key = UseRegisterAtStart(instr->key()); | 1734 LOperand* key = UseRegisterAtStart(instr->key()); |
| 1730 LOperand* load_result = NULL; | 1735 LOperand* load_result = NULL; |
| 1731 // Double needs an extra temp, because the result is converted from heap | 1736 // Double needs an extra temp, because the result is converted from heap |
| 1732 // number to a double register. | 1737 // number to a double register. |
| 1733 if (r.IsDouble()) load_result = TempRegister(); | 1738 if (r.IsDouble()) load_result = TempRegister(); |
| 1734 LInstruction* result = new LLoadKeyedFastElement(obj, | 1739 LLoadKeyedFastElement* load = new LLoadKeyedFastElement(obj, |
| 1735 key, | 1740 key, |
| 1736 load_result); | 1741 load_result); |
| 1737 if (r.IsDouble()) { | 1742 LInstruction* result = r.IsDouble() |
| 1738 result = DefineAsRegister(result); | 1743 ? DefineAsRegister(load) |
| 1739 } else { | 1744 : DefineSameAsFirst(load); |
| 1740 result = DefineSameAsFirst(result); | |
| 1741 } | |
| 1742 return AssignEnvironment(result); | 1745 return AssignEnvironment(result); |
| 1743 } | 1746 } |
| 1744 | 1747 |
| 1745 | 1748 |
| 1746 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { | 1749 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { |
| 1747 LOperand* object = UseFixed(instr->object(), edx); | 1750 LOperand* object = UseFixed(instr->object(), edx); |
| 1748 LOperand* key = UseFixed(instr->key(), eax); | 1751 LOperand* key = UseFixed(instr->key(), eax); |
| 1749 | 1752 |
| 1750 LInstruction* result = | 1753 LLoadKeyedGeneric* result = new LLoadKeyedGeneric(object, key); |
| 1751 DefineFixed(new LLoadKeyedGeneric(object, key), eax); | 1754 return MarkAsCall(DefineFixed(result, eax), instr); |
| 1752 return MarkAsCall(result, instr); | |
| 1753 } | 1755 } |
| 1754 | 1756 |
| 1755 | 1757 |
| 1756 LInstruction* LChunkBuilder::DoStoreKeyedFastElement( | 1758 LInstruction* LChunkBuilder::DoStoreKeyedFastElement( |
| 1757 HStoreKeyedFastElement* instr) { | 1759 HStoreKeyedFastElement* instr) { |
| 1758 bool needs_write_barrier = instr->NeedsWriteBarrier(); | 1760 bool needs_write_barrier = instr->NeedsWriteBarrier(); |
| 1759 ASSERT(instr->value()->representation().IsTagged()); | 1761 ASSERT(instr->value()->representation().IsTagged()); |
| 1760 ASSERT(instr->object()->representation().IsTagged()); | 1762 ASSERT(instr->object()->representation().IsTagged()); |
| 1761 ASSERT(instr->key()->representation().IsInteger32()); | 1763 ASSERT(instr->key()->representation().IsInteger32()); |
| 1762 | 1764 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1809 temp, | 1811 temp, |
| 1810 needs_write_barrier, | 1812 needs_write_barrier, |
| 1811 instr->transition()); | 1813 instr->transition()); |
| 1812 } | 1814 } |
| 1813 | 1815 |
| 1814 | 1816 |
| 1815 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) { | 1817 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) { |
| 1816 LOperand* obj = UseFixed(instr->object(), edx); | 1818 LOperand* obj = UseFixed(instr->object(), edx); |
| 1817 LOperand* val = UseFixed(instr->value(), eax); | 1819 LOperand* val = UseFixed(instr->value(), eax); |
| 1818 | 1820 |
| 1819 LInstruction* result = new LStoreNamedGeneric(obj, instr->name(), val); | 1821 LStoreNamedGeneric* result = new LStoreNamedGeneric(obj, instr->name(), val); |
| 1820 return MarkAsCall(result, instr); | 1822 return MarkAsCall(result, instr); |
| 1821 } | 1823 } |
| 1822 | 1824 |
| 1823 | 1825 |
| 1824 LInstruction* LChunkBuilder::DoArrayLiteral(HArrayLiteral* instr) { | 1826 LInstruction* LChunkBuilder::DoArrayLiteral(HArrayLiteral* instr) { |
| 1825 return MarkAsCall(DefineFixed(new LArrayLiteral, eax), instr); | 1827 return MarkAsCall(DefineFixed(new LArrayLiteral, eax), instr); |
| 1826 } | 1828 } |
| 1827 | 1829 |
| 1828 | 1830 |
| 1829 LInstruction* LChunkBuilder::DoObjectLiteral(HObjectLiteral* instr) { | 1831 LInstruction* LChunkBuilder::DoObjectLiteral(HObjectLiteral* instr) { |
| 1830 return MarkAsCall(DefineFixed(new LObjectLiteral, eax), instr); | 1832 return MarkAsCall(DefineFixed(new LObjectLiteral, eax), instr); |
| 1831 } | 1833 } |
| 1832 | 1834 |
| 1833 | 1835 |
| 1834 LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) { | 1836 LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) { |
| 1835 return MarkAsCall(DefineFixed(new LRegExpLiteral, eax), instr); | 1837 return MarkAsCall(DefineFixed(new LRegExpLiteral, eax), instr); |
| 1836 } | 1838 } |
| 1837 | 1839 |
| 1838 | 1840 |
| 1839 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) { | 1841 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) { |
| 1840 return MarkAsCall(DefineFixed(new LFunctionLiteral, eax), instr); | 1842 return MarkAsCall(DefineFixed(new LFunctionLiteral, eax), instr); |
| 1841 } | 1843 } |
| 1842 | 1844 |
| 1843 | 1845 |
| 1844 LInstruction* LChunkBuilder::DoDeleteProperty(HDeleteProperty* instr) { | 1846 LInstruction* LChunkBuilder::DoDeleteProperty(HDeleteProperty* instr) { |
| 1845 LInstruction* result = new LDeleteProperty(Use(instr->object()), | 1847 LDeleteProperty* result = new LDeleteProperty(Use(instr->object()), |
| 1846 UseOrConstant(instr->key())); | 1848 UseOrConstant(instr->key())); |
| 1847 return MarkAsCall(DefineFixed(result, eax), instr); | 1849 return MarkAsCall(DefineFixed(result, eax), instr); |
| 1848 } | 1850 } |
| 1849 | 1851 |
| 1850 | 1852 |
| 1851 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) { | 1853 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) { |
| 1852 allocator_->MarkAsOsrEntry(); | 1854 allocator_->MarkAsOsrEntry(); |
| 1853 current_block_->last_environment()->set_ast_id(instr->ast_id()); | 1855 current_block_->last_environment()->set_ast_id(instr->ast_id()); |
| 1854 return AssignEnvironment(new LOsrEntry); | 1856 return AssignEnvironment(new LOsrEntry); |
| 1855 } | 1857 } |
| 1856 | 1858 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1877 // There are no real uses of the arguments object (we bail out in all other | 1879 // There are no real uses of the arguments object (we bail out in all other |
| 1878 // cases). | 1880 // cases). |
| 1879 return NULL; | 1881 return NULL; |
| 1880 } | 1882 } |
| 1881 | 1883 |
| 1882 | 1884 |
| 1883 LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) { | 1885 LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) { |
| 1884 LOperand* arguments = UseRegister(instr->arguments()); | 1886 LOperand* arguments = UseRegister(instr->arguments()); |
| 1885 LOperand* length = UseTempRegister(instr->length()); | 1887 LOperand* length = UseTempRegister(instr->length()); |
| 1886 LOperand* index = Use(instr->index()); | 1888 LOperand* index = Use(instr->index()); |
| 1887 LInstruction* result = new LAccessArgumentsAt(arguments, length, index); | 1889 LAccessArgumentsAt* result = new LAccessArgumentsAt(arguments, length, index); |
| 1888 return DefineAsRegister(AssignEnvironment(result)); | 1890 return AssignEnvironment(DefineAsRegister(result)); |
| 1889 } | 1891 } |
| 1890 | 1892 |
| 1891 | 1893 |
| 1892 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) { | 1894 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) { |
| 1893 LInstruction* result = new LTypeof(UseAtStart(instr->value())); | 1895 LTypeof* result = new LTypeof(UseAtStart(instr->value())); |
| 1894 return MarkAsCall(DefineFixed(result, eax), instr); | 1896 return MarkAsCall(DefineFixed(result, eax), instr); |
| 1895 } | 1897 } |
| 1896 | 1898 |
| 1897 | 1899 |
| 1898 LInstruction* LChunkBuilder::DoTypeofIs(HTypeofIs* instr) { | 1900 LInstruction* LChunkBuilder::DoTypeofIs(HTypeofIs* instr) { |
| 1899 return DefineSameAsFirst(new LTypeofIs(UseRegister(instr->value()))); | 1901 return DefineSameAsFirst(new LTypeofIs(UseRegister(instr->value()))); |
| 1900 } | 1902 } |
| 1901 | 1903 |
| 1902 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) { | 1904 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) { |
| 1903 HEnvironment* env = current_block_->last_environment(); | 1905 HEnvironment* env = current_block_->last_environment(); |
| 1904 ASSERT(env != NULL); | 1906 ASSERT(env != NULL); |
| 1905 | 1907 |
| 1906 env->set_ast_id(instr->ast_id()); | 1908 env->set_ast_id(instr->ast_id()); |
| 1907 | 1909 |
| 1908 env->Drop(instr->pop_count()); | 1910 env->Drop(instr->pop_count()); |
| 1909 for (int i = 0; i < instr->values()->length(); ++i) { | 1911 for (int i = 0; i < instr->values()->length(); ++i) { |
| 1910 HValue* value = instr->values()->at(i); | 1912 HValue* value = instr->values()->at(i); |
| 1911 if (instr->HasAssignedIndexAt(i)) { | 1913 if (instr->HasAssignedIndexAt(i)) { |
| 1912 env->Bind(instr->GetAssignedIndexAt(i), value); | 1914 env->Bind(instr->GetAssignedIndexAt(i), value); |
| 1913 } else { | 1915 } else { |
| 1914 env->Push(value); | 1916 env->Push(value); |
| 1915 } | 1917 } |
| 1916 } | 1918 } |
| 1917 ASSERT(env->length() == instr->environment_length()); | 1919 ASSERT(env->length() == instr->environment_length()); |
| 1918 | 1920 |
| 1919 // If there is an instruction pending deoptimization environment create a | 1921 // If there is an instruction pending deoptimization environment create a |
| 1920 // lazy bailout instruction to capture the environment. | 1922 // lazy bailout instruction to capture the environment. |
| 1921 if (pending_deoptimization_ast_id_ == instr->ast_id()) { | 1923 if (pending_deoptimization_ast_id_ == instr->ast_id()) { |
| 1922 LInstruction* result = new LLazyBailout; | 1924 LLazyBailout* lazy_bailout = new LLazyBailout; |
| 1923 result = AssignEnvironment(result); | 1925 LInstruction* result = AssignEnvironment(lazy_bailout); |
| 1924 instructions_pending_deoptimization_environment_-> | 1926 instructions_pending_deoptimization_environment_-> |
| 1925 set_deoptimization_environment(result->environment()); | 1927 set_deoptimization_environment(result->environment()); |
| 1926 ClearInstructionPendingDeoptimizationEnvironment(); | 1928 ClearInstructionPendingDeoptimizationEnvironment(); |
| 1927 return result; | 1929 return result; |
| 1928 } | 1930 } |
| 1929 | 1931 |
| 1930 return NULL; | 1932 return NULL; |
| 1931 } | 1933 } |
| 1932 | 1934 |
| 1933 | 1935 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1957 | 1959 |
| 1958 | 1960 |
| 1959 void LPointerMap::RecordPointer(LOperand* op) { | 1961 void LPointerMap::RecordPointer(LOperand* op) { |
| 1960 // Do not record arguments as pointers. | 1962 // Do not record arguments as pointers. |
| 1961 if (op->IsStackSlot() && op->index() < 0) return; | 1963 if (op->IsStackSlot() && op->index() < 0) return; |
| 1962 ASSERT(!op->IsDoubleRegister() && !op->IsDoubleStackSlot()); | 1964 ASSERT(!op->IsDoubleRegister() && !op->IsDoubleStackSlot()); |
| 1963 pointer_operands_.Add(op); | 1965 pointer_operands_.Add(op); |
| 1964 } | 1966 } |
| 1965 | 1967 |
| 1966 | 1968 |
| 1967 void LPointerMap::PrintTo(StringStream* stream) const { | 1969 void LPointerMap::PrintTo(StringStream* stream) { |
| 1968 stream->Add("{"); | 1970 stream->Add("{"); |
| 1969 for (int i = 0; i < pointer_operands_.length(); ++i) { | 1971 for (int i = 0; i < pointer_operands_.length(); ++i) { |
| 1970 if (i != 0) stream->Add(";"); | 1972 if (i != 0) stream->Add(";"); |
| 1971 pointer_operands_[i]->PrintTo(stream); | 1973 pointer_operands_[i]->PrintTo(stream); |
| 1972 } | 1974 } |
| 1973 stream->Add("} @%d", position()); | 1975 stream->Add("} @%d", position()); |
| 1974 } | 1976 } |
| 1975 | 1977 |
| 1976 } } // namespace v8::internal | 1978 } } // namespace v8::internal |
| OLD | NEW |