| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 472 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 483 | 483 |
| 484 previous_ = previous; | 484 previous_ = previous; |
| 485 next_ = next; | 485 next_ = next; |
| 486 SetBlock(block); | 486 SetBlock(block); |
| 487 previous->next_ = this; | 487 previous->next_ = this; |
| 488 if (next != NULL) next->previous_ = this; | 488 if (next != NULL) next->previous_ = this; |
| 489 } | 489 } |
| 490 | 490 |
| 491 | 491 |
| 492 #ifdef DEBUG | 492 #ifdef DEBUG |
| 493 void HInstruction::Verify() const { | 493 void HInstruction::Verify() { |
| 494 // Verify that input operands are defined before use. | 494 // Verify that input operands are defined before use. |
| 495 HBasicBlock* cur_block = block(); | 495 HBasicBlock* cur_block = block(); |
| 496 for (int i = 0; i < OperandCount(); ++i) { | 496 for (int i = 0; i < OperandCount(); ++i) { |
| 497 HValue* other_operand = OperandAt(i); | 497 HValue* other_operand = OperandAt(i); |
| 498 HBasicBlock* other_block = other_operand->block(); | 498 HBasicBlock* other_block = other_operand->block(); |
| 499 if (cur_block == other_block) { | 499 if (cur_block == other_block) { |
| 500 if (!other_operand->IsPhi()) { | 500 if (!other_operand->IsPhi()) { |
| 501 HInstruction* cur = cur_block->first(); | 501 HInstruction* cur = cur_block->first(); |
| 502 while (cur != NULL) { | 502 while (cur != NULL) { |
| 503 ASSERT(cur != this); // We should reach other_operand before! | 503 ASSERT(cur != this); // We should reach other_operand before! |
| 504 if (cur == other_operand) break; | 504 if (cur == other_operand) break; |
| 505 cur = cur->next(); | 505 cur = cur->next(); |
| 506 } | 506 } |
| 507 // Must reach other operand in the same block! | 507 // Must reach other operand in the same block! |
| 508 ASSERT(cur == other_operand); | 508 ASSERT(cur == other_operand); |
| 509 } | 509 } |
| 510 } else { | 510 } else { |
| 511 ASSERT(other_block->Dominates(cur_block)); | 511 ASSERT(other_block->Dominates(cur_block)); |
| 512 } | 512 } |
| 513 } | 513 } |
| 514 | 514 |
| 515 // Verify that instructions that may have side-effects are followed | 515 // Verify that instructions that may have side-effects are followed |
| 516 // by a simulate instruction. | 516 // by a simulate instruction. |
| 517 if (HasSideEffects() && !IsOsrEntry()) { | 517 if (HasSideEffects() && !IsOsrEntry()) { |
| 518 ASSERT(next()->IsSimulate()); | 518 ASSERT(next()->IsSimulate()); |
| 519 } | 519 } |
| 520 |
| 521 // Verify that instructions that can be eliminated by GVN have overridden |
| 522 // HValue::DataEquals. The default implementation is UNREACHABLE. We |
| 523 // don't actually care whether DataEquals returns true or false here. |
| 524 if (CheckFlag(kUseGVN)) DataEquals(this); |
| 520 } | 525 } |
| 521 #endif | 526 #endif |
| 522 | 527 |
| 523 | 528 |
| 524 HCall::HCall(int count) : arguments_(ZONE->NewArray<HValue*>(count), count) { | 529 HCall::HCall(int count) : arguments_(ZONE->NewArray<HValue*>(count), count) { |
| 525 for (int i = 0; i < count; ++i) arguments_[i] = NULL; | 530 for (int i = 0; i < count; ++i) arguments_[i] = NULL; |
| 526 set_representation(Representation::Tagged()); | 531 set_representation(Representation::Tagged()); |
| 527 SetFlagMask(AllSideEffects()); | 532 SetAllSideEffects(); |
| 528 } | 533 } |
| 529 | 534 |
| 530 | 535 |
| 531 void HCall::PrintDataTo(StringStream* stream) const { | 536 void HCall::PrintDataTo(StringStream* stream) const { |
| 532 stream->Add("("); | 537 stream->Add("("); |
| 533 for (int i = 0; i < arguments_.length(); ++i) { | 538 for (int i = 0; i < arguments_.length(); ++i) { |
| 534 if (i != 0) stream->Add(", "); | 539 if (i != 0) stream->Add(", "); |
| 535 arguments_.at(i)->PrintNameTo(stream); | 540 arguments_.at(i)->PrintNameTo(stream); |
| 536 } | 541 } |
| 537 stream->Add(")"); | 542 stream->Add(")"); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 563 void HCallConstantFunction::PrintDataTo(StringStream* stream) const { | 568 void HCallConstantFunction::PrintDataTo(StringStream* stream) const { |
| 564 if (IsApplyFunction()) { | 569 if (IsApplyFunction()) { |
| 565 stream->Add("SPECIAL function: apply"); | 570 stream->Add("SPECIAL function: apply"); |
| 566 } else { | 571 } else { |
| 567 stream->Add("%s", *(function()->shared()->DebugName()->ToCString())); | 572 stream->Add("%s", *(function()->shared()->DebugName()->ToCString())); |
| 568 } | 573 } |
| 569 HCall::PrintDataTo(stream); | 574 HCall::PrintDataTo(stream); |
| 570 } | 575 } |
| 571 | 576 |
| 572 | 577 |
| 573 void HBranch::PrintDataTo(StringStream* stream) const { | 578 void HControlInstruction::PrintDataTo(StringStream* stream) const { |
| 574 int first_id = FirstSuccessor()->block_id(); | 579 if (FirstSuccessor() != NULL) { |
| 575 int second_id = SecondSuccessor()->block_id(); | 580 int first_id = FirstSuccessor()->block_id(); |
| 576 stream->Add("on "); | 581 if (SecondSuccessor() == NULL) { |
| 577 value()->PrintNameTo(stream); | 582 stream->Add(" B%d", first_id); |
| 578 stream->Add(" (B%d, B%d)", first_id, second_id); | 583 } else { |
| 584 int second_id = SecondSuccessor()->block_id(); |
| 585 stream->Add(" goto (B%d, B%d)", first_id, second_id); |
| 586 } |
| 587 } |
| 579 } | 588 } |
| 580 | 589 |
| 581 | 590 |
| 582 void HCompareMapAndBranch::PrintDataTo(StringStream* stream) const { | 591 void HUnaryControlInstruction::PrintDataTo(StringStream* stream) const { |
| 583 stream->Add("on "); | |
| 584 value()->PrintNameTo(stream); | 592 value()->PrintNameTo(stream); |
| 585 stream->Add(" (%p)", *map()); | 593 HControlInstruction::PrintDataTo(stream); |
| 586 } | 594 } |
| 587 | 595 |
| 588 | 596 |
| 589 void HGoto::PrintDataTo(StringStream* stream) const { | 597 void HCompareMap::PrintDataTo(StringStream* stream) const { |
| 590 stream->Add("B%d", FirstSuccessor()->block_id()); | |
| 591 } | |
| 592 | |
| 593 | |
| 594 void HReturn::PrintDataTo(StringStream* stream) const { | |
| 595 value()->PrintNameTo(stream); | 598 value()->PrintNameTo(stream); |
| 596 } | 599 stream->Add(" (%p)", *map()); |
| 597 | 600 HControlInstruction::PrintDataTo(stream); |
| 598 | |
| 599 void HThrow::PrintDataTo(StringStream* stream) const { | |
| 600 value()->PrintNameTo(stream); | |
| 601 } | 601 } |
| 602 | 602 |
| 603 | 603 |
| 604 const char* HUnaryMathOperation::OpName() const { | 604 const char* HUnaryMathOperation::OpName() const { |
| 605 switch (op()) { | 605 switch (op()) { |
| 606 case kMathFloor: return "floor"; | 606 case kMathFloor: return "floor"; |
| 607 case kMathRound: return "round"; | 607 case kMathRound: return "round"; |
| 608 case kMathCeil: return "ceil"; | 608 case kMathCeil: return "ceil"; |
| 609 case kMathAbs: return "abs"; | 609 case kMathAbs: return "abs"; |
| 610 case kMathLog: return "log"; | 610 case kMathLog: return "log"; |
| (...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 989 : handle_(handle), | 989 : handle_(handle), |
| 990 constant_type_(HType::TypeFromValue(handle)), | 990 constant_type_(HType::TypeFromValue(handle)), |
| 991 has_int32_value_(false), | 991 has_int32_value_(false), |
| 992 int32_value_(0), | 992 int32_value_(0), |
| 993 has_double_value_(false), | 993 has_double_value_(false), |
| 994 double_value_(0) { | 994 double_value_(0) { |
| 995 set_representation(r); | 995 set_representation(r); |
| 996 SetFlag(kUseGVN); | 996 SetFlag(kUseGVN); |
| 997 if (handle_->IsNumber()) { | 997 if (handle_->IsNumber()) { |
| 998 double n = handle_->Number(); | 998 double n = handle_->Number(); |
| 999 has_int32_value_ = static_cast<double>(static_cast<int32_t>(n)) == n; | 999 double roundtrip_value = static_cast<double>(static_cast<int32_t>(n)); |
| 1000 has_int32_value_ = BitCast<int64_t>(roundtrip_value) == BitCast<int64_t>(n); |
| 1000 if (has_int32_value_) int32_value_ = static_cast<int32_t>(n); | 1001 if (has_int32_value_) int32_value_ = static_cast<int32_t>(n); |
| 1001 double_value_ = n; | 1002 double_value_ = n; |
| 1002 has_double_value_ = true; | 1003 has_double_value_ = true; |
| 1003 } | 1004 } |
| 1004 } | 1005 } |
| 1005 | 1006 |
| 1006 | 1007 |
| 1007 HConstant* HConstant::CopyToRepresentation(Representation r) const { | 1008 HConstant* HConstant::CopyToRepresentation(Representation r) const { |
| 1008 if (r.IsInteger32() && !has_int32_value_) return NULL; | 1009 if (r.IsInteger32() && !has_int32_value_) return NULL; |
| 1009 if (r.IsDouble() && !has_double_value_) return NULL; | 1010 if (r.IsDouble() && !has_double_value_) return NULL; |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1116 void HCompare::PrintDataTo(StringStream* stream) const { | 1117 void HCompare::PrintDataTo(StringStream* stream) const { |
| 1117 stream->Add(Token::Name(token())); | 1118 stream->Add(Token::Name(token())); |
| 1118 stream->Add(" "); | 1119 stream->Add(" "); |
| 1119 HBinaryOperation::PrintDataTo(stream); | 1120 HBinaryOperation::PrintDataTo(stream); |
| 1120 } | 1121 } |
| 1121 | 1122 |
| 1122 | 1123 |
| 1123 void HCompare::SetInputRepresentation(Representation r) { | 1124 void HCompare::SetInputRepresentation(Representation r) { |
| 1124 input_representation_ = r; | 1125 input_representation_ = r; |
| 1125 if (r.IsTagged()) { | 1126 if (r.IsTagged()) { |
| 1126 SetFlagMask(AllSideEffects()); | 1127 SetAllSideEffects(); |
| 1127 ClearFlag(kUseGVN); | 1128 ClearFlag(kUseGVN); |
| 1128 } else { | 1129 } else { |
| 1129 ClearFlagMask(AllSideEffects()); | 1130 ClearAllSideEffects(); |
| 1130 SetFlag(kUseGVN); | 1131 SetFlag(kUseGVN); |
| 1131 } | 1132 } |
| 1132 } | 1133 } |
| 1133 | 1134 |
| 1134 | 1135 |
| 1135 void HParameter::PrintDataTo(StringStream* stream) const { | 1136 void HParameter::PrintDataTo(StringStream* stream) const { |
| 1136 stream->Add("%u", index()); | 1137 stream->Add("%u", index()); |
| 1137 } | 1138 } |
| 1138 | 1139 |
| 1139 | 1140 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1183 if (check_hole_value()) stream->Add(" (deleteable/read-only)"); | 1184 if (check_hole_value()) stream->Add(" (deleteable/read-only)"); |
| 1184 } | 1185 } |
| 1185 | 1186 |
| 1186 | 1187 |
| 1187 void HStoreGlobal::PrintDataTo(StringStream* stream) const { | 1188 void HStoreGlobal::PrintDataTo(StringStream* stream) const { |
| 1188 stream->Add("[%p] = ", *cell()); | 1189 stream->Add("[%p] = ", *cell()); |
| 1189 value()->PrintNameTo(stream); | 1190 value()->PrintNameTo(stream); |
| 1190 } | 1191 } |
| 1191 | 1192 |
| 1192 | 1193 |
| 1194 void HLoadContextSlot::PrintDataTo(StringStream* stream) const { |
| 1195 stream->Add("(%d, %d)", context_chain_length(), slot_index()); |
| 1196 } |
| 1197 |
| 1198 |
| 1193 // Implementation of type inference and type conversions. Calculates | 1199 // Implementation of type inference and type conversions. Calculates |
| 1194 // the inferred type of this instruction based on the input operands. | 1200 // the inferred type of this instruction based on the input operands. |
| 1195 | 1201 |
| 1196 HType HValue::CalculateInferredType() const { | 1202 HType HValue::CalculateInferredType() const { |
| 1197 return type_; | 1203 return type_; |
| 1198 } | 1204 } |
| 1199 | 1205 |
| 1200 | 1206 |
| 1201 HType HCheckMap::CalculateInferredType() const { | 1207 HType HCheckMap::CalculateInferredType() const { |
| 1202 return value()->type(); | 1208 return value()->type(); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1242 HType HCompareJSObjectEq::CalculateInferredType() const { | 1248 HType HCompareJSObjectEq::CalculateInferredType() const { |
| 1243 return HType::Boolean(); | 1249 return HType::Boolean(); |
| 1244 } | 1250 } |
| 1245 | 1251 |
| 1246 | 1252 |
| 1247 HType HUnaryPredicate::CalculateInferredType() const { | 1253 HType HUnaryPredicate::CalculateInferredType() const { |
| 1248 return HType::Boolean(); | 1254 return HType::Boolean(); |
| 1249 } | 1255 } |
| 1250 | 1256 |
| 1251 | 1257 |
| 1258 HType HBitwiseBinaryOperation::CalculateInferredType() const { |
| 1259 return HType::TaggedNumber(); |
| 1260 } |
| 1261 |
| 1262 |
| 1252 HType HArithmeticBinaryOperation::CalculateInferredType() const { | 1263 HType HArithmeticBinaryOperation::CalculateInferredType() const { |
| 1253 return HType::TaggedNumber(); | 1264 return HType::TaggedNumber(); |
| 1254 } | 1265 } |
| 1255 | 1266 |
| 1256 | 1267 |
| 1257 HType HAdd::CalculateInferredType() const { | 1268 HType HAdd::CalculateInferredType() const { |
| 1258 return HType::Tagged(); | 1269 return HType::Tagged(); |
| 1259 } | 1270 } |
| 1260 | 1271 |
| 1261 | 1272 |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1375 if (range() == NULL || range()->CanBeMinusZero()) { | 1386 if (range() == NULL || range()->CanBeMinusZero()) { |
| 1376 return left(); | 1387 return left(); |
| 1377 } | 1388 } |
| 1378 return NULL; | 1389 return NULL; |
| 1379 } | 1390 } |
| 1380 | 1391 |
| 1381 | 1392 |
| 1382 // Node-specific verification code is only included in debug mode. | 1393 // Node-specific verification code is only included in debug mode. |
| 1383 #ifdef DEBUG | 1394 #ifdef DEBUG |
| 1384 | 1395 |
| 1385 void HPhi::Verify() const { | 1396 void HPhi::Verify() { |
| 1386 ASSERT(OperandCount() == block()->predecessors()->length()); | 1397 ASSERT(OperandCount() == block()->predecessors()->length()); |
| 1387 for (int i = 0; i < OperandCount(); ++i) { | 1398 for (int i = 0; i < OperandCount(); ++i) { |
| 1388 HValue* value = OperandAt(i); | 1399 HValue* value = OperandAt(i); |
| 1389 HBasicBlock* defining_block = value->block(); | 1400 HBasicBlock* defining_block = value->block(); |
| 1390 HBasicBlock* predecessor_block = block()->predecessors()->at(i); | 1401 HBasicBlock* predecessor_block = block()->predecessors()->at(i); |
| 1391 ASSERT(defining_block == predecessor_block || | 1402 ASSERT(defining_block == predecessor_block || |
| 1392 defining_block->Dominates(predecessor_block)); | 1403 defining_block->Dominates(predecessor_block)); |
| 1393 } | 1404 } |
| 1394 } | 1405 } |
| 1395 | 1406 |
| 1396 | 1407 |
| 1397 void HSimulate::Verify() const { | 1408 void HSimulate::Verify() { |
| 1398 HInstruction::Verify(); | 1409 HInstruction::Verify(); |
| 1399 ASSERT(HasAstId()); | 1410 ASSERT(HasAstId()); |
| 1400 } | 1411 } |
| 1401 | 1412 |
| 1402 | 1413 |
| 1403 void HBoundsCheck::Verify() const { | 1414 void HBoundsCheck::Verify() { |
| 1404 HInstruction::Verify(); | 1415 HInstruction::Verify(); |
| 1405 ASSERT(HasNoUses()); | 1416 ASSERT(HasNoUses()); |
| 1406 } | 1417 } |
| 1407 | 1418 |
| 1408 | 1419 |
| 1409 void HCheckSmi::Verify() const { | 1420 void HCheckSmi::Verify() { |
| 1410 HInstruction::Verify(); | 1421 HInstruction::Verify(); |
| 1411 ASSERT(HasNoUses()); | 1422 ASSERT(HasNoUses()); |
| 1412 } | 1423 } |
| 1413 | 1424 |
| 1414 | 1425 |
| 1415 void HCheckNonSmi::Verify() const { | 1426 void HCheckNonSmi::Verify() { |
| 1416 HInstruction::Verify(); | 1427 HInstruction::Verify(); |
| 1417 ASSERT(HasNoUses()); | 1428 ASSERT(HasNoUses()); |
| 1418 } | 1429 } |
| 1419 | 1430 |
| 1420 | 1431 |
| 1421 void HCheckInstanceType::Verify() const { | 1432 void HCheckInstanceType::Verify() { |
| 1422 HInstruction::Verify(); | 1433 HInstruction::Verify(); |
| 1423 ASSERT(HasNoUses()); | 1434 ASSERT(HasNoUses()); |
| 1424 } | 1435 } |
| 1425 | 1436 |
| 1426 | 1437 |
| 1427 void HCheckMap::Verify() const { | 1438 void HCheckMap::Verify() { |
| 1428 HInstruction::Verify(); | 1439 HInstruction::Verify(); |
| 1429 ASSERT(HasNoUses()); | 1440 ASSERT(HasNoUses()); |
| 1430 } | 1441 } |
| 1431 | 1442 |
| 1432 | 1443 |
| 1433 void HCheckFunction::Verify() const { | 1444 void HCheckFunction::Verify() { |
| 1434 HInstruction::Verify(); | 1445 HInstruction::Verify(); |
| 1435 ASSERT(HasNoUses()); | 1446 ASSERT(HasNoUses()); |
| 1436 } | 1447 } |
| 1437 | 1448 |
| 1438 | 1449 |
| 1439 void HCheckPrototypeMaps::Verify() const { | 1450 void HCheckPrototypeMaps::Verify() { |
| 1440 HInstruction::Verify(); | 1451 HInstruction::Verify(); |
| 1441 ASSERT(HasNoUses()); | 1452 ASSERT(HasNoUses()); |
| 1442 } | 1453 } |
| 1443 | 1454 |
| 1444 #endif | 1455 #endif |
| 1445 | 1456 |
| 1446 } } // namespace v8::internal | 1457 } } // namespace v8::internal |
| OLD | NEW |