| 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 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 289 InputAt(0)->PrintTo(stream); | 289 InputAt(0)->PrintTo(stream); |
| 290 } | 290 } |
| 291 | 291 |
| 292 | 292 |
| 293 void LLoadContextSlot::PrintDataTo(StringStream* stream) { | 293 void LLoadContextSlot::PrintDataTo(StringStream* stream) { |
| 294 InputAt(0)->PrintTo(stream); | 294 InputAt(0)->PrintTo(stream); |
| 295 stream->Add("[%d]", slot_index()); | 295 stream->Add("[%d]", slot_index()); |
| 296 } | 296 } |
| 297 | 297 |
| 298 | 298 |
| 299 void LStoreContextSlot::PrintDataTo(StringStream* stream) { |
| 300 InputAt(0)->PrintTo(stream); |
| 301 stream->Add("[%d] <- ", slot_index()); |
| 302 InputAt(1)->PrintTo(stream); |
| 303 } |
| 304 |
| 305 |
| 299 void LCallKeyed::PrintDataTo(StringStream* stream) { | 306 void LCallKeyed::PrintDataTo(StringStream* stream) { |
| 300 stream->Add("[ecx] #%d / ", arity()); | 307 stream->Add("[rcx] #%d / ", arity()); |
| 301 } | 308 } |
| 302 | 309 |
| 303 | 310 |
| 304 void LCallNamed::PrintDataTo(StringStream* stream) { | 311 void LCallNamed::PrintDataTo(StringStream* stream) { |
| 305 SmartPointer<char> name_string = name()->ToCString(); | 312 SmartPointer<char> name_string = name()->ToCString(); |
| 306 stream->Add("%s #%d / ", *name_string, arity()); | 313 stream->Add("%s #%d / ", *name_string, arity()); |
| 307 } | 314 } |
| 308 | 315 |
| 309 | 316 |
| 310 void LCallGlobal::PrintDataTo(StringStream* stream) { | 317 void LCallGlobal::PrintDataTo(StringStream* stream) { |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 391 | 398 |
| 392 if (can_eliminate) { | 399 if (can_eliminate) { |
| 393 label->set_replacement(GetLabel(goto_instr->block_id())); | 400 label->set_replacement(GetLabel(goto_instr->block_id())); |
| 394 } | 401 } |
| 395 } | 402 } |
| 396 } | 403 } |
| 397 } | 404 } |
| 398 } | 405 } |
| 399 | 406 |
| 400 | 407 |
| 401 void LStoreNamed::PrintDataTo(StringStream* stream) { | 408 void LStoreNamedField::PrintDataTo(StringStream* stream) { |
| 402 object()->PrintTo(stream); | 409 object()->PrintTo(stream); |
| 403 stream->Add("."); | 410 stream->Add("."); |
| 404 stream->Add(*String::cast(*name())->ToCString()); | 411 stream->Add(*String::cast(*name())->ToCString()); |
| 405 stream->Add(" <- "); | 412 stream->Add(" <- "); |
| 406 value()->PrintTo(stream); | 413 value()->PrintTo(stream); |
| 407 } | 414 } |
| 408 | 415 |
| 409 | 416 |
| 410 void LStoreKeyed::PrintDataTo(StringStream* stream) { | 417 void LStoreNamedGeneric::PrintDataTo(StringStream* stream) { |
| 418 object()->PrintTo(stream); |
| 419 stream->Add("."); |
| 420 stream->Add(*String::cast(*name())->ToCString()); |
| 421 stream->Add(" <- "); |
| 422 value()->PrintTo(stream); |
| 423 } |
| 424 |
| 425 |
| 426 void LStoreKeyedFastElement::PrintDataTo(StringStream* stream) { |
| 411 object()->PrintTo(stream); | 427 object()->PrintTo(stream); |
| 412 stream->Add("["); | 428 stream->Add("["); |
| 413 key()->PrintTo(stream); | 429 key()->PrintTo(stream); |
| 414 stream->Add("] <- "); | 430 stream->Add("] <- "); |
| 415 value()->PrintTo(stream); | 431 value()->PrintTo(stream); |
| 416 } | 432 } |
| 417 | 433 |
| 418 | 434 |
| 435 void LStoreKeyedGeneric::PrintDataTo(StringStream* stream) { |
| 436 object()->PrintTo(stream); |
| 437 stream->Add("["); |
| 438 key()->PrintTo(stream); |
| 439 stream->Add("] <- "); |
| 440 value()->PrintTo(stream); |
| 441 } |
| 442 |
| 443 |
| 419 void LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) { | 444 void LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) { |
| 420 LGap* gap = new LGap(block); | 445 LGap* gap = new LGap(block); |
| 421 int index = -1; | 446 int index = -1; |
| 422 if (instr->IsControl()) { | 447 if (instr->IsControl()) { |
| 423 instructions_.Add(gap); | 448 instructions_.Add(gap); |
| 424 index = instructions_.length(); | 449 index = instructions_.length(); |
| 425 instructions_.Add(instr); | 450 instructions_.Add(instr); |
| 426 } else { | 451 } else { |
| 427 index = instructions_.length(); | 452 index = instructions_.length(); |
| 428 instructions_.Add(instr); | 453 instructions_.Add(instr); |
| 429 instructions_.Add(gap); | 454 instructions_.Add(gap); |
| 430 } | 455 } |
| 431 if (instr->HasPointerMap()) { | 456 if (instr->HasPointerMap()) { |
| 432 pointer_maps_.Add(instr->pointer_map()); | 457 pointer_maps_.Add(instr->pointer_map()); |
| 433 instr->pointer_map()->set_lithium_position(index); | 458 instr->pointer_map()->set_lithium_position(index); |
| 434 } | 459 } |
| 435 } | 460 } |
| 436 | 461 |
| 437 | 462 |
| 438 LConstantOperand* LChunk::DefineConstantOperand(HConstant* constant) { | 463 LConstantOperand* LChunk::DefineConstantOperand(HConstant* constant) { |
| 439 return LConstantOperand::Create(constant->id()); | 464 return LConstantOperand::Create(constant->id()); |
| 440 } | 465 } |
| 441 | 466 |
| 442 | 467 |
| 443 int LChunk::GetParameterStackSlot(int index) const { | 468 int LChunk::GetParameterStackSlot(int index) const { |
| 444 // The receiver is at index 0, the first parameter at index 1, so we | 469 // The receiver is at index 0, the first parameter at index 1, so we |
| 445 // shift all parameter indexes down by the number of parameters, and | 470 // shift all parameter indexes down by the number of parameters, and |
| 446 // make sure they end up negative so they are distinguishable from | 471 // make sure they end up negative so they are distinguishable from |
| 447 // spill slots. | 472 // spill slots. |
| 448 int result = index - graph()->info()->scope()->num_parameters() - 1; | 473 int result = index - info()->scope()->num_parameters() - 1; |
| 449 ASSERT(result < 0); | 474 ASSERT(result < 0); |
| 450 return result; | 475 return result; |
| 451 } | 476 } |
| 452 | 477 |
| 453 // A parameter relative to ebp in the arguments stub. | 478 // A parameter relative to ebp in the arguments stub. |
| 454 int LChunk::ParameterAt(int index) { | 479 int LChunk::ParameterAt(int index) { |
| 455 ASSERT(-1 <= index); // -1 is the receiver. | 480 ASSERT(-1 <= index); // -1 is the receiver. |
| 456 return (1 + graph()->info()->scope()->num_parameters() - index) * | 481 return (1 + info()->scope()->num_parameters() - index) * |
| 457 kPointerSize; | 482 kPointerSize; |
| 458 } | 483 } |
| 459 | 484 |
| 460 | 485 |
| 461 LGap* LChunk::GetGapAt(int index) const { | 486 LGap* LChunk::GetGapAt(int index) const { |
| 462 return LGap::cast(instructions_[index]); | 487 return LGap::cast(instructions_[index]); |
| 463 } | 488 } |
| 464 | 489 |
| 465 | 490 |
| 466 bool LChunk::IsGapAt(int index) const { | 491 bool LChunk::IsGapAt(int index) const { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 485 | 510 |
| 486 | 511 |
| 487 Representation LChunk::LookupLiteralRepresentation( | 512 Representation LChunk::LookupLiteralRepresentation( |
| 488 LConstantOperand* operand) const { | 513 LConstantOperand* operand) const { |
| 489 return graph_->LookupValue(operand->index())->representation(); | 514 return graph_->LookupValue(operand->index())->representation(); |
| 490 } | 515 } |
| 491 | 516 |
| 492 | 517 |
| 493 LChunk* LChunkBuilder::Build() { | 518 LChunk* LChunkBuilder::Build() { |
| 494 ASSERT(is_unused()); | 519 ASSERT(is_unused()); |
| 495 chunk_ = new LChunk(graph()); | 520 chunk_ = new LChunk(info(), graph()); |
| 496 HPhase phase("Building chunk", chunk_); | 521 HPhase phase("Building chunk", chunk_); |
| 497 status_ = BUILDING; | 522 status_ = BUILDING; |
| 498 const ZoneList<HBasicBlock*>* blocks = graph()->blocks(); | 523 const ZoneList<HBasicBlock*>* blocks = graph()->blocks(); |
| 499 for (int i = 0; i < blocks->length(); i++) { | 524 for (int i = 0; i < blocks->length(); i++) { |
| 500 HBasicBlock* next = NULL; | 525 HBasicBlock* next = NULL; |
| 501 if (i < blocks->length() - 1) next = blocks->at(i + 1); | 526 if (i < blocks->length() - 1) next = blocks->at(i + 1); |
| 502 DoBasicBlock(blocks->at(i), next); | 527 DoBasicBlock(blocks->at(i), next); |
| 503 if (is_aborted()) return NULL; | 528 if (is_aborted()) return NULL; |
| 504 } | 529 } |
| 505 status_ = DONE; | 530 status_ = DONE; |
| 506 return chunk_; | 531 return chunk_; |
| 507 } | 532 } |
| 508 | 533 |
| 509 | 534 |
| 510 void LChunkBuilder::Abort(const char* format, ...) { | 535 void LChunkBuilder::Abort(const char* format, ...) { |
| 511 if (FLAG_trace_bailout) { | 536 if (FLAG_trace_bailout) { |
| 512 SmartPointer<char> debug_name = graph()->debug_name()->ToCString(); | 537 SmartPointer<char> name(info()->shared_info()->DebugName()->ToCString()); |
| 513 PrintF("Aborting LChunk building in @\"%s\": ", *debug_name); | 538 PrintF("Aborting LChunk building in @\"%s\": ", *name); |
| 514 va_list arguments; | 539 va_list arguments; |
| 515 va_start(arguments, format); | 540 va_start(arguments, format); |
| 516 OS::VPrint(format, arguments); | 541 OS::VPrint(format, arguments); |
| 517 va_end(arguments); | 542 va_end(arguments); |
| 518 PrintF("\n"); | 543 PrintF("\n"); |
| 519 } | 544 } |
| 520 status_ = ABORTED; | 545 status_ = ABORTED; |
| 521 } | 546 } |
| 522 | 547 |
| 523 | 548 |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 839 ? AssignEnvironment(DefineSameAsFirst(result)) | 864 ? AssignEnvironment(DefineSameAsFirst(result)) |
| 840 : DefineSameAsFirst(result); | 865 : DefineSameAsFirst(result); |
| 841 } | 866 } |
| 842 | 867 |
| 843 | 868 |
| 844 LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op, | 869 LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op, |
| 845 HArithmeticBinaryOperation* instr) { | 870 HArithmeticBinaryOperation* instr) { |
| 846 ASSERT(instr->representation().IsDouble()); | 871 ASSERT(instr->representation().IsDouble()); |
| 847 ASSERT(instr->left()->representation().IsDouble()); | 872 ASSERT(instr->left()->representation().IsDouble()); |
| 848 ASSERT(instr->right()->representation().IsDouble()); | 873 ASSERT(instr->right()->representation().IsDouble()); |
| 849 if (op == Token::MOD) { | 874 ASSERT(op != Token::MOD); |
| 850 Abort("Unimplemented: %s", "DoArithmeticD MOD"); | |
| 851 } | |
| 852 LOperand* left = UseRegisterAtStart(instr->left()); | 875 LOperand* left = UseRegisterAtStart(instr->left()); |
| 853 LOperand* right = UseRegisterAtStart(instr->right()); | 876 LOperand* right = UseRegisterAtStart(instr->right()); |
| 854 LArithmeticD* result = new LArithmeticD(op, left, right); | 877 LArithmeticD* result = new LArithmeticD(op, left, right); |
| 855 return DefineSameAsFirst(result); | 878 return DefineSameAsFirst(result); |
| 856 } | 879 } |
| 857 | 880 |
| 858 | 881 |
| 859 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, | 882 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, |
| 860 HArithmeticBinaryOperation* instr) { | 883 HArithmeticBinaryOperation* instr) { |
| 861 ASSERT(op == Token::ADD || | 884 ASSERT(op == Token::ADD || |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1074 HIsObject* compare = HIsObject::cast(v); | 1097 HIsObject* compare = HIsObject::cast(v); |
| 1075 ASSERT(compare->value()->representation().IsTagged()); | 1098 ASSERT(compare->value()->representation().IsTagged()); |
| 1076 return new LIsObjectAndBranch(UseRegisterAtStart(compare->value())); | 1099 return new LIsObjectAndBranch(UseRegisterAtStart(compare->value())); |
| 1077 } else if (v->IsCompareJSObjectEq()) { | 1100 } else if (v->IsCompareJSObjectEq()) { |
| 1078 HCompareJSObjectEq* compare = HCompareJSObjectEq::cast(v); | 1101 HCompareJSObjectEq* compare = HCompareJSObjectEq::cast(v); |
| 1079 return new LCmpJSObjectEqAndBranch(UseRegisterAtStart(compare->left()), | 1102 return new LCmpJSObjectEqAndBranch(UseRegisterAtStart(compare->left()), |
| 1080 UseRegisterAtStart(compare->right())); | 1103 UseRegisterAtStart(compare->right())); |
| 1081 } else if (v->IsInstanceOf()) { | 1104 } else if (v->IsInstanceOf()) { |
| 1082 HInstanceOf* instance_of = HInstanceOf::cast(v); | 1105 HInstanceOf* instance_of = HInstanceOf::cast(v); |
| 1083 LInstanceOfAndBranch* result = | 1106 LInstanceOfAndBranch* result = |
| 1084 new LInstanceOfAndBranch( | 1107 new LInstanceOfAndBranch(UseFixed(instance_of->left(), rax), |
| 1085 UseFixed(instance_of->left(), InstanceofStub::left()), | 1108 UseFixed(instance_of->right(), rdx)); |
| 1086 UseFixed(instance_of->right(), InstanceofStub::right())); | |
| 1087 return MarkAsCall(result, instr); | 1109 return MarkAsCall(result, instr); |
| 1088 } else if (v->IsTypeofIs()) { | 1110 } else if (v->IsTypeofIs()) { |
| 1089 HTypeofIs* typeof_is = HTypeofIs::cast(v); | 1111 HTypeofIs* typeof_is = HTypeofIs::cast(v); |
| 1090 return new LTypeofIsAndBranch(UseTempRegister(typeof_is->value())); | 1112 return new LTypeofIsAndBranch(UseTempRegister(typeof_is->value())); |
| 1091 } else if (v->IsIsConstructCall()) { | 1113 } else if (v->IsIsConstructCall()) { |
| 1092 return new LIsConstructCallAndBranch(TempRegister()); | 1114 return new LIsConstructCallAndBranch(TempRegister()); |
| 1093 } else { | 1115 } else { |
| 1094 if (v->IsConstant()) { | 1116 if (v->IsConstant()) { |
| 1095 if (HConstant::cast(v)->handle()->IsTrue()) { | 1117 if (HConstant::cast(v)->handle()->IsTrue()) { |
| 1096 return new LGoto(instr->FirstSuccessor()->block_id()); | 1118 return new LGoto(instr->FirstSuccessor()->block_id()); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1117 return DefineAsRegister(new LArgumentsLength(Use(length->value()))); | 1139 return DefineAsRegister(new LArgumentsLength(Use(length->value()))); |
| 1118 } | 1140 } |
| 1119 | 1141 |
| 1120 | 1142 |
| 1121 LInstruction* LChunkBuilder::DoArgumentsElements(HArgumentsElements* elems) { | 1143 LInstruction* LChunkBuilder::DoArgumentsElements(HArgumentsElements* elems) { |
| 1122 return DefineAsRegister(new LArgumentsElements); | 1144 return DefineAsRegister(new LArgumentsElements); |
| 1123 } | 1145 } |
| 1124 | 1146 |
| 1125 | 1147 |
| 1126 LInstruction* LChunkBuilder::DoInstanceOf(HInstanceOf* instr) { | 1148 LInstruction* LChunkBuilder::DoInstanceOf(HInstanceOf* instr) { |
| 1127 Abort("Unimplemented: %s", "DoInstanceOf"); | 1149 LOperand* left = UseFixed(instr->left(), rax); |
| 1128 return NULL; | 1150 LOperand* right = UseFixed(instr->right(), rdx); |
| 1151 LInstanceOf* result = new LInstanceOf(left, right); |
| 1152 return MarkAsCall(DefineFixed(result, rax), instr); |
| 1129 } | 1153 } |
| 1130 | 1154 |
| 1131 | 1155 |
| 1132 LInstruction* LChunkBuilder::DoInstanceOfKnownGlobal( | 1156 LInstruction* LChunkBuilder::DoInstanceOfKnownGlobal( |
| 1133 HInstanceOfKnownGlobal* instr) { | 1157 HInstanceOfKnownGlobal* instr) { |
| 1134 Abort("Unimplemented: %s", "DoInstanceOfKnownGlobal"); | 1158 LInstanceOfKnownGlobal* result = |
| 1135 return NULL; | 1159 new LInstanceOfKnownGlobal(UseFixed(instr->value(), rax), |
| 1160 FixedTemp(rdi)); |
| 1161 return MarkAsCall(DefineFixed(result, rax), instr); |
| 1136 } | 1162 } |
| 1137 | 1163 |
| 1138 | 1164 |
| 1139 LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) { | 1165 LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) { |
| 1140 Abort("Unimplemented: %s", "DoApplyArguments"); | 1166 LOperand* function = UseFixed(instr->function(), rdi); |
| 1141 return NULL; | 1167 LOperand* receiver = UseFixed(instr->receiver(), rax); |
| 1168 LOperand* length = UseFixed(instr->length(), rbx); |
| 1169 LOperand* elements = UseFixed(instr->elements(), rcx); |
| 1170 LApplyArguments* result = new LApplyArguments(function, |
| 1171 receiver, |
| 1172 length, |
| 1173 elements); |
| 1174 return MarkAsCall(DefineFixed(result, rax), instr, CAN_DEOPTIMIZE_EAGERLY); |
| 1142 } | 1175 } |
| 1143 | 1176 |
| 1144 | 1177 |
| 1145 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) { | 1178 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) { |
| 1146 ++argument_count_; | 1179 ++argument_count_; |
| 1147 LOperand* argument = UseOrConstant(instr->argument()); | 1180 LOperand* argument = UseOrConstant(instr->argument()); |
| 1148 return new LPushArgument(argument); | 1181 return new LPushArgument(argument); |
| 1149 } | 1182 } |
| 1150 | 1183 |
| 1151 | 1184 |
| 1152 LInstruction* LChunkBuilder::DoContext(HContext* instr) { | 1185 LInstruction* LChunkBuilder::DoContext(HContext* instr) { |
| 1153 return DefineAsRegister(new LContext); | 1186 return DefineAsRegister(new LContext); |
| 1154 } | 1187 } |
| 1155 | 1188 |
| 1156 | 1189 |
| 1157 LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) { | 1190 LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) { |
| 1158 Abort("Unimplemented: DoOuterContext"); | 1191 LOperand* context = UseRegisterAtStart(instr->value()); |
| 1159 return NULL; | 1192 return DefineAsRegister(new LOuterContext(context)); |
| 1160 } | 1193 } |
| 1161 | 1194 |
| 1162 | 1195 |
| 1163 LInstruction* LChunkBuilder::DoGlobalObject(HGlobalObject* instr) { | 1196 LInstruction* LChunkBuilder::DoGlobalObject(HGlobalObject* instr) { |
| 1164 return DefineAsRegister(new LGlobalObject); | 1197 return DefineAsRegister(new LGlobalObject); |
| 1165 } | 1198 } |
| 1166 | 1199 |
| 1167 | 1200 |
| 1168 LInstruction* LChunkBuilder::DoGlobalReceiver(HGlobalReceiver* instr) { | 1201 LInstruction* LChunkBuilder::DoGlobalReceiver(HGlobalReceiver* instr) { |
| 1169 return DefineAsRegister(new LGlobalReceiver); | 1202 return DefineAsRegister(new LGlobalReceiver); |
| 1170 } | 1203 } |
| 1171 | 1204 |
| 1172 | 1205 |
| 1173 LInstruction* LChunkBuilder::DoCallConstantFunction( | 1206 LInstruction* LChunkBuilder::DoCallConstantFunction( |
| 1174 HCallConstantFunction* instr) { | 1207 HCallConstantFunction* instr) { |
| 1175 argument_count_ -= instr->argument_count(); | 1208 argument_count_ -= instr->argument_count(); |
| 1176 return MarkAsCall(DefineFixed(new LCallConstantFunction, rax), instr); | 1209 return MarkAsCall(DefineFixed(new LCallConstantFunction, rax), instr); |
| 1177 } | 1210 } |
| 1178 | 1211 |
| 1179 | 1212 |
| 1180 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { | 1213 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { |
| 1181 Abort("Unimplemented: %s", "DoUnaryMathOperation"); | 1214 BuiltinFunctionId op = instr->op(); |
| 1182 return NULL; | 1215 if (op == kMathLog || op == kMathSin || op == kMathCos) { |
| 1216 LOperand* input = UseFixedDouble(instr->value(), xmm1); |
| 1217 LUnaryMathOperation* result = new LUnaryMathOperation(input); |
| 1218 return MarkAsCall(DefineFixedDouble(result, xmm1), instr); |
| 1219 } else { |
| 1220 LOperand* input = UseRegisterAtStart(instr->value()); |
| 1221 LUnaryMathOperation* result = new LUnaryMathOperation(input); |
| 1222 switch (op) { |
| 1223 case kMathAbs: |
| 1224 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result))); |
| 1225 case kMathFloor: |
| 1226 return AssignEnvironment(DefineAsRegister(result)); |
| 1227 case kMathRound: |
| 1228 return AssignEnvironment(DefineAsRegister(result)); |
| 1229 case kMathSqrt: |
| 1230 return DefineSameAsFirst(result); |
| 1231 case kMathPowHalf: |
| 1232 return DefineSameAsFirst(result); |
| 1233 default: |
| 1234 UNREACHABLE(); |
| 1235 return NULL; |
| 1236 } |
| 1237 } |
| 1183 } | 1238 } |
| 1184 | 1239 |
| 1185 | 1240 |
| 1186 LInstruction* LChunkBuilder::DoCallKeyed(HCallKeyed* instr) { | 1241 LInstruction* LChunkBuilder::DoCallKeyed(HCallKeyed* instr) { |
| 1187 Abort("Unimplemented: %s", "DoCallKeyed"); | 1242 ASSERT(instr->key()->representation().IsTagged()); |
| 1188 return NULL; | 1243 LOperand* key = UseFixed(instr->key(), rcx); |
| 1244 argument_count_ -= instr->argument_count(); |
| 1245 LCallKeyed* result = new LCallKeyed(key); |
| 1246 return MarkAsCall(DefineFixed(result, rax), instr); |
| 1189 } | 1247 } |
| 1190 | 1248 |
| 1191 | 1249 |
| 1192 LInstruction* LChunkBuilder::DoCallNamed(HCallNamed* instr) { | 1250 LInstruction* LChunkBuilder::DoCallNamed(HCallNamed* instr) { |
| 1193 argument_count_ -= instr->argument_count(); | 1251 argument_count_ -= instr->argument_count(); |
| 1194 return MarkAsCall(DefineFixed(new LCallNamed, rax), instr); | 1252 return MarkAsCall(DefineFixed(new LCallNamed, rax), instr); |
| 1195 } | 1253 } |
| 1196 | 1254 |
| 1197 | 1255 |
| 1198 LInstruction* LChunkBuilder::DoCallGlobal(HCallGlobal* instr) { | 1256 LInstruction* LChunkBuilder::DoCallGlobal(HCallGlobal* instr) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1209 | 1267 |
| 1210 LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) { | 1268 LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) { |
| 1211 LOperand* constructor = UseFixed(instr->constructor(), rdi); | 1269 LOperand* constructor = UseFixed(instr->constructor(), rdi); |
| 1212 argument_count_ -= instr->argument_count(); | 1270 argument_count_ -= instr->argument_count(); |
| 1213 LCallNew* result = new LCallNew(constructor); | 1271 LCallNew* result = new LCallNew(constructor); |
| 1214 return MarkAsCall(DefineFixed(result, rax), instr); | 1272 return MarkAsCall(DefineFixed(result, rax), instr); |
| 1215 } | 1273 } |
| 1216 | 1274 |
| 1217 | 1275 |
| 1218 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) { | 1276 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) { |
| 1219 Abort("Unimplemented: %s", "DoCallFunction"); | 1277 argument_count_ -= instr->argument_count(); |
| 1220 return NULL; | 1278 LCallFunction* result = new LCallFunction(); |
| 1279 return MarkAsCall(DefineFixed(result, rax), instr); |
| 1221 } | 1280 } |
| 1222 | 1281 |
| 1223 | 1282 |
| 1224 LInstruction* LChunkBuilder::DoCallRuntime(HCallRuntime* instr) { | 1283 LInstruction* LChunkBuilder::DoCallRuntime(HCallRuntime* instr) { |
| 1225 argument_count_ -= instr->argument_count(); | 1284 argument_count_ -= instr->argument_count(); |
| 1226 return MarkAsCall(DefineFixed(new LCallRuntime, rax), instr); | 1285 return MarkAsCall(DefineFixed(new LCallRuntime, rax), instr); |
| 1227 } | 1286 } |
| 1228 | 1287 |
| 1229 | 1288 |
| 1230 LInstruction* LChunkBuilder::DoShr(HShr* instr) { | 1289 LInstruction* LChunkBuilder::DoShr(HShr* instr) { |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1278 LDivI* result = new LDivI(dividend, divisor, temp); | 1337 LDivI* result = new LDivI(dividend, divisor, temp); |
| 1279 return AssignEnvironment(DefineFixed(result, rax)); | 1338 return AssignEnvironment(DefineFixed(result, rax)); |
| 1280 } else { | 1339 } else { |
| 1281 ASSERT(instr->representation().IsTagged()); | 1340 ASSERT(instr->representation().IsTagged()); |
| 1282 return DoArithmeticT(Token::DIV, instr); | 1341 return DoArithmeticT(Token::DIV, instr); |
| 1283 } | 1342 } |
| 1284 } | 1343 } |
| 1285 | 1344 |
| 1286 | 1345 |
| 1287 LInstruction* LChunkBuilder::DoMod(HMod* instr) { | 1346 LInstruction* LChunkBuilder::DoMod(HMod* instr) { |
| 1288 Abort("Unimplemented: %s", "DoMod"); | 1347 if (instr->representation().IsInteger32()) { |
| 1289 return NULL; | 1348 ASSERT(instr->left()->representation().IsInteger32()); |
| 1349 ASSERT(instr->right()->representation().IsInteger32()); |
| 1350 |
| 1351 LInstruction* result; |
| 1352 if (instr->HasPowerOf2Divisor()) { |
| 1353 ASSERT(!instr->CheckFlag(HValue::kCanBeDivByZero)); |
| 1354 LOperand* value = UseRegisterAtStart(instr->left()); |
| 1355 LModI* mod = new LModI(value, UseOrConstant(instr->right()), NULL); |
| 1356 result = DefineSameAsFirst(mod); |
| 1357 } else { |
| 1358 // The temporary operand is necessary to ensure that right is not |
| 1359 // allocated into edx. |
| 1360 LOperand* temp = FixedTemp(rdx); |
| 1361 LOperand* value = UseFixed(instr->left(), rax); |
| 1362 LOperand* divisor = UseRegister(instr->right()); |
| 1363 LModI* mod = new LModI(value, divisor, temp); |
| 1364 result = DefineFixed(mod, rdx); |
| 1365 } |
| 1366 |
| 1367 return (instr->CheckFlag(HValue::kBailoutOnMinusZero) || |
| 1368 instr->CheckFlag(HValue::kCanBeDivByZero)) |
| 1369 ? AssignEnvironment(result) |
| 1370 : result; |
| 1371 } else if (instr->representation().IsTagged()) { |
| 1372 return DoArithmeticT(Token::MOD, instr); |
| 1373 } else { |
| 1374 ASSERT(instr->representation().IsDouble()); |
| 1375 // We call a C function for double modulo. It can't trigger a GC. |
| 1376 // We need to use fixed result register for the call. |
| 1377 // TODO(fschneider): Allow any register as input registers. |
| 1378 LOperand* left = UseFixedDouble(instr->left(), xmm2); |
| 1379 LOperand* right = UseFixedDouble(instr->right(), xmm1); |
| 1380 LArithmeticD* result = new LArithmeticD(Token::MOD, left, right); |
| 1381 return MarkAsCall(DefineFixedDouble(result, xmm1), instr); |
| 1382 } |
| 1290 } | 1383 } |
| 1291 | 1384 |
| 1292 | 1385 |
| 1293 LInstruction* LChunkBuilder::DoMul(HMul* instr) { | 1386 LInstruction* LChunkBuilder::DoMul(HMul* instr) { |
| 1294 if (instr->representation().IsInteger32()) { | 1387 if (instr->representation().IsInteger32()) { |
| 1295 ASSERT(instr->left()->representation().IsInteger32()); | 1388 ASSERT(instr->left()->representation().IsInteger32()); |
| 1296 ASSERT(instr->right()->representation().IsInteger32()); | 1389 ASSERT(instr->right()->representation().IsInteger32()); |
| 1297 LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand()); | 1390 LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand()); |
| 1298 LOperand* right = UseOrConstant(instr->MostConstantOperand()); | 1391 LOperand* right = UseOrConstant(instr->MostConstantOperand()); |
| 1299 LMulI* mul = new LMulI(left, right); | 1392 LMulI* mul = new LMulI(left, right); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1344 return DoArithmeticD(Token::ADD, instr); | 1437 return DoArithmeticD(Token::ADD, instr); |
| 1345 } else { | 1438 } else { |
| 1346 ASSERT(instr->representation().IsTagged()); | 1439 ASSERT(instr->representation().IsTagged()); |
| 1347 return DoArithmeticT(Token::ADD, instr); | 1440 return DoArithmeticT(Token::ADD, instr); |
| 1348 } | 1441 } |
| 1349 return NULL; | 1442 return NULL; |
| 1350 } | 1443 } |
| 1351 | 1444 |
| 1352 | 1445 |
| 1353 LInstruction* LChunkBuilder::DoPower(HPower* instr) { | 1446 LInstruction* LChunkBuilder::DoPower(HPower* instr) { |
| 1354 Abort("Unimplemented: %s", "DoPower"); | 1447 ASSERT(instr->representation().IsDouble()); |
| 1355 return NULL; | 1448 // We call a C function for double power. It can't trigger a GC. |
| 1449 // We need to use fixed result register for the call. |
| 1450 Representation exponent_type = instr->right()->representation(); |
| 1451 ASSERT(instr->left()->representation().IsDouble()); |
| 1452 LOperand* left = UseFixedDouble(instr->left(), xmm2); |
| 1453 LOperand* right = exponent_type.IsDouble() ? |
| 1454 UseFixedDouble(instr->right(), xmm1) : |
| 1455 #ifdef _WIN64 |
| 1456 UseFixed(instr->right(), rdx); |
| 1457 #else |
| 1458 UseFixed(instr->right(), rdi); |
| 1459 #endif |
| 1460 LPower* result = new LPower(left, right); |
| 1461 return MarkAsCall(DefineFixedDouble(result, xmm1), instr, |
| 1462 CAN_DEOPTIMIZE_EAGERLY); |
| 1356 } | 1463 } |
| 1357 | 1464 |
| 1358 | 1465 |
| 1359 LInstruction* LChunkBuilder::DoCompare(HCompare* instr) { | 1466 LInstruction* LChunkBuilder::DoCompare(HCompare* instr) { |
| 1360 Token::Value op = instr->token(); | 1467 Token::Value op = instr->token(); |
| 1361 Representation r = instr->GetInputRepresentation(); | 1468 Representation r = instr->GetInputRepresentation(); |
| 1362 if (r.IsInteger32()) { | 1469 if (r.IsInteger32()) { |
| 1363 ASSERT(instr->left()->representation().IsInteger32()); | 1470 ASSERT(instr->left()->representation().IsInteger32()); |
| 1364 ASSERT(instr->right()->representation().IsInteger32()); | 1471 ASSERT(instr->right()->representation().IsInteger32()); |
| 1365 LOperand* left = UseRegisterAtStart(instr->left()); | 1472 LOperand* left = UseRegisterAtStart(instr->left()); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1410 | 1517 |
| 1411 LInstruction* LChunkBuilder::DoIsSmi(HIsSmi* instr) { | 1518 LInstruction* LChunkBuilder::DoIsSmi(HIsSmi* instr) { |
| 1412 ASSERT(instr->value()->representation().IsTagged()); | 1519 ASSERT(instr->value()->representation().IsTagged()); |
| 1413 LOperand* value = UseAtStart(instr->value()); | 1520 LOperand* value = UseAtStart(instr->value()); |
| 1414 | 1521 |
| 1415 return DefineAsRegister(new LIsSmi(value)); | 1522 return DefineAsRegister(new LIsSmi(value)); |
| 1416 } | 1523 } |
| 1417 | 1524 |
| 1418 | 1525 |
| 1419 LInstruction* LChunkBuilder::DoHasInstanceType(HHasInstanceType* instr) { | 1526 LInstruction* LChunkBuilder::DoHasInstanceType(HHasInstanceType* instr) { |
| 1420 Abort("Unimplemented: %s", "DoHasInstanceType"); | 1527 ASSERT(instr->value()->representation().IsTagged()); |
| 1421 return NULL; | 1528 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1529 |
| 1530 return DefineAsRegister(new LHasInstanceType(value)); |
| 1531 } |
| 1532 |
| 1533 |
| 1534 LInstruction* LChunkBuilder::DoGetCachedArrayIndex( |
| 1535 HGetCachedArrayIndex* instr) { |
| 1536 ASSERT(instr->value()->representation().IsTagged()); |
| 1537 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1538 |
| 1539 return DefineAsRegister(new LGetCachedArrayIndex(value)); |
| 1422 } | 1540 } |
| 1423 | 1541 |
| 1424 | 1542 |
| 1425 LInstruction* LChunkBuilder::DoHasCachedArrayIndex( | 1543 LInstruction* LChunkBuilder::DoHasCachedArrayIndex( |
| 1426 HHasCachedArrayIndex* instr) { | 1544 HHasCachedArrayIndex* instr) { |
| 1427 Abort("Unimplemented: %s", "DoHasCachedArrayIndex"); | 1545 ASSERT(instr->value()->representation().IsTagged()); |
| 1428 return NULL; | 1546 LOperand* value = UseRegister(instr->value()); |
| 1547 return DefineAsRegister(new LHasCachedArrayIndex(value)); |
| 1429 } | 1548 } |
| 1430 | 1549 |
| 1431 | 1550 |
| 1432 LInstruction* LChunkBuilder::DoClassOfTest(HClassOfTest* instr) { | 1551 LInstruction* LChunkBuilder::DoClassOfTest(HClassOfTest* instr) { |
| 1433 Abort("Unimplemented: %s", "DoClassOfTest"); | 1552 Abort("Unimplemented: %s", "DoClassOfTest"); |
| 1434 return NULL; | 1553 return NULL; |
| 1435 } | 1554 } |
| 1436 | 1555 |
| 1437 | 1556 |
| 1438 LInstruction* LChunkBuilder::DoJSArrayLength(HJSArrayLength* instr) { | 1557 LInstruction* LChunkBuilder::DoJSArrayLength(HJSArrayLength* instr) { |
| 1439 LOperand* array = UseRegisterAtStart(instr->value()); | 1558 LOperand* array = UseRegisterAtStart(instr->value()); |
| 1440 return DefineAsRegister(new LJSArrayLength(array)); | 1559 return DefineAsRegister(new LJSArrayLength(array)); |
| 1441 } | 1560 } |
| 1442 | 1561 |
| 1443 | 1562 |
| 1444 LInstruction* LChunkBuilder::DoFixedArrayLength(HFixedArrayLength* instr) { | 1563 LInstruction* LChunkBuilder::DoFixedArrayLength(HFixedArrayLength* instr) { |
| 1445 LOperand* array = UseRegisterAtStart(instr->value()); | 1564 LOperand* array = UseRegisterAtStart(instr->value()); |
| 1446 return DefineAsRegister(new LFixedArrayLength(array)); | 1565 return DefineAsRegister(new LFixedArrayLength(array)); |
| 1447 } | 1566 } |
| 1448 | 1567 |
| 1449 | 1568 |
| 1450 LInstruction* LChunkBuilder::DoPixelArrayLength(HPixelArrayLength* instr) { | 1569 LInstruction* LChunkBuilder::DoExternalArrayLength( |
| 1570 HExternalArrayLength* instr) { |
| 1451 LOperand* array = UseRegisterAtStart(instr->value()); | 1571 LOperand* array = UseRegisterAtStart(instr->value()); |
| 1452 return DefineAsRegister(new LPixelArrayLength(array)); | 1572 return DefineAsRegister(new LExternalArrayLength(array)); |
| 1453 } | 1573 } |
| 1454 | 1574 |
| 1455 | 1575 |
| 1456 LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) { | 1576 LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) { |
| 1457 Abort("Unimplemented: %s", "DoValueOf"); | 1577 LOperand* object = UseRegister(instr->value()); |
| 1458 return NULL; | 1578 LValueOf* result = new LValueOf(object); |
| 1579 return AssignEnvironment(DefineSameAsFirst(result)); |
| 1459 } | 1580 } |
| 1460 | 1581 |
| 1461 | 1582 |
| 1462 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) { | 1583 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) { |
| 1463 return AssignEnvironment(new LBoundsCheck(UseRegisterAtStart(instr->index()), | 1584 return AssignEnvironment(new LBoundsCheck(UseRegisterAtStart(instr->index()), |
| 1464 Use(instr->length()))); | 1585 Use(instr->length()))); |
| 1465 } | 1586 } |
| 1466 | 1587 |
| 1467 | 1588 |
| 1468 LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) { | 1589 LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1505 if (to.IsTagged()) { | 1626 if (to.IsTagged()) { |
| 1506 LOperand* value = UseRegister(instr->value()); | 1627 LOperand* value = UseRegister(instr->value()); |
| 1507 LOperand* temp = TempRegister(); | 1628 LOperand* temp = TempRegister(); |
| 1508 | 1629 |
| 1509 // Make sure that temp and result_temp are different registers. | 1630 // Make sure that temp and result_temp are different registers. |
| 1510 LUnallocated* result_temp = TempRegister(); | 1631 LUnallocated* result_temp = TempRegister(); |
| 1511 LNumberTagD* result = new LNumberTagD(value, temp); | 1632 LNumberTagD* result = new LNumberTagD(value, temp); |
| 1512 return AssignPointerMap(Define(result, result_temp)); | 1633 return AssignPointerMap(Define(result, result_temp)); |
| 1513 } else { | 1634 } else { |
| 1514 ASSERT(to.IsInteger32()); | 1635 ASSERT(to.IsInteger32()); |
| 1515 bool needs_temp = instr->CanTruncateToInt32() && | 1636 LOperand* value = UseRegister(instr->value()); |
| 1516 !CpuFeatures::IsSupported(SSE3); | 1637 return AssignEnvironment(DefineAsRegister(new LDoubleToI(value))); |
| 1517 LOperand* value = needs_temp ? | |
| 1518 UseTempRegister(instr->value()) : UseRegister(instr->value()); | |
| 1519 LOperand* temp = needs_temp ? TempRegister() : NULL; | |
| 1520 return AssignEnvironment(DefineAsRegister(new LDoubleToI(value, temp))); | |
| 1521 } | 1638 } |
| 1522 } else if (from.IsInteger32()) { | 1639 } else if (from.IsInteger32()) { |
| 1523 if (to.IsTagged()) { | 1640 if (to.IsTagged()) { |
| 1524 HValue* val = instr->value(); | 1641 HValue* val = instr->value(); |
| 1525 LOperand* value = UseRegister(val); | 1642 LOperand* value = UseRegister(val); |
| 1526 if (val->HasRange() && val->range()->IsInSmiRange()) { | 1643 if (val->HasRange() && val->range()->IsInSmiRange()) { |
| 1527 return DefineSameAsFirst(new LSmiTag(value)); | 1644 return DefineSameAsFirst(new LSmiTag(value)); |
| 1528 } else { | 1645 } else { |
| 1529 LNumberTagI* result = new LNumberTagI(value); | 1646 LNumberTagI* result = new LNumberTagI(value); |
| 1530 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result))); | 1647 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result))); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1608 | 1725 |
| 1609 | 1726 |
| 1610 LInstruction* LChunkBuilder::DoStoreGlobal(HStoreGlobal* instr) { | 1727 LInstruction* LChunkBuilder::DoStoreGlobal(HStoreGlobal* instr) { |
| 1611 LStoreGlobal* result = new LStoreGlobal(UseRegister(instr->value()), | 1728 LStoreGlobal* result = new LStoreGlobal(UseRegister(instr->value()), |
| 1612 TempRegister()); | 1729 TempRegister()); |
| 1613 return instr->check_hole_value() ? AssignEnvironment(result) : result; | 1730 return instr->check_hole_value() ? AssignEnvironment(result) : result; |
| 1614 } | 1731 } |
| 1615 | 1732 |
| 1616 | 1733 |
| 1617 LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) { | 1734 LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) { |
| 1618 Abort("Unimplemented: %s", "DoLoadContextSlot"); | 1735 LOperand* context = UseRegisterAtStart(instr->value()); |
| 1619 return NULL; | 1736 return DefineAsRegister(new LLoadContextSlot(context)); |
| 1620 } | 1737 } |
| 1621 | 1738 |
| 1622 | 1739 |
| 1623 LInstruction* LChunkBuilder::DoStoreContextSlot(HStoreContextSlot* instr) { | 1740 LInstruction* LChunkBuilder::DoStoreContextSlot(HStoreContextSlot* instr) { |
| 1624 Abort("Unimplemented: DoStoreContextSlot"); | 1741 LOperand* context; |
| 1625 return NULL; | 1742 LOperand* value; |
| 1743 LOperand* temp; |
| 1744 if (instr->NeedsWriteBarrier()) { |
| 1745 context = UseTempRegister(instr->context()); |
| 1746 value = UseTempRegister(instr->value()); |
| 1747 temp = TempRegister(); |
| 1748 } else { |
| 1749 context = UseRegister(instr->context()); |
| 1750 value = UseRegister(instr->value()); |
| 1751 temp = NULL; |
| 1752 } |
| 1753 return new LStoreContextSlot(context, value, temp); |
| 1626 } | 1754 } |
| 1627 | 1755 |
| 1628 | 1756 |
| 1629 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) { | 1757 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) { |
| 1630 ASSERT(instr->representation().IsTagged()); | 1758 ASSERT(instr->representation().IsTagged()); |
| 1631 LOperand* obj = UseRegisterAtStart(instr->object()); | 1759 LOperand* obj = UseRegisterAtStart(instr->object()); |
| 1632 return DefineAsRegister(new LLoadNamedField(obj)); | 1760 return DefineAsRegister(new LLoadNamedField(obj)); |
| 1633 } | 1761 } |
| 1634 | 1762 |
| 1635 | 1763 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1646 new LLoadFunctionPrototype(UseRegister(instr->function())))); | 1774 new LLoadFunctionPrototype(UseRegister(instr->function())))); |
| 1647 } | 1775 } |
| 1648 | 1776 |
| 1649 | 1777 |
| 1650 LInstruction* LChunkBuilder::DoLoadElements(HLoadElements* instr) { | 1778 LInstruction* LChunkBuilder::DoLoadElements(HLoadElements* instr) { |
| 1651 LOperand* input = UseRegisterAtStart(instr->value()); | 1779 LOperand* input = UseRegisterAtStart(instr->value()); |
| 1652 return DefineAsRegister(new LLoadElements(input)); | 1780 return DefineAsRegister(new LLoadElements(input)); |
| 1653 } | 1781 } |
| 1654 | 1782 |
| 1655 | 1783 |
| 1656 LInstruction* LChunkBuilder::DoLoadPixelArrayExternalPointer( | 1784 LInstruction* LChunkBuilder::DoLoadExternalArrayPointer( |
| 1657 HLoadPixelArrayExternalPointer* instr) { | 1785 HLoadExternalArrayPointer* instr) { |
| 1658 LOperand* input = UseRegisterAtStart(instr->value()); | 1786 LOperand* input = UseRegisterAtStart(instr->value()); |
| 1659 return DefineAsRegister(new LLoadPixelArrayExternalPointer(input)); | 1787 return DefineAsRegister(new LLoadExternalArrayPointer(input)); |
| 1660 } | 1788 } |
| 1661 | 1789 |
| 1662 | 1790 |
| 1663 LInstruction* LChunkBuilder::DoLoadKeyedFastElement( | 1791 LInstruction* LChunkBuilder::DoLoadKeyedFastElement( |
| 1664 HLoadKeyedFastElement* instr) { | 1792 HLoadKeyedFastElement* instr) { |
| 1665 ASSERT(instr->representation().IsTagged()); | 1793 ASSERT(instr->representation().IsTagged()); |
| 1666 ASSERT(instr->key()->representation().IsInteger32()); | 1794 ASSERT(instr->key()->representation().IsInteger32()); |
| 1667 LOperand* obj = UseRegisterAtStart(instr->object()); | 1795 LOperand* obj = UseRegisterAtStart(instr->object()); |
| 1668 LOperand* key = UseRegisterAtStart(instr->key()); | 1796 LOperand* key = UseRegisterAtStart(instr->key()); |
| 1669 LLoadKeyedFastElement* result = new LLoadKeyedFastElement(obj, key); | 1797 LLoadKeyedFastElement* result = new LLoadKeyedFastElement(obj, key); |
| 1670 return AssignEnvironment(DefineSameAsFirst(result)); | 1798 return AssignEnvironment(DefineSameAsFirst(result)); |
| 1671 } | 1799 } |
| 1672 | 1800 |
| 1673 | 1801 |
| 1674 LInstruction* LChunkBuilder::DoLoadPixelArrayElement( | 1802 LInstruction* LChunkBuilder::DoLoadPixelArrayElement( |
| 1675 HLoadPixelArrayElement* instr) { | 1803 HLoadPixelArrayElement* instr) { |
| 1676 ASSERT(instr->representation().IsInteger32()); | 1804 ASSERT(instr->representation().IsInteger32()); |
| 1677 ASSERT(instr->key()->representation().IsInteger32()); | 1805 ASSERT(instr->key()->representation().IsInteger32()); |
| 1678 LOperand* external_pointer = | 1806 LOperand* external_pointer = |
| 1679 UseRegisterAtStart(instr->external_pointer()); | 1807 UseRegisterAtStart(instr->external_pointer()); |
| 1680 LOperand* key = UseRegisterAtStart(instr->key()); | 1808 LOperand* key = UseRegisterAtStart(instr->key()); |
| 1681 LLoadPixelArrayElement* result = | 1809 LLoadPixelArrayElement* result = |
| 1682 new LLoadPixelArrayElement(external_pointer, key); | 1810 new LLoadPixelArrayElement(external_pointer, key); |
| 1683 return DefineSameAsFirst(result); | 1811 return DefineSameAsFirst(result); |
| 1684 } | 1812 } |
| 1685 | 1813 |
| 1686 | 1814 |
| 1687 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { | 1815 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { |
| 1688 Abort("Unimplemented: %s", "DoLoadKeyedGeneric"); | 1816 LOperand* object = UseFixed(instr->object(), rdx); |
| 1689 return NULL; | 1817 LOperand* key = UseFixed(instr->key(), rax); |
| 1818 |
| 1819 LLoadKeyedGeneric* result = new LLoadKeyedGeneric(object, key); |
| 1820 return MarkAsCall(DefineFixed(result, rax), instr); |
| 1690 } | 1821 } |
| 1691 | 1822 |
| 1692 | 1823 |
| 1693 LInstruction* LChunkBuilder::DoStoreKeyedFastElement( | 1824 LInstruction* LChunkBuilder::DoStoreKeyedFastElement( |
| 1694 HStoreKeyedFastElement* instr) { | 1825 HStoreKeyedFastElement* instr) { |
| 1695 bool needs_write_barrier = instr->NeedsWriteBarrier(); | 1826 bool needs_write_barrier = instr->NeedsWriteBarrier(); |
| 1696 ASSERT(instr->value()->representation().IsTagged()); | 1827 ASSERT(instr->value()->representation().IsTagged()); |
| 1697 ASSERT(instr->object()->representation().IsTagged()); | 1828 ASSERT(instr->object()->representation().IsTagged()); |
| 1698 ASSERT(instr->key()->representation().IsInteger32()); | 1829 ASSERT(instr->key()->representation().IsInteger32()); |
| 1699 | 1830 |
| 1700 LOperand* obj = UseTempRegister(instr->object()); | 1831 LOperand* obj = UseTempRegister(instr->object()); |
| 1701 LOperand* val = needs_write_barrier | 1832 LOperand* val = needs_write_barrier |
| 1702 ? UseTempRegister(instr->value()) | 1833 ? UseTempRegister(instr->value()) |
| 1703 : UseRegisterAtStart(instr->value()); | 1834 : UseRegisterAtStart(instr->value()); |
| 1704 LOperand* key = needs_write_barrier | 1835 LOperand* key = needs_write_barrier |
| 1705 ? UseTempRegister(instr->key()) | 1836 ? UseTempRegister(instr->key()) |
| 1706 : UseRegisterOrConstantAtStart(instr->key()); | 1837 : UseRegisterOrConstantAtStart(instr->key()); |
| 1707 | 1838 |
| 1708 return AssignEnvironment(new LStoreKeyedFastElement(obj, key, val)); | 1839 return AssignEnvironment(new LStoreKeyedFastElement(obj, key, val)); |
| 1709 } | 1840 } |
| 1710 | 1841 |
| 1711 | 1842 |
| 1843 LInstruction* LChunkBuilder::DoStorePixelArrayElement( |
| 1844 HStorePixelArrayElement* instr) { |
| 1845 ASSERT(instr->value()->representation().IsInteger32()); |
| 1846 ASSERT(instr->external_pointer()->representation().IsExternal()); |
| 1847 ASSERT(instr->key()->representation().IsInteger32()); |
| 1848 |
| 1849 LOperand* external_pointer = UseRegister(instr->external_pointer()); |
| 1850 LOperand* val = UseTempRegister(instr->value()); |
| 1851 LOperand* key = UseRegister(instr->key()); |
| 1852 |
| 1853 return new LStorePixelArrayElement(external_pointer, key, val); |
| 1854 } |
| 1855 |
| 1856 |
| 1712 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) { | 1857 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) { |
| 1713 Abort("Unimplemented: %s", "DoStoreKeyedGeneric"); | 1858 LOperand* object = UseFixed(instr->object(), rdx); |
| 1714 return NULL; | 1859 LOperand* key = UseFixed(instr->key(), rcx); |
| 1860 LOperand* value = UseFixed(instr->value(), rax); |
| 1861 |
| 1862 ASSERT(instr->object()->representation().IsTagged()); |
| 1863 ASSERT(instr->key()->representation().IsTagged()); |
| 1864 ASSERT(instr->value()->representation().IsTagged()); |
| 1865 |
| 1866 LStoreKeyedGeneric* result = new LStoreKeyedGeneric(object, key, value); |
| 1867 return MarkAsCall(result, instr); |
| 1715 } | 1868 } |
| 1716 | 1869 |
| 1717 | 1870 |
| 1718 LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) { | 1871 LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) { |
| 1719 bool needs_write_barrier = instr->NeedsWriteBarrier(); | 1872 bool needs_write_barrier = instr->NeedsWriteBarrier(); |
| 1720 | 1873 |
| 1721 LOperand* obj = needs_write_barrier | 1874 LOperand* obj = needs_write_barrier |
| 1722 ? UseTempRegister(instr->object()) | 1875 ? UseTempRegister(instr->object()) |
| 1723 : UseRegisterAtStart(instr->object()); | 1876 : UseRegisterAtStart(instr->object()); |
| 1724 | 1877 |
| 1725 LOperand* val = needs_write_barrier | 1878 LOperand* val = needs_write_barrier |
| 1726 ? UseTempRegister(instr->value()) | 1879 ? UseTempRegister(instr->value()) |
| 1727 : UseRegister(instr->value()); | 1880 : UseRegister(instr->value()); |
| 1728 | 1881 |
| 1729 // We only need a scratch register if we have a write barrier or we | 1882 // We only need a scratch register if we have a write barrier or we |
| 1730 // have a store into the properties array (not in-object-property). | 1883 // have a store into the properties array (not in-object-property). |
| 1731 LOperand* temp = (!instr->is_in_object() || needs_write_barrier) | 1884 LOperand* temp = (!instr->is_in_object() || needs_write_barrier) |
| 1732 ? TempRegister() : NULL; | 1885 ? TempRegister() : NULL; |
| 1733 | 1886 |
| 1734 return new LStoreNamedField(obj, val, temp); | 1887 return new LStoreNamedField(obj, val, temp); |
| 1735 } | 1888 } |
| 1736 | 1889 |
| 1737 | 1890 |
| 1738 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) { | 1891 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) { |
| 1739 Abort("Unimplemented: %s", "DoStoreNamedGeneric"); | 1892 LOperand* object = UseFixed(instr->object(), rdx); |
| 1740 return NULL; | 1893 LOperand* value = UseFixed(instr->value(), rax); |
| 1894 |
| 1895 LStoreNamedGeneric* result = new LStoreNamedGeneric(object, value); |
| 1896 return MarkAsCall(result, instr); |
| 1741 } | 1897 } |
| 1742 | 1898 |
| 1743 | 1899 |
| 1744 LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) { | 1900 LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) { |
| 1745 Abort("Unimplemented: %s", "DoStringCharCodeAt"); | 1901 LOperand* string = UseRegister(instr->string()); |
| 1746 return NULL; | 1902 LOperand* index = UseRegisterOrConstant(instr->index()); |
| 1903 LStringCharCodeAt* result = new LStringCharCodeAt(string, index); |
| 1904 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); |
| 1905 } |
| 1906 |
| 1907 |
| 1908 LInstruction* LChunkBuilder::DoStringCharFromCode(HStringCharFromCode* instr) { |
| 1909 LOperand* char_code = UseRegister(instr->value()); |
| 1910 LStringCharFromCode* result = new LStringCharFromCode(char_code); |
| 1911 return AssignPointerMap(DefineAsRegister(result)); |
| 1747 } | 1912 } |
| 1748 | 1913 |
| 1749 | 1914 |
| 1750 LInstruction* LChunkBuilder::DoStringLength(HStringLength* instr) { | 1915 LInstruction* LChunkBuilder::DoStringLength(HStringLength* instr) { |
| 1751 LOperand* string = UseRegisterAtStart(instr->value()); | 1916 LOperand* string = UseRegisterAtStart(instr->value()); |
| 1752 return DefineAsRegister(new LStringLength(string)); | 1917 return DefineAsRegister(new LStringLength(string)); |
| 1753 } | 1918 } |
| 1754 | 1919 |
| 1755 | 1920 |
| 1756 LInstruction* LChunkBuilder::DoArrayLiteral(HArrayLiteral* instr) { | 1921 LInstruction* LChunkBuilder::DoArrayLiteral(HArrayLiteral* instr) { |
| 1757 return MarkAsCall(DefineFixed(new LArrayLiteral, rax), instr); | 1922 return MarkAsCall(DefineFixed(new LArrayLiteral, rax), instr); |
| 1758 } | 1923 } |
| 1759 | 1924 |
| 1760 | 1925 |
| 1761 LInstruction* LChunkBuilder::DoObjectLiteral(HObjectLiteral* instr) { | 1926 LInstruction* LChunkBuilder::DoObjectLiteral(HObjectLiteral* instr) { |
| 1762 return MarkAsCall(DefineFixed(new LObjectLiteral, rax), instr); | 1927 return MarkAsCall(DefineFixed(new LObjectLiteral, rax), instr); |
| 1763 } | 1928 } |
| 1764 | 1929 |
| 1765 | 1930 |
| 1766 LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) { | 1931 LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) { |
| 1767 Abort("Unimplemented: %s", "DoRegExpLiteral"); | 1932 return MarkAsCall(DefineFixed(new LRegExpLiteral, rax), instr); |
| 1768 return NULL; | |
| 1769 } | 1933 } |
| 1770 | 1934 |
| 1771 | 1935 |
| 1772 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) { | 1936 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) { |
| 1773 return MarkAsCall(DefineFixed(new LFunctionLiteral, rax), instr); | 1937 return MarkAsCall(DefineFixed(new LFunctionLiteral, rax), instr); |
| 1774 } | 1938 } |
| 1775 | 1939 |
| 1776 | 1940 |
| 1777 LInstruction* LChunkBuilder::DoDeleteProperty(HDeleteProperty* instr) { | 1941 LInstruction* LChunkBuilder::DoDeleteProperty(HDeleteProperty* instr) { |
| 1778 Abort("Unimplemented: %s", "DoDeleteProperty"); | 1942 LDeleteProperty* result = |
| 1779 return NULL; | 1943 new LDeleteProperty(Use(instr->object()), UseOrConstant(instr->key())); |
| 1944 return MarkAsCall(DefineFixed(result, rax), instr); |
| 1780 } | 1945 } |
| 1781 | 1946 |
| 1782 | 1947 |
| 1783 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) { | 1948 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) { |
| 1784 Abort("Unimplemented: %s", "DoOsrEntry"); | 1949 allocator_->MarkAsOsrEntry(); |
| 1785 return NULL; | 1950 current_block_->last_environment()->set_ast_id(instr->ast_id()); |
| 1951 return AssignEnvironment(new LOsrEntry); |
| 1786 } | 1952 } |
| 1787 | 1953 |
| 1788 | 1954 |
| 1789 LInstruction* LChunkBuilder::DoParameter(HParameter* instr) { | 1955 LInstruction* LChunkBuilder::DoParameter(HParameter* instr) { |
| 1790 int spill_index = chunk()->GetParameterStackSlot(instr->index()); | 1956 int spill_index = chunk()->GetParameterStackSlot(instr->index()); |
| 1791 return DefineAsSpilled(new LParameter, spill_index); | 1957 return DefineAsSpilled(new LParameter, spill_index); |
| 1792 } | 1958 } |
| 1793 | 1959 |
| 1794 | 1960 |
| 1795 LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) { | 1961 LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) { |
| 1796 Abort("Unimplemented: %s", "DoUnknownOSRValue"); | 1962 int spill_index = chunk()->GetNextSpillIndex(false); // Not double-width. |
| 1797 return NULL; | 1963 return DefineAsSpilled(new LUnknownOSRValue, spill_index); |
| 1798 } | 1964 } |
| 1799 | 1965 |
| 1800 | 1966 |
| 1801 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) { | 1967 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) { |
| 1802 argument_count_ -= instr->argument_count(); | 1968 argument_count_ -= instr->argument_count(); |
| 1803 return MarkAsCall(DefineFixed(new LCallStub, rax), instr); | 1969 return MarkAsCall(DefineFixed(new LCallStub, rax), instr); |
| 1804 } | 1970 } |
| 1805 | 1971 |
| 1806 | 1972 |
| 1807 LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) { | 1973 LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) { |
| 1808 Abort("Unimplemented: %s", "DoArgumentsObject"); | 1974 // There are no real uses of the arguments object. |
| 1975 // arguments.length and element access are supported directly on |
| 1976 // stack arguments, and any real arguments object use causes a bailout. |
| 1977 // So this value is never used. |
| 1809 return NULL; | 1978 return NULL; |
| 1810 } | 1979 } |
| 1811 | 1980 |
| 1812 | 1981 |
| 1813 LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) { | 1982 LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) { |
| 1814 LOperand* arguments = UseRegister(instr->arguments()); | 1983 LOperand* arguments = UseRegister(instr->arguments()); |
| 1815 LOperand* length = UseTempRegister(instr->length()); | 1984 LOperand* length = UseTempRegister(instr->length()); |
| 1816 LOperand* index = Use(instr->index()); | 1985 LOperand* index = Use(instr->index()); |
| 1817 LAccessArgumentsAt* result = new LAccessArgumentsAt(arguments, length, index); | 1986 LAccessArgumentsAt* result = new LAccessArgumentsAt(arguments, length, index); |
| 1818 return AssignEnvironment(DefineAsRegister(result)); | 1987 return AssignEnvironment(DefineAsRegister(result)); |
| 1819 } | 1988 } |
| 1820 | 1989 |
| 1821 | 1990 |
| 1822 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) { | 1991 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) { |
| 1823 Abort("Unimplemented: %s", "DoTypeof"); | 1992 LTypeof* result = new LTypeof(UseAtStart(instr->value())); |
| 1824 return NULL; | 1993 return MarkAsCall(DefineFixed(result, rax), instr); |
| 1825 } | 1994 } |
| 1826 | 1995 |
| 1827 | 1996 |
| 1828 LInstruction* LChunkBuilder::DoTypeofIs(HTypeofIs* instr) { | 1997 LInstruction* LChunkBuilder::DoTypeofIs(HTypeofIs* instr) { |
| 1829 Abort("Unimplemented: %s", "DoTypeofIs"); | 1998 return DefineSameAsFirst(new LTypeofIs(UseRegister(instr->value()))); |
| 1830 return NULL; | |
| 1831 } | 1999 } |
| 1832 | 2000 |
| 1833 | 2001 |
| 1834 LInstruction* LChunkBuilder::DoIsConstructCall(HIsConstructCall* instr) { | 2002 LInstruction* LChunkBuilder::DoIsConstructCall(HIsConstructCall* instr) { |
| 1835 return DefineAsRegister(new LIsConstructCall); | 2003 return DefineAsRegister(new LIsConstructCall); |
| 1836 } | 2004 } |
| 1837 | 2005 |
| 1838 | 2006 |
| 1839 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) { | 2007 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) { |
| 1840 HEnvironment* env = current_block_->last_environment(); | 2008 HEnvironment* env = current_block_->last_environment(); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1888 | 2056 |
| 1889 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { | 2057 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { |
| 1890 HEnvironment* outer = current_block_->last_environment()->outer(); | 2058 HEnvironment* outer = current_block_->last_environment()->outer(); |
| 1891 current_block_->UpdateEnvironment(outer); | 2059 current_block_->UpdateEnvironment(outer); |
| 1892 return NULL; | 2060 return NULL; |
| 1893 } | 2061 } |
| 1894 | 2062 |
| 1895 } } // namespace v8::internal | 2063 } } // namespace v8::internal |
| 1896 | 2064 |
| 1897 #endif // V8_TARGET_ARCH_X64 | 2065 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |