| 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 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 50 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DEFINE_COMPILE) | 50 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DEFINE_COMPILE) |
| 51 #undef DEFINE_COMPILE | 51 #undef DEFINE_COMPILE |
| 52 | 52 |
| 53 | 53 |
| 54 const char* Representation::Mnemonic() const { | 54 const char* Representation::Mnemonic() const { |
| 55 switch (kind_) { | 55 switch (kind_) { |
| 56 case kNone: return "v"; | 56 case kNone: return "v"; |
| 57 case kTagged: return "t"; | 57 case kTagged: return "t"; |
| 58 case kDouble: return "d"; | 58 case kDouble: return "d"; |
| 59 case kInteger32: return "i"; | 59 case kInteger32: return "i"; |
| 60 default: | 60 case kExternal: return "x"; |
| 61 case kNumRepresentations: |
| 61 UNREACHABLE(); | 62 UNREACHABLE(); |
| 62 return NULL; | 63 return NULL; |
| 63 } | 64 } |
| 65 UNREACHABLE(); |
| 66 return NULL; |
| 64 } | 67 } |
| 65 | 68 |
| 66 | 69 |
| 67 static int32_t ConvertAndSetOverflow(int64_t result, bool* overflow) { | 70 static int32_t ConvertAndSetOverflow(int64_t result, bool* overflow) { |
| 68 if (result > kMaxInt) { | 71 if (result > kMaxInt) { |
| 69 *overflow = true; | 72 *overflow = true; |
| 70 return kMaxInt; | 73 return kMaxInt; |
| 71 } | 74 } |
| 72 if (result < kMinInt) { | 75 if (result < kMinInt) { |
| 73 *overflow = true; | 76 *overflow = true; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 110 | 113 |
| 111 void Range::AddConstant(int32_t value) { | 114 void Range::AddConstant(int32_t value) { |
| 112 if (value == 0) return; | 115 if (value == 0) return; |
| 113 bool may_overflow = false; // Overflow is ignored here. | 116 bool may_overflow = false; // Overflow is ignored here. |
| 114 lower_ = AddWithoutOverflow(lower_, value, &may_overflow); | 117 lower_ = AddWithoutOverflow(lower_, value, &may_overflow); |
| 115 upper_ = AddWithoutOverflow(upper_, value, &may_overflow); | 118 upper_ = AddWithoutOverflow(upper_, value, &may_overflow); |
| 116 Verify(); | 119 Verify(); |
| 117 } | 120 } |
| 118 | 121 |
| 119 | 122 |
| 123 void Range::Intersect(Range* other) { |
| 124 upper_ = Min(upper_, other->upper_); |
| 125 lower_ = Max(lower_, other->lower_); |
| 126 bool b = CanBeMinusZero() && other->CanBeMinusZero(); |
| 127 set_can_be_minus_zero(b); |
| 128 } |
| 129 |
| 130 |
| 131 void Range::Union(Range* other) { |
| 132 upper_ = Max(upper_, other->upper_); |
| 133 lower_ = Min(lower_, other->lower_); |
| 134 bool b = CanBeMinusZero() || other->CanBeMinusZero(); |
| 135 set_can_be_minus_zero(b); |
| 136 } |
| 137 |
| 138 |
| 139 void Range::Sar(int32_t value) { |
| 140 int32_t bits = value & 0x1F; |
| 141 lower_ = lower_ >> bits; |
| 142 upper_ = upper_ >> bits; |
| 143 set_can_be_minus_zero(false); |
| 144 } |
| 145 |
| 146 |
| 147 void Range::Shl(int32_t value) { |
| 148 int32_t bits = value & 0x1F; |
| 149 int old_lower = lower_; |
| 150 int old_upper = upper_; |
| 151 lower_ = lower_ << bits; |
| 152 upper_ = upper_ << bits; |
| 153 if (old_lower != lower_ >> bits || old_upper != upper_ >> bits) { |
| 154 upper_ = kMaxInt; |
| 155 lower_ = kMinInt; |
| 156 } |
| 157 set_can_be_minus_zero(false); |
| 158 } |
| 159 |
| 160 |
| 120 bool Range::AddAndCheckOverflow(Range* other) { | 161 bool Range::AddAndCheckOverflow(Range* other) { |
| 121 bool may_overflow = false; | 162 bool may_overflow = false; |
| 122 lower_ = AddWithoutOverflow(lower_, other->lower(), &may_overflow); | 163 lower_ = AddWithoutOverflow(lower_, other->lower(), &may_overflow); |
| 123 upper_ = AddWithoutOverflow(upper_, other->upper(), &may_overflow); | 164 upper_ = AddWithoutOverflow(upper_, other->upper(), &may_overflow); |
| 124 KeepOrder(); | 165 KeepOrder(); |
| 125 Verify(); | 166 Verify(); |
| 126 return may_overflow; | 167 return may_overflow; |
| 127 } | 168 } |
| 128 | 169 |
| 129 | 170 |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 214 result = HType::Boolean(); | 255 result = HType::Boolean(); |
| 215 } else if (value->IsJSObject()) { | 256 } else if (value->IsJSObject()) { |
| 216 result = HType::JSObject(); | 257 result = HType::JSObject(); |
| 217 } else if (value->IsJSArray()) { | 258 } else if (value->IsJSArray()) { |
| 218 result = HType::JSArray(); | 259 result = HType::JSArray(); |
| 219 } | 260 } |
| 220 return result; | 261 return result; |
| 221 } | 262 } |
| 222 | 263 |
| 223 | 264 |
| 224 int HValue::LookupOperandIndex(int occurrence_index, HValue* op) const { | 265 int HValue::LookupOperandIndex(int occurrence_index, HValue* op) { |
| 225 for (int i = 0; i < OperandCount(); ++i) { | 266 for (int i = 0; i < OperandCount(); ++i) { |
| 226 if (OperandAt(i) == op) { | 267 if (OperandAt(i) == op) { |
| 227 if (occurrence_index == 0) return i; | 268 if (occurrence_index == 0) return i; |
| 228 --occurrence_index; | 269 --occurrence_index; |
| 229 } | 270 } |
| 230 } | 271 } |
| 231 return -1; | 272 return -1; |
| 232 } | 273 } |
| 233 | 274 |
| 234 | 275 |
| 235 bool HValue::IsDefinedAfter(HBasicBlock* other) const { | 276 bool HValue::IsDefinedAfter(HBasicBlock* other) const { |
| 236 return block()->block_id() > other->block_id(); | 277 return block()->block_id() > other->block_id(); |
| 237 } | 278 } |
| 238 | 279 |
| 239 | 280 |
| 240 bool HValue::UsesMultipleTimes(HValue* op) const { | 281 bool HValue::UsesMultipleTimes(HValue* op) { |
| 241 bool seen = false; | 282 bool seen = false; |
| 242 for (int i = 0; i < OperandCount(); ++i) { | 283 for (int i = 0; i < OperandCount(); ++i) { |
| 243 if (OperandAt(i) == op) { | 284 if (OperandAt(i) == op) { |
| 244 if (seen) return true; | 285 if (seen) return true; |
| 245 seen = true; | 286 seen = true; |
| 246 } | 287 } |
| 247 } | 288 } |
| 248 return false; | 289 return false; |
| 249 } | 290 } |
| 250 | 291 |
| 251 | 292 |
| 252 bool HValue::Equals(HValue* other) const { | 293 bool HValue::Equals(HValue* other) { |
| 253 if (other->opcode() != opcode()) return false; | 294 if (other->opcode() != opcode()) return false; |
| 254 if (!other->representation().Equals(representation())) return false; | 295 if (!other->representation().Equals(representation())) return false; |
| 255 if (!other->type_.Equals(type_)) return false; | 296 if (!other->type_.Equals(type_)) return false; |
| 256 if (other->flags() != flags()) return false; | 297 if (other->flags() != flags()) return false; |
| 257 if (OperandCount() != other->OperandCount()) return false; | 298 if (OperandCount() != other->OperandCount()) return false; |
| 258 for (int i = 0; i < OperandCount(); ++i) { | 299 for (int i = 0; i < OperandCount(); ++i) { |
| 259 if (OperandAt(i)->id() != other->OperandAt(i)->id()) return false; | 300 if (OperandAt(i)->id() != other->OperandAt(i)->id()) return false; |
| 260 } | 301 } |
| 261 bool result = DataEquals(other); | 302 bool result = DataEquals(other); |
| 262 ASSERT(!result || Hashcode() == other->Hashcode()); | 303 ASSERT(!result || Hashcode() == other->Hashcode()); |
| 263 return result; | 304 return result; |
| 264 } | 305 } |
| 265 | 306 |
| 266 | 307 |
| 267 intptr_t HValue::Hashcode() const { | 308 intptr_t HValue::Hashcode() { |
| 268 intptr_t result = opcode(); | 309 intptr_t result = opcode(); |
| 269 int count = OperandCount(); | 310 int count = OperandCount(); |
| 270 for (int i = 0; i < count; ++i) { | 311 for (int i = 0; i < count; ++i) { |
| 271 result = result * 19 + OperandAt(i)->id() + (result >> 7); | 312 result = result * 19 + OperandAt(i)->id() + (result >> 7); |
| 272 } | 313 } |
| 273 return result; | 314 return result; |
| 274 } | 315 } |
| 275 | 316 |
| 276 | 317 |
| 277 void HValue::SetOperandAt(int index, HValue* value) { | 318 void HValue::SetOperandAt(int index, HValue* value) { |
| 278 ASSERT(value == NULL || !value->representation().IsNone()); | 319 ASSERT(value == NULL || !value->representation().IsNone()); |
| 279 RegisterUse(index, value); | 320 RegisterUse(index, value); |
| 280 InternalSetOperandAt(index, value); | 321 InternalSetOperandAt(index, value); |
| 281 } | 322 } |
| 282 | 323 |
| 283 | 324 |
| 284 void HLoadKeyedGeneric::InternalSetOperandAt(int index, HValue* value) { | |
| 285 if (index < 2) { | |
| 286 operands_[index] = value; | |
| 287 } else { | |
| 288 context_ = value; | |
| 289 } | |
| 290 } | |
| 291 | |
| 292 | |
| 293 void HStoreKeyedGeneric::InternalSetOperandAt(int index, HValue* value) { | |
| 294 if (index < 3) { | |
| 295 operands_[index] = value; | |
| 296 } else { | |
| 297 context_ = value; | |
| 298 } | |
| 299 } | |
| 300 | |
| 301 | |
| 302 void HStoreNamedGeneric::InternalSetOperandAt(int index, HValue* value) { | |
| 303 if (index < 2) { | |
| 304 operands_[index] = value; | |
| 305 } else { | |
| 306 context_ = value; | |
| 307 } | |
| 308 } | |
| 309 | |
| 310 | |
| 311 void HValue::ReplaceAndDelete(HValue* other) { | 325 void HValue::ReplaceAndDelete(HValue* other) { |
| 312 ReplaceValue(other); | 326 if (other != NULL) ReplaceValue(other); |
| 313 Delete(); | 327 Delete(); |
| 314 } | 328 } |
| 315 | 329 |
| 316 | 330 |
| 317 void HValue::ReplaceValue(HValue* other) { | 331 void HValue::ReplaceValue(HValue* other) { |
| 318 ZoneList<HValue*> start_uses(2); | |
| 319 for (int i = 0; i < uses_.length(); ++i) { | 332 for (int i = 0; i < uses_.length(); ++i) { |
| 320 HValue* use = uses_.at(i); | 333 HValue* use = uses_[i]; |
| 321 if (!use->block()->IsStartBlock()) { | 334 ASSERT(!use->block()->IsStartBlock()); |
| 322 InternalReplaceAtUse(use, other); | 335 InternalReplaceAtUse(use, other); |
| 323 other->uses_.Add(use); | 336 other->uses_.Add(use); |
| 324 } else { | |
| 325 start_uses.Add(use); | |
| 326 } | |
| 327 } | 337 } |
| 328 uses_.Clear(); | 338 uses_.Rewind(0); |
| 329 uses_.AddAll(start_uses); | |
| 330 } | 339 } |
| 331 | 340 |
| 332 | 341 |
| 333 void HValue::ClearOperands() { | 342 void HValue::ClearOperands() { |
| 334 for (int i = 0; i < OperandCount(); ++i) { | 343 for (int i = 0; i < OperandCount(); ++i) { |
| 335 SetOperandAt(i, NULL); | 344 SetOperandAt(i, NULL); |
| 336 } | 345 } |
| 337 } | 346 } |
| 338 | 347 |
| 339 | 348 |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 398 HType type = CalculateInferredType(); | 407 HType type = CalculateInferredType(); |
| 399 bool result = (!type.Equals(type_)); | 408 bool result = (!type.Equals(type_)); |
| 400 type_ = type; | 409 type_ = type; |
| 401 return result; | 410 return result; |
| 402 } | 411 } |
| 403 | 412 |
| 404 | 413 |
| 405 void HValue::RegisterUse(int index, HValue* new_value) { | 414 void HValue::RegisterUse(int index, HValue* new_value) { |
| 406 HValue* old_value = OperandAt(index); | 415 HValue* old_value = OperandAt(index); |
| 407 if (old_value == new_value) return; | 416 if (old_value == new_value) return; |
| 408 if (old_value != NULL) { | 417 if (old_value != NULL) old_value->uses_.RemoveElement(this); |
| 409 ASSERT(old_value->uses_.Contains(this)); | |
| 410 old_value->uses_.RemoveElement(this); | |
| 411 } | |
| 412 if (new_value != NULL) { | 418 if (new_value != NULL) { |
| 413 new_value->uses_.Add(this); | 419 new_value->uses_.Add(this); |
| 414 } | 420 } |
| 415 } | 421 } |
| 416 | 422 |
| 417 | 423 |
| 418 void HValue::AddNewRange(Range* r) { | 424 void HValue::AddNewRange(Range* r) { |
| 419 if (!HasRange()) ComputeInitialRange(); | 425 if (!HasRange()) ComputeInitialRange(); |
| 420 if (!HasRange()) range_ = new Range(); | 426 if (!HasRange()) range_ = new Range(); |
| 421 ASSERT(HasRange()); | 427 ASSERT(HasRange()); |
| 422 r->StackUpon(range_); | 428 r->StackUpon(range_); |
| 423 range_ = r; | 429 range_ = r; |
| 424 } | 430 } |
| 425 | 431 |
| 426 | 432 |
| 427 void HValue::RemoveLastAddedRange() { | 433 void HValue::RemoveLastAddedRange() { |
| 428 ASSERT(HasRange()); | 434 ASSERT(HasRange()); |
| 429 ASSERT(range_->next() != NULL); | 435 ASSERT(range_->next() != NULL); |
| 430 range_ = range_->next(); | 436 range_ = range_->next(); |
| 431 } | 437 } |
| 432 | 438 |
| 433 | 439 |
| 434 void HValue::ComputeInitialRange() { | 440 void HValue::ComputeInitialRange() { |
| 435 ASSERT(!HasRange()); | 441 ASSERT(!HasRange()); |
| 436 range_ = InferRange(); | 442 range_ = InferRange(); |
| 437 ASSERT(HasRange()); | 443 ASSERT(HasRange()); |
| 438 } | 444 } |
| 439 | 445 |
| 440 | 446 |
| 441 void HInstruction::PrintTo(StringStream* stream) const { | 447 void HInstruction::PrintTo(StringStream* stream) { |
| 442 stream->Add("%s", Mnemonic()); | 448 stream->Add("%s", Mnemonic()); |
| 443 if (HasSideEffects()) stream->Add("*"); | 449 if (HasSideEffects()) stream->Add("*"); |
| 444 stream->Add(" "); | 450 stream->Add(" "); |
| 445 PrintDataTo(stream); | 451 PrintDataTo(stream); |
| 446 | 452 |
| 447 if (range() != NULL) { | 453 if (range() != NULL && |
| 454 !range()->IsMostGeneric() && |
| 455 !range()->CanBeMinusZero()) { |
| 448 stream->Add(" range[%d,%d,m0=%d]", | 456 stream->Add(" range[%d,%d,m0=%d]", |
| 449 range()->lower(), | 457 range()->lower(), |
| 450 range()->upper(), | 458 range()->upper(), |
| 451 static_cast<int>(range()->CanBeMinusZero())); | 459 static_cast<int>(range()->CanBeMinusZero())); |
| 452 } | 460 } |
| 453 | 461 |
| 454 int changes_flags = (flags() & HValue::ChangesFlagsMask()); | 462 int changes_flags = (flags() & HValue::ChangesFlagsMask()); |
| 455 if (changes_flags != 0) { | 463 if (changes_flags != 0) { |
| 456 stream->Add(" changes[0x%x]", changes_flags); | 464 stream->Add(" changes[0x%x]", changes_flags); |
| 457 } | 465 } |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 554 } | 562 } |
| 555 | 563 |
| 556 // Verify that instructions that can be eliminated by GVN have overridden | 564 // Verify that instructions that can be eliminated by GVN have overridden |
| 557 // HValue::DataEquals. The default implementation is UNREACHABLE. We | 565 // HValue::DataEquals. The default implementation is UNREACHABLE. We |
| 558 // don't actually care whether DataEquals returns true or false here. | 566 // don't actually care whether DataEquals returns true or false here. |
| 559 if (CheckFlag(kUseGVN)) DataEquals(this); | 567 if (CheckFlag(kUseGVN)) DataEquals(this); |
| 560 } | 568 } |
| 561 #endif | 569 #endif |
| 562 | 570 |
| 563 | 571 |
| 564 void HCall::PrintDataTo(StringStream* stream) const { | 572 void HUnaryCall::PrintDataTo(StringStream* stream) { |
| 573 value()->PrintNameTo(stream); |
| 574 stream->Add(" "); |
| 565 stream->Add("#%d", argument_count()); | 575 stream->Add("#%d", argument_count()); |
| 566 } | 576 } |
| 567 | 577 |
| 568 | 578 |
| 569 void HUnaryCall::PrintDataTo(StringStream* stream) const { | 579 void HBinaryCall::PrintDataTo(StringStream* stream) { |
| 570 value()->PrintNameTo(stream); | |
| 571 stream->Add(" "); | |
| 572 HCall::PrintDataTo(stream); | |
| 573 } | |
| 574 | |
| 575 | |
| 576 void HBinaryCall::PrintDataTo(StringStream* stream) const { | |
| 577 first()->PrintNameTo(stream); | 580 first()->PrintNameTo(stream); |
| 578 stream->Add(" "); | 581 stream->Add(" "); |
| 579 second()->PrintNameTo(stream); | 582 second()->PrintNameTo(stream); |
| 580 stream->Add(" "); | 583 stream->Add(" "); |
| 581 HCall::PrintDataTo(stream); | 584 stream->Add("#%d", argument_count()); |
| 582 } | 585 } |
| 583 | 586 |
| 584 | 587 |
| 585 void HCallConstantFunction::PrintDataTo(StringStream* stream) const { | 588 void HCallConstantFunction::PrintDataTo(StringStream* stream) { |
| 586 if (IsApplyFunction()) { | 589 if (IsApplyFunction()) { |
| 587 stream->Add("optimized apply "); | 590 stream->Add("optimized apply "); |
| 588 } else { | 591 } else { |
| 589 stream->Add("%o ", function()->shared()->DebugName()); | 592 stream->Add("%o ", function()->shared()->DebugName()); |
| 590 } | 593 } |
| 591 HCall::PrintDataTo(stream); | 594 stream->Add("#%d", argument_count()); |
| 592 } | 595 } |
| 593 | 596 |
| 594 | 597 |
| 595 void HCallNamed::PrintDataTo(StringStream* stream) const { | 598 void HCallNamed::PrintDataTo(StringStream* stream) { |
| 596 stream->Add("%o ", *name()); | 599 stream->Add("%o ", *name()); |
| 597 HUnaryCall::PrintDataTo(stream); | 600 HUnaryCall::PrintDataTo(stream); |
| 598 } | 601 } |
| 599 | 602 |
| 600 | 603 |
| 601 void HCallGlobal::PrintDataTo(StringStream* stream) const { | 604 void HCallGlobal::PrintDataTo(StringStream* stream) { |
| 602 stream->Add("%o ", *name()); | 605 stream->Add("%o ", *name()); |
| 603 HUnaryCall::PrintDataTo(stream); | 606 HUnaryCall::PrintDataTo(stream); |
| 604 } | 607 } |
| 605 | 608 |
| 606 | 609 |
| 607 void HCallKnownGlobal::PrintDataTo(StringStream* stream) const { | 610 void HCallKnownGlobal::PrintDataTo(StringStream* stream) { |
| 608 stream->Add("o ", target()->shared()->DebugName()); | 611 stream->Add("o ", target()->shared()->DebugName()); |
| 609 HCall::PrintDataTo(stream); | 612 stream->Add("#%d", argument_count()); |
| 610 } | 613 } |
| 611 | 614 |
| 612 | 615 |
| 613 void HCallRuntime::PrintDataTo(StringStream* stream) const { | 616 void HCallRuntime::PrintDataTo(StringStream* stream) { |
| 614 stream->Add("%o ", *name()); | 617 stream->Add("%o ", *name()); |
| 615 HCall::PrintDataTo(stream); | 618 stream->Add("#%d", argument_count()); |
| 616 } | 619 } |
| 617 | 620 |
| 618 | 621 |
| 619 void HClassOfTest::PrintDataTo(StringStream* stream) const { | 622 void HClassOfTest::PrintDataTo(StringStream* stream) { |
| 620 stream->Add("class_of_test("); | 623 stream->Add("class_of_test("); |
| 621 value()->PrintNameTo(stream); | 624 value()->PrintNameTo(stream); |
| 622 stream->Add(", \"%o\")", *class_name()); | 625 stream->Add(", \"%o\")", *class_name()); |
| 623 } | 626 } |
| 624 | 627 |
| 625 | 628 |
| 626 void HAccessArgumentsAt::PrintDataTo(StringStream* stream) const { | 629 void HAccessArgumentsAt::PrintDataTo(StringStream* stream) { |
| 627 arguments()->PrintNameTo(stream); | 630 arguments()->PrintNameTo(stream); |
| 628 stream->Add("["); | 631 stream->Add("["); |
| 629 index()->PrintNameTo(stream); | 632 index()->PrintNameTo(stream); |
| 630 stream->Add("], length "); | 633 stream->Add("], length "); |
| 631 length()->PrintNameTo(stream); | 634 length()->PrintNameTo(stream); |
| 632 } | 635 } |
| 633 | 636 |
| 634 | 637 |
| 635 void HControlInstruction::PrintDataTo(StringStream* stream) const { | 638 void HControlInstruction::PrintDataTo(StringStream* stream) { |
| 636 if (FirstSuccessor() != NULL) { | 639 if (FirstSuccessor() != NULL) { |
| 637 int first_id = FirstSuccessor()->block_id(); | 640 int first_id = FirstSuccessor()->block_id(); |
| 638 if (SecondSuccessor() == NULL) { | 641 if (SecondSuccessor() == NULL) { |
| 639 stream->Add(" B%d", first_id); | 642 stream->Add(" B%d", first_id); |
| 640 } else { | 643 } else { |
| 641 int second_id = SecondSuccessor()->block_id(); | 644 int second_id = SecondSuccessor()->block_id(); |
| 642 stream->Add(" goto (B%d, B%d)", first_id, second_id); | 645 stream->Add(" goto (B%d, B%d)", first_id, second_id); |
| 643 } | 646 } |
| 644 } | 647 } |
| 645 } | 648 } |
| 646 | 649 |
| 647 | 650 |
| 648 void HUnaryControlInstruction::PrintDataTo(StringStream* stream) const { | 651 void HUnaryControlInstruction::PrintDataTo(StringStream* stream) { |
| 649 value()->PrintNameTo(stream); | 652 value()->PrintNameTo(stream); |
| 650 HControlInstruction::PrintDataTo(stream); | 653 HControlInstruction::PrintDataTo(stream); |
| 651 } | 654 } |
| 652 | 655 |
| 653 | 656 |
| 654 void HCompareMap::PrintDataTo(StringStream* stream) const { | 657 void HCompareMap::PrintDataTo(StringStream* stream) { |
| 655 value()->PrintNameTo(stream); | 658 value()->PrintNameTo(stream); |
| 656 stream->Add(" (%p)", *map()); | 659 stream->Add(" (%p)", *map()); |
| 657 HControlInstruction::PrintDataTo(stream); | 660 HControlInstruction::PrintDataTo(stream); |
| 658 } | 661 } |
| 659 | 662 |
| 660 | 663 |
| 661 const char* HUnaryMathOperation::OpName() const { | 664 const char* HUnaryMathOperation::OpName() const { |
| 662 switch (op()) { | 665 switch (op()) { |
| 663 case kMathFloor: return "floor"; | 666 case kMathFloor: return "floor"; |
| 664 case kMathRound: return "round"; | 667 case kMathRound: return "round"; |
| 665 case kMathCeil: return "ceil"; | 668 case kMathCeil: return "ceil"; |
| 666 case kMathAbs: return "abs"; | 669 case kMathAbs: return "abs"; |
| 667 case kMathLog: return "log"; | 670 case kMathLog: return "log"; |
| 668 case kMathSin: return "sin"; | 671 case kMathSin: return "sin"; |
| 669 case kMathCos: return "cos"; | 672 case kMathCos: return "cos"; |
| 670 case kMathTan: return "tan"; | 673 case kMathTan: return "tan"; |
| 671 case kMathASin: return "asin"; | 674 case kMathASin: return "asin"; |
| 672 case kMathACos: return "acos"; | 675 case kMathACos: return "acos"; |
| 673 case kMathATan: return "atan"; | 676 case kMathATan: return "atan"; |
| 674 case kMathExp: return "exp"; | 677 case kMathExp: return "exp"; |
| 675 case kMathSqrt: return "sqrt"; | 678 case kMathSqrt: return "sqrt"; |
| 676 default: break; | 679 default: break; |
| 677 } | 680 } |
| 678 return "(unknown operation)"; | 681 return "(unknown operation)"; |
| 679 } | 682 } |
| 680 | 683 |
| 681 | 684 |
| 682 void HUnaryMathOperation::PrintDataTo(StringStream* stream) const { | 685 void HUnaryMathOperation::PrintDataTo(StringStream* stream) { |
| 683 const char* name = OpName(); | 686 const char* name = OpName(); |
| 684 stream->Add("%s ", name); | 687 stream->Add("%s ", name); |
| 685 value()->PrintNameTo(stream); | 688 value()->PrintNameTo(stream); |
| 686 } | 689 } |
| 687 | 690 |
| 688 | 691 |
| 689 void HUnaryOperation::PrintDataTo(StringStream* stream) const { | 692 void HUnaryOperation::PrintDataTo(StringStream* stream) { |
| 690 value()->PrintNameTo(stream); | 693 value()->PrintNameTo(stream); |
| 691 } | 694 } |
| 692 | 695 |
| 693 | 696 |
| 694 void HHasInstanceType::PrintDataTo(StringStream* stream) const { | 697 void HHasInstanceType::PrintDataTo(StringStream* stream) { |
| 695 value()->PrintNameTo(stream); | 698 value()->PrintNameTo(stream); |
| 696 switch (from_) { | 699 switch (from_) { |
| 697 case FIRST_JS_OBJECT_TYPE: | 700 case FIRST_JS_OBJECT_TYPE: |
| 698 if (to_ == LAST_TYPE) stream->Add(" spec_object"); | 701 if (to_ == LAST_TYPE) stream->Add(" spec_object"); |
| 699 break; | 702 break; |
| 700 case JS_REGEXP_TYPE: | 703 case JS_REGEXP_TYPE: |
| 701 if (to_ == JS_REGEXP_TYPE) stream->Add(" reg_exp"); | 704 if (to_ == JS_REGEXP_TYPE) stream->Add(" reg_exp"); |
| 702 break; | 705 break; |
| 703 case JS_ARRAY_TYPE: | 706 case JS_ARRAY_TYPE: |
| 704 if (to_ == JS_ARRAY_TYPE) stream->Add(" array"); | 707 if (to_ == JS_ARRAY_TYPE) stream->Add(" array"); |
| 705 break; | 708 break; |
| 706 case JS_FUNCTION_TYPE: | 709 case JS_FUNCTION_TYPE: |
| 707 if (to_ == JS_FUNCTION_TYPE) stream->Add(" function"); | 710 if (to_ == JS_FUNCTION_TYPE) stream->Add(" function"); |
| 708 break; | 711 break; |
| 709 default: | 712 default: |
| 710 break; | 713 break; |
| 711 } | 714 } |
| 712 } | 715 } |
| 713 | 716 |
| 714 | 717 |
| 715 void HTypeofIs::PrintDataTo(StringStream* stream) const { | 718 void HTypeofIs::PrintDataTo(StringStream* stream) { |
| 716 value()->PrintNameTo(stream); | 719 value()->PrintNameTo(stream); |
| 717 stream->Add(" == "); | 720 stream->Add(" == "); |
| 718 stream->Add(type_literal_->ToAsciiVector()); | 721 stream->Add(type_literal_->ToAsciiVector()); |
| 719 } | 722 } |
| 720 | 723 |
| 721 | 724 |
| 722 void HChange::PrintDataTo(StringStream* stream) const { | 725 void HChange::PrintDataTo(StringStream* stream) { |
| 723 HUnaryOperation::PrintDataTo(stream); | 726 HUnaryOperation::PrintDataTo(stream); |
| 724 stream->Add(" %s to %s", from_.Mnemonic(), to_.Mnemonic()); | 727 stream->Add(" %s to %s", from_.Mnemonic(), to_.Mnemonic()); |
| 725 | 728 |
| 726 if (CanTruncateToInt32()) stream->Add(" truncating-int32"); | 729 if (CanTruncateToInt32()) stream->Add(" truncating-int32"); |
| 727 if (CheckFlag(kBailoutOnMinusZero)) stream->Add(" -0?"); | 730 if (CheckFlag(kBailoutOnMinusZero)) stream->Add(" -0?"); |
| 728 } | 731 } |
| 729 | 732 |
| 730 | 733 |
| 731 HCheckInstanceType* HCheckInstanceType::NewIsJSObjectOrJSFunction( | 734 HCheckInstanceType* HCheckInstanceType::NewIsJSObjectOrJSFunction( |
| 732 HValue* value) { | 735 HValue* value) { |
| 733 STATIC_ASSERT((LAST_JS_OBJECT_TYPE + 1) == JS_FUNCTION_TYPE); | 736 STATIC_ASSERT((LAST_JS_OBJECT_TYPE + 1) == JS_FUNCTION_TYPE); |
| 734 return new HCheckInstanceType(value, FIRST_JS_OBJECT_TYPE, JS_FUNCTION_TYPE); | 737 return new HCheckInstanceType(value, FIRST_JS_OBJECT_TYPE, JS_FUNCTION_TYPE); |
| 735 } | 738 } |
| 736 | 739 |
| 737 | 740 |
| 738 void HCheckMap::PrintDataTo(StringStream* stream) const { | 741 void HCheckMap::PrintDataTo(StringStream* stream) { |
| 739 value()->PrintNameTo(stream); | 742 value()->PrintNameTo(stream); |
| 740 stream->Add(" %p", *map()); | 743 stream->Add(" %p", *map()); |
| 741 } | 744 } |
| 742 | 745 |
| 743 | 746 |
| 744 void HCheckFunction::PrintDataTo(StringStream* stream) const { | 747 void HCheckFunction::PrintDataTo(StringStream* stream) { |
| 745 value()->PrintNameTo(stream); | 748 value()->PrintNameTo(stream); |
| 746 stream->Add(" %p", *target()); | 749 stream->Add(" %p", *target()); |
| 747 } | 750 } |
| 748 | 751 |
| 749 | 752 |
| 750 void HCallStub::PrintDataTo(StringStream* stream) const { | 753 void HCallStub::PrintDataTo(StringStream* stream) { |
| 751 stream->Add("%s ", | 754 stream->Add("%s ", |
| 752 CodeStub::MajorName(major_key_, false)); | 755 CodeStub::MajorName(major_key_, false)); |
| 753 HUnaryCall::PrintDataTo(stream); | 756 HUnaryCall::PrintDataTo(stream); |
| 754 } | 757 } |
| 755 | 758 |
| 756 | 759 |
| 757 void HInstanceOf::PrintDataTo(StringStream* stream) const { | 760 void HInstanceOf::PrintDataTo(StringStream* stream) { |
| 758 left()->PrintNameTo(stream); | 761 left()->PrintNameTo(stream); |
| 759 stream->Add(" "); | 762 stream->Add(" "); |
| 760 right()->PrintNameTo(stream); | 763 right()->PrintNameTo(stream); |
| 761 stream->Add(" "); | 764 stream->Add(" "); |
| 762 context()->PrintNameTo(stream); | 765 context()->PrintNameTo(stream); |
| 763 } | 766 } |
| 764 | 767 |
| 765 | 768 |
| 766 Range* HValue::InferRange() { | 769 Range* HValue::InferRange() { |
| 767 if (representation().IsTagged()) { | 770 if (representation().IsTagged()) { |
| 768 // Tagged values are always in int32 range when converted to integer, | 771 // Tagged values are always in int32 range when converted to integer, |
| 769 // but they can contain -0. | 772 // but they can contain -0. |
| 770 Range* result = new Range(); | 773 Range* result = new Range(); |
| 771 result->set_can_be_minus_zero(true); | 774 result->set_can_be_minus_zero(true); |
| 772 return result; | 775 return result; |
| 773 } else if (representation().IsNone()) { | 776 } else if (representation().IsNone()) { |
| 774 return NULL; | 777 return NULL; |
| 775 } else { | 778 } else { |
| 779 // Untagged integer32 cannot be -0 and we don't compute ranges for |
| 780 // untagged doubles. |
| 776 return new Range(); | 781 return new Range(); |
| 777 } | 782 } |
| 778 } | 783 } |
| 779 | 784 |
| 780 | 785 |
| 781 Range* HConstant::InferRange() { | 786 Range* HConstant::InferRange() { |
| 782 if (has_int32_value_) { | 787 if (has_int32_value_) { |
| 783 Range* result = new Range(int32_value_, int32_value_); | 788 Range* result = new Range(int32_value_, int32_value_); |
| 784 result->set_can_be_minus_zero(false); | 789 result->set_can_be_minus_zero(false); |
| 785 return result; | 790 return result; |
| 786 } | 791 } |
| 787 return HInstruction::InferRange(); | 792 return HValue::InferRange(); |
| 788 } | 793 } |
| 789 | 794 |
| 790 | 795 |
| 791 Range* HPhi::InferRange() { | 796 Range* HPhi::InferRange() { |
| 792 if (representation().IsInteger32()) { | 797 if (representation().IsInteger32()) { |
| 793 if (block()->IsLoopHeader()) { | 798 if (block()->IsLoopHeader()) { |
| 794 Range* range = new Range(kMinInt, kMaxInt); | 799 Range* range = new Range(kMinInt, kMaxInt); |
| 795 return range; | 800 return range; |
| 796 } else { | 801 } else { |
| 797 Range* range = OperandAt(0)->range()->Copy(); | 802 Range* range = OperandAt(0)->range()->Copy(); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 811 Range* a = left()->range(); | 816 Range* a = left()->range(); |
| 812 Range* b = right()->range(); | 817 Range* b = right()->range(); |
| 813 Range* res = a->Copy(); | 818 Range* res = a->Copy(); |
| 814 if (!res->AddAndCheckOverflow(b)) { | 819 if (!res->AddAndCheckOverflow(b)) { |
| 815 ClearFlag(kCanOverflow); | 820 ClearFlag(kCanOverflow); |
| 816 } | 821 } |
| 817 bool m0 = a->CanBeMinusZero() && b->CanBeMinusZero(); | 822 bool m0 = a->CanBeMinusZero() && b->CanBeMinusZero(); |
| 818 res->set_can_be_minus_zero(m0); | 823 res->set_can_be_minus_zero(m0); |
| 819 return res; | 824 return res; |
| 820 } else { | 825 } else { |
| 821 return HArithmeticBinaryOperation::InferRange(); | 826 return HValue::InferRange(); |
| 822 } | 827 } |
| 823 } | 828 } |
| 824 | 829 |
| 825 | 830 |
| 826 Range* HSub::InferRange() { | 831 Range* HSub::InferRange() { |
| 827 if (representation().IsInteger32()) { | 832 if (representation().IsInteger32()) { |
| 828 Range* a = left()->range(); | 833 Range* a = left()->range(); |
| 829 Range* b = right()->range(); | 834 Range* b = right()->range(); |
| 830 Range* res = a->Copy(); | 835 Range* res = a->Copy(); |
| 831 if (!res->SubAndCheckOverflow(b)) { | 836 if (!res->SubAndCheckOverflow(b)) { |
| 832 ClearFlag(kCanOverflow); | 837 ClearFlag(kCanOverflow); |
| 833 } | 838 } |
| 834 res->set_can_be_minus_zero(a->CanBeMinusZero() && b->CanBeZero()); | 839 res->set_can_be_minus_zero(a->CanBeMinusZero() && b->CanBeZero()); |
| 835 return res; | 840 return res; |
| 836 } else { | 841 } else { |
| 837 return HArithmeticBinaryOperation::InferRange(); | 842 return HValue::InferRange(); |
| 838 } | 843 } |
| 839 } | 844 } |
| 840 | 845 |
| 841 | 846 |
| 842 Range* HMul::InferRange() { | 847 Range* HMul::InferRange() { |
| 843 if (representation().IsInteger32()) { | 848 if (representation().IsInteger32()) { |
| 844 Range* a = left()->range(); | 849 Range* a = left()->range(); |
| 845 Range* b = right()->range(); | 850 Range* b = right()->range(); |
| 846 Range* res = a->Copy(); | 851 Range* res = a->Copy(); |
| 847 if (!res->MulAndCheckOverflow(b)) { | 852 if (!res->MulAndCheckOverflow(b)) { |
| 848 ClearFlag(kCanOverflow); | 853 ClearFlag(kCanOverflow); |
| 849 } | 854 } |
| 850 bool m0 = (a->CanBeZero() && b->CanBeNegative()) || | 855 bool m0 = (a->CanBeZero() && b->CanBeNegative()) || |
| 851 (a->CanBeNegative() && b->CanBeZero()); | 856 (a->CanBeNegative() && b->CanBeZero()); |
| 852 res->set_can_be_minus_zero(m0); | 857 res->set_can_be_minus_zero(m0); |
| 853 return res; | 858 return res; |
| 854 } else { | 859 } else { |
| 855 return HArithmeticBinaryOperation::InferRange(); | 860 return HValue::InferRange(); |
| 856 } | 861 } |
| 857 } | 862 } |
| 858 | 863 |
| 859 | 864 |
| 860 Range* HDiv::InferRange() { | 865 Range* HDiv::InferRange() { |
| 861 if (representation().IsInteger32()) { | 866 if (representation().IsInteger32()) { |
| 862 Range* result = new Range(); | 867 Range* result = new Range(); |
| 863 if (left()->range()->CanBeMinusZero()) { | 868 if (left()->range()->CanBeMinusZero()) { |
| 864 result->set_can_be_minus_zero(true); | 869 result->set_can_be_minus_zero(true); |
| 865 } | 870 } |
| 866 | 871 |
| 867 if (left()->range()->CanBeZero() && right()->range()->CanBeNegative()) { | 872 if (left()->range()->CanBeZero() && right()->range()->CanBeNegative()) { |
| 868 result->set_can_be_minus_zero(true); | 873 result->set_can_be_minus_zero(true); |
| 869 } | 874 } |
| 870 | 875 |
| 871 if (right()->range()->Includes(-1) && left()->range()->Includes(kMinInt)) { | 876 if (right()->range()->Includes(-1) && left()->range()->Includes(kMinInt)) { |
| 872 SetFlag(HValue::kCanOverflow); | 877 SetFlag(HValue::kCanOverflow); |
| 873 } | 878 } |
| 874 | 879 |
| 875 if (!right()->range()->CanBeZero()) { | 880 if (!right()->range()->CanBeZero()) { |
| 876 ClearFlag(HValue::kCanBeDivByZero); | 881 ClearFlag(HValue::kCanBeDivByZero); |
| 877 } | 882 } |
| 878 return result; | 883 return result; |
| 879 } else { | 884 } else { |
| 880 return HArithmeticBinaryOperation::InferRange(); | 885 return HValue::InferRange(); |
| 881 } | 886 } |
| 882 } | 887 } |
| 883 | 888 |
| 884 | 889 |
| 885 Range* HMod::InferRange() { | 890 Range* HMod::InferRange() { |
| 886 if (representation().IsInteger32()) { | 891 if (representation().IsInteger32()) { |
| 887 Range* a = left()->range(); | 892 Range* a = left()->range(); |
| 888 Range* result = new Range(); | 893 Range* result = new Range(); |
| 889 if (a->CanBeMinusZero() || a->CanBeNegative()) { | 894 if (a->CanBeMinusZero() || a->CanBeNegative()) { |
| 890 result->set_can_be_minus_zero(true); | 895 result->set_can_be_minus_zero(true); |
| 891 } | 896 } |
| 892 if (!right()->range()->CanBeZero()) { | 897 if (!right()->range()->CanBeZero()) { |
| 893 ClearFlag(HValue::kCanBeDivByZero); | 898 ClearFlag(HValue::kCanBeDivByZero); |
| 894 } | 899 } |
| 895 return result; | 900 return result; |
| 896 } else { | 901 } else { |
| 897 return HArithmeticBinaryOperation::InferRange(); | 902 return HValue::InferRange(); |
| 898 } | 903 } |
| 899 } | 904 } |
| 900 | 905 |
| 901 | 906 |
| 902 void HPhi::PrintTo(StringStream* stream) const { | 907 void HPhi::PrintTo(StringStream* stream) { |
| 903 stream->Add("["); | 908 stream->Add("["); |
| 904 for (int i = 0; i < OperandCount(); ++i) { | 909 for (int i = 0; i < OperandCount(); ++i) { |
| 905 HValue* value = OperandAt(i); | 910 HValue* value = OperandAt(i); |
| 906 stream->Add(" "); | 911 stream->Add(" "); |
| 907 value->PrintNameTo(stream); | 912 value->PrintNameTo(stream); |
| 908 stream->Add(" "); | 913 stream->Add(" "); |
| 909 } | 914 } |
| 910 stream->Add(" uses%d_%di_%dd_%dt]", | 915 stream->Add(" uses%d_%di_%dd_%dt]", |
| 911 uses()->length(), | 916 uses()->length(), |
| 912 int32_non_phi_uses() + int32_indirect_uses(), | 917 int32_non_phi_uses() + int32_indirect_uses(), |
| 913 double_non_phi_uses() + double_indirect_uses(), | 918 double_non_phi_uses() + double_indirect_uses(), |
| 914 tagged_non_phi_uses() + tagged_indirect_uses()); | 919 tagged_non_phi_uses() + tagged_indirect_uses()); |
| 915 } | 920 } |
| 916 | 921 |
| 917 | 922 |
| 918 void HPhi::AddInput(HValue* value) { | 923 void HPhi::AddInput(HValue* value) { |
| 919 inputs_.Add(NULL); | 924 inputs_.Add(NULL); |
| 920 SetOperandAt(OperandCount() - 1, value); | 925 SetOperandAt(OperandCount() - 1, value); |
| 921 // Mark phis that may have 'arguments' directly or indirectly as an operand. | 926 // Mark phis that may have 'arguments' directly or indirectly as an operand. |
| 922 if (!CheckFlag(kIsArguments) && value->CheckFlag(kIsArguments)) { | 927 if (!CheckFlag(kIsArguments) && value->CheckFlag(kIsArguments)) { |
| 923 SetFlag(kIsArguments); | 928 SetFlag(kIsArguments); |
| 924 } | 929 } |
| 925 } | 930 } |
| 926 | 931 |
| 927 | 932 |
| 928 HValue* HPhi::GetRedundantReplacement() const { | 933 bool HPhi::HasRealUses() { |
| 934 for (int i = 0; i < uses()->length(); i++) { |
| 935 if (!uses()->at(i)->IsPhi()) return true; |
| 936 } |
| 937 return false; |
| 938 } |
| 939 |
| 940 |
| 941 HValue* HPhi::GetRedundantReplacement() { |
| 929 HValue* candidate = NULL; | 942 HValue* candidate = NULL; |
| 930 int count = OperandCount(); | 943 int count = OperandCount(); |
| 931 int position = 0; | 944 int position = 0; |
| 932 while (position < count && candidate == NULL) { | 945 while (position < count && candidate == NULL) { |
| 933 HValue* current = OperandAt(position++); | 946 HValue* current = OperandAt(position++); |
| 934 if (current != this) candidate = current; | 947 if (current != this) candidate = current; |
| 935 } | 948 } |
| 936 while (position < count) { | 949 while (position < count) { |
| 937 HValue* current = OperandAt(position++); | 950 HValue* current = OperandAt(position++); |
| 938 if (current != this && current != candidate) return NULL; | 951 if (current != this && current != candidate) return NULL; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 970 } | 983 } |
| 971 | 984 |
| 972 | 985 |
| 973 void HPhi::AddIndirectUsesTo(int* dest) { | 986 void HPhi::AddIndirectUsesTo(int* dest) { |
| 974 for (int i = 0; i < Representation::kNumRepresentations; i++) { | 987 for (int i = 0; i < Representation::kNumRepresentations; i++) { |
| 975 dest[i] += indirect_uses_[i]; | 988 dest[i] += indirect_uses_[i]; |
| 976 } | 989 } |
| 977 } | 990 } |
| 978 | 991 |
| 979 | 992 |
| 980 void HSimulate::PrintDataTo(StringStream* stream) const { | 993 void HSimulate::PrintDataTo(StringStream* stream) { |
| 981 stream->Add("id=%d ", ast_id()); | 994 stream->Add("id=%d ", ast_id()); |
| 982 if (pop_count_ > 0) stream->Add("pop %d", pop_count_); | 995 if (pop_count_ > 0) stream->Add("pop %d", pop_count_); |
| 983 if (values_.length() > 0) { | 996 if (values_.length() > 0) { |
| 984 if (pop_count_ > 0) stream->Add(" /"); | 997 if (pop_count_ > 0) stream->Add(" /"); |
| 985 for (int i = 0; i < values_.length(); ++i) { | 998 for (int i = 0; i < values_.length(); ++i) { |
| 986 if (!HasAssignedIndexAt(i)) { | 999 if (!HasAssignedIndexAt(i)) { |
| 987 stream->Add(" push "); | 1000 stream->Add(" push "); |
| 988 } else { | 1001 } else { |
| 989 stream->Add(" var[%d] = ", GetAssignedIndexAt(i)); | 1002 stream->Add(" var[%d] = ", GetAssignedIndexAt(i)); |
| 990 } | 1003 } |
| 991 values_[i]->PrintNameTo(stream); | 1004 values_[i]->PrintNameTo(stream); |
| 992 } | 1005 } |
| 993 } | 1006 } |
| 994 } | 1007 } |
| 995 | 1008 |
| 996 | 1009 |
| 997 void HEnterInlined::PrintDataTo(StringStream* stream) const { | 1010 void HEnterInlined::PrintDataTo(StringStream* stream) { |
| 998 SmartPointer<char> name = function()->debug_name()->ToCString(); | 1011 SmartPointer<char> name = function()->debug_name()->ToCString(); |
| 999 stream->Add("%s, id=%d", *name, function()->id()); | 1012 stream->Add("%s, id=%d", *name, function()->id()); |
| 1000 } | 1013 } |
| 1001 | 1014 |
| 1002 | 1015 |
| 1003 HConstant::HConstant(Handle<Object> handle, Representation r) | 1016 HConstant::HConstant(Handle<Object> handle, Representation r) |
| 1004 : handle_(handle), | 1017 : handle_(handle), |
| 1005 constant_type_(HType::TypeFromValue(handle)), | 1018 constant_type_(HType::TypeFromValue(handle)), |
| 1006 has_int32_value_(false), | 1019 has_int32_value_(false), |
| 1007 int32_value_(0), | 1020 int32_value_(0), |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1028 | 1041 |
| 1029 | 1042 |
| 1030 HConstant* HConstant::CopyToTruncatedInt32() const { | 1043 HConstant* HConstant::CopyToTruncatedInt32() const { |
| 1031 if (!has_double_value_) return NULL; | 1044 if (!has_double_value_) return NULL; |
| 1032 int32_t truncated = NumberToInt32(*handle_); | 1045 int32_t truncated = NumberToInt32(*handle_); |
| 1033 return new HConstant(Factory::NewNumberFromInt(truncated), | 1046 return new HConstant(Factory::NewNumberFromInt(truncated), |
| 1034 Representation::Integer32()); | 1047 Representation::Integer32()); |
| 1035 } | 1048 } |
| 1036 | 1049 |
| 1037 | 1050 |
| 1038 void HConstant::PrintDataTo(StringStream* stream) const { | 1051 void HConstant::PrintDataTo(StringStream* stream) { |
| 1039 handle()->ShortPrint(stream); | 1052 handle()->ShortPrint(stream); |
| 1040 } | 1053 } |
| 1041 | 1054 |
| 1042 | 1055 |
| 1043 bool HArrayLiteral::IsCopyOnWrite() const { | 1056 bool HArrayLiteral::IsCopyOnWrite() const { |
| 1044 return constant_elements()->map() == Heap::fixed_cow_array_map(); | 1057 return constant_elements()->map() == Heap::fixed_cow_array_map(); |
| 1045 } | 1058 } |
| 1046 | 1059 |
| 1047 | 1060 |
| 1048 void HBinaryOperation::PrintDataTo(StringStream* stream) const { | 1061 void HBinaryOperation::PrintDataTo(StringStream* stream) { |
| 1049 left()->PrintNameTo(stream); | 1062 left()->PrintNameTo(stream); |
| 1050 stream->Add(" "); | 1063 stream->Add(" "); |
| 1051 right()->PrintNameTo(stream); | 1064 right()->PrintNameTo(stream); |
| 1052 if (CheckFlag(kCanOverflow)) stream->Add(" !"); | 1065 if (CheckFlag(kCanOverflow)) stream->Add(" !"); |
| 1053 if (CheckFlag(kBailoutOnMinusZero)) stream->Add(" -0?"); | 1066 if (CheckFlag(kBailoutOnMinusZero)) stream->Add(" -0?"); |
| 1054 } | 1067 } |
| 1055 | 1068 |
| 1056 | 1069 |
| 1057 Range* HBitAnd::InferRange() { | 1070 Range* HBitAnd::InferRange() { |
| 1058 Range* a = left()->range(); | 1071 int32_t left_mask = (left()->range() != NULL) |
| 1059 Range* b = right()->range(); | 1072 ? left()->range()->Mask() |
| 1060 int32_t a_mask = 0xffffffff; | 1073 : 0xffffffff; |
| 1061 int32_t b_mask = 0xffffffff; | 1074 int32_t right_mask = (right()->range() != NULL) |
| 1062 if (a != NULL) a_mask = a->Mask(); | 1075 ? right()->range()->Mask() |
| 1063 if (b != NULL) b_mask = b->Mask(); | 1076 : 0xffffffff; |
| 1064 int32_t result_mask = a_mask & b_mask; | 1077 int32_t result_mask = left_mask & right_mask; |
| 1065 if (result_mask >= 0) { | 1078 return (result_mask >= 0) |
| 1066 return new Range(0, result_mask); | 1079 ? new Range(0, result_mask) |
| 1067 } else { | 1080 : HValue::InferRange(); |
| 1068 return HBinaryOperation::InferRange(); | |
| 1069 } | |
| 1070 } | 1081 } |
| 1071 | 1082 |
| 1072 | 1083 |
| 1073 Range* HBitOr::InferRange() { | 1084 Range* HBitOr::InferRange() { |
| 1074 Range* a = left()->range(); | 1085 int32_t left_mask = (left()->range() != NULL) |
| 1075 Range* b = right()->range(); | 1086 ? left()->range()->Mask() |
| 1076 int32_t a_mask = 0xffffffff; | 1087 : 0xffffffff; |
| 1077 int32_t b_mask = 0xffffffff; | 1088 int32_t right_mask = (right()->range() != NULL) |
| 1078 if (a != NULL) a_mask = a->Mask(); | 1089 ? right()->range()->Mask() |
| 1079 if (b != NULL) b_mask = b->Mask(); | 1090 : 0xffffffff; |
| 1080 int32_t result_mask = a_mask | b_mask; | 1091 int32_t result_mask = left_mask | right_mask; |
| 1081 if (result_mask >= 0) { | 1092 return (result_mask >= 0) |
| 1082 return new Range(0, result_mask); | 1093 ? new Range(0, result_mask) |
| 1083 } else { | 1094 : HValue::InferRange(); |
| 1084 return HBinaryOperation::InferRange(); | |
| 1085 } | |
| 1086 } | 1095 } |
| 1087 | 1096 |
| 1088 | 1097 |
| 1089 Range* HSar::InferRange() { | 1098 Range* HSar::InferRange() { |
| 1090 if (right()->IsConstant()) { | 1099 if (right()->IsConstant()) { |
| 1091 HConstant* c = HConstant::cast(right()); | 1100 HConstant* c = HConstant::cast(right()); |
| 1092 if (c->HasInteger32Value()) { | 1101 if (c->HasInteger32Value()) { |
| 1093 int32_t val = c->Integer32Value(); | 1102 Range* result = (left()->range() != NULL) |
| 1094 Range* result = NULL; | 1103 ? left()->range()->Copy() |
| 1095 Range* left_range = left()->range(); | 1104 : new Range(); |
| 1096 if (left_range == NULL) { | 1105 result->Sar(c->Integer32Value()); |
| 1097 result = new Range(); | |
| 1098 } else { | |
| 1099 result = left_range->Copy(); | |
| 1100 } | |
| 1101 result->Sar(val); | |
| 1102 return result; | 1106 return result; |
| 1103 } | 1107 } |
| 1104 } | 1108 } |
| 1105 | 1109 return HValue::InferRange(); |
| 1106 return HBinaryOperation::InferRange(); | |
| 1107 } | 1110 } |
| 1108 | 1111 |
| 1109 | 1112 |
| 1110 Range* HShl::InferRange() { | 1113 Range* HShl::InferRange() { |
| 1111 if (right()->IsConstant()) { | 1114 if (right()->IsConstant()) { |
| 1112 HConstant* c = HConstant::cast(right()); | 1115 HConstant* c = HConstant::cast(right()); |
| 1113 if (c->HasInteger32Value()) { | 1116 if (c->HasInteger32Value()) { |
| 1114 int32_t val = c->Integer32Value(); | 1117 Range* result = (left()->range() != NULL) |
| 1115 Range* result = NULL; | 1118 ? left()->range()->Copy() |
| 1116 Range* left_range = left()->range(); | 1119 : new Range(); |
| 1117 if (left_range == NULL) { | 1120 result->Shl(c->Integer32Value()); |
| 1118 result = new Range(); | |
| 1119 } else { | |
| 1120 result = left_range->Copy(); | |
| 1121 } | |
| 1122 result->Shl(val); | |
| 1123 return result; | 1121 return result; |
| 1124 } | 1122 } |
| 1125 } | 1123 } |
| 1126 | 1124 return HValue::InferRange(); |
| 1127 return HBinaryOperation::InferRange(); | |
| 1128 } | 1125 } |
| 1129 | 1126 |
| 1130 | 1127 |
| 1131 | 1128 |
| 1132 void HCompare::PrintDataTo(StringStream* stream) const { | 1129 void HCompare::PrintDataTo(StringStream* stream) { |
| 1133 stream->Add(Token::Name(token())); | 1130 stream->Add(Token::Name(token())); |
| 1134 stream->Add(" "); | 1131 stream->Add(" "); |
| 1135 HBinaryOperation::PrintDataTo(stream); | 1132 HBinaryOperation::PrintDataTo(stream); |
| 1136 } | 1133 } |
| 1137 | 1134 |
| 1138 | 1135 |
| 1139 void HCompare::SetInputRepresentation(Representation r) { | 1136 void HCompare::SetInputRepresentation(Representation r) { |
| 1140 input_representation_ = r; | 1137 input_representation_ = r; |
| 1141 if (r.IsTagged()) { | 1138 if (r.IsTagged()) { |
| 1142 SetAllSideEffects(); | 1139 SetAllSideEffects(); |
| 1143 ClearFlag(kUseGVN); | 1140 ClearFlag(kUseGVN); |
| 1144 } else { | 1141 } else { |
| 1145 ClearAllSideEffects(); | 1142 ClearAllSideEffects(); |
| 1146 SetFlag(kUseGVN); | 1143 SetFlag(kUseGVN); |
| 1147 } | 1144 } |
| 1148 } | 1145 } |
| 1149 | 1146 |
| 1150 | 1147 |
| 1151 void HParameter::PrintDataTo(StringStream* stream) const { | 1148 void HParameter::PrintDataTo(StringStream* stream) { |
| 1152 stream->Add("%u", index()); | 1149 stream->Add("%u", index()); |
| 1153 } | 1150 } |
| 1154 | 1151 |
| 1155 | 1152 |
| 1156 void HLoadNamedField::PrintDataTo(StringStream* stream) const { | 1153 void HLoadNamedField::PrintDataTo(StringStream* stream) { |
| 1157 object()->PrintNameTo(stream); | 1154 object()->PrintNameTo(stream); |
| 1158 stream->Add(" @%d%s", offset(), is_in_object() ? "[in-object]" : ""); | 1155 stream->Add(" @%d%s", offset(), is_in_object() ? "[in-object]" : ""); |
| 1159 } | 1156 } |
| 1160 | 1157 |
| 1161 | 1158 |
| 1162 void HLoadKeyed::PrintDataTo(StringStream* stream) const { | 1159 void HLoadKeyedFastElement::PrintDataTo(StringStream* stream) { |
| 1163 object()->PrintNameTo(stream); | 1160 object()->PrintNameTo(stream); |
| 1164 stream->Add("["); | 1161 stream->Add("["); |
| 1165 key()->PrintNameTo(stream); | 1162 key()->PrintNameTo(stream); |
| 1166 stream->Add("]"); | 1163 stream->Add("]"); |
| 1167 } | 1164 } |
| 1168 | 1165 |
| 1169 | 1166 |
| 1170 void HLoadPixelArrayElement::PrintDataTo(StringStream* stream) const { | 1167 void HLoadKeyedGeneric::PrintDataTo(StringStream* stream) { |
| 1168 object()->PrintNameTo(stream); |
| 1169 stream->Add("["); |
| 1170 key()->PrintNameTo(stream); |
| 1171 stream->Add("]"); |
| 1172 } |
| 1173 |
| 1174 |
| 1175 void HLoadPixelArrayElement::PrintDataTo(StringStream* stream) { |
| 1171 external_pointer()->PrintNameTo(stream); | 1176 external_pointer()->PrintNameTo(stream); |
| 1172 stream->Add("["); | 1177 stream->Add("["); |
| 1173 key()->PrintNameTo(stream); | 1178 key()->PrintNameTo(stream); |
| 1174 stream->Add("]"); | 1179 stream->Add("]"); |
| 1175 } | 1180 } |
| 1176 | 1181 |
| 1177 | 1182 |
| 1178 void HStoreNamed::PrintDataTo(StringStream* stream) const { | 1183 void HStoreNamedGeneric::PrintDataTo(StringStream* stream) { |
| 1179 object()->PrintNameTo(stream); | 1184 object()->PrintNameTo(stream); |
| 1180 stream->Add("."); | 1185 stream->Add("."); |
| 1181 ASSERT(name()->IsString()); | 1186 ASSERT(name()->IsString()); |
| 1182 stream->Add(*String::cast(*name())->ToCString()); | 1187 stream->Add(*String::cast(*name())->ToCString()); |
| 1183 stream->Add(" = "); | 1188 stream->Add(" = "); |
| 1184 value()->PrintNameTo(stream); | 1189 value()->PrintNameTo(stream); |
| 1185 } | 1190 } |
| 1186 | 1191 |
| 1187 | 1192 |
| 1188 void HStoreNamedField::PrintDataTo(StringStream* stream) const { | 1193 void HStoreNamedField::PrintDataTo(StringStream* stream) { |
| 1189 HStoreNamed::PrintDataTo(stream); | 1194 object()->PrintNameTo(stream); |
| 1195 stream->Add("."); |
| 1196 ASSERT(name()->IsString()); |
| 1197 stream->Add(*String::cast(*name())->ToCString()); |
| 1198 stream->Add(" = "); |
| 1199 value()->PrintNameTo(stream); |
| 1190 if (!transition().is_null()) { | 1200 if (!transition().is_null()) { |
| 1191 stream->Add(" (transition map %p)", *transition()); | 1201 stream->Add(" (transition map %p)", *transition()); |
| 1192 } | 1202 } |
| 1193 } | 1203 } |
| 1194 | 1204 |
| 1195 | 1205 |
| 1196 void HStoreKeyed::PrintDataTo(StringStream* stream) const { | 1206 void HStoreKeyedFastElement::PrintDataTo(StringStream* stream) { |
| 1197 object()->PrintNameTo(stream); | 1207 object()->PrintNameTo(stream); |
| 1198 stream->Add("["); | 1208 stream->Add("["); |
| 1199 key()->PrintNameTo(stream); | 1209 key()->PrintNameTo(stream); |
| 1200 stream->Add("] = "); | 1210 stream->Add("] = "); |
| 1201 value()->PrintNameTo(stream); | 1211 value()->PrintNameTo(stream); |
| 1202 } | 1212 } |
| 1203 | 1213 |
| 1204 | 1214 |
| 1205 void HLoadGlobal::PrintDataTo(StringStream* stream) const { | 1215 void HStoreKeyedGeneric::PrintDataTo(StringStream* stream) { |
| 1216 object()->PrintNameTo(stream); |
| 1217 stream->Add("["); |
| 1218 key()->PrintNameTo(stream); |
| 1219 stream->Add("] = "); |
| 1220 value()->PrintNameTo(stream); |
| 1221 } |
| 1222 |
| 1223 |
| 1224 void HStorePixelArrayElement::PrintDataTo(StringStream* stream) { |
| 1225 external_pointer()->PrintNameTo(stream); |
| 1226 stream->Add("["); |
| 1227 key()->PrintNameTo(stream); |
| 1228 stream->Add("] = "); |
| 1229 value()->PrintNameTo(stream); |
| 1230 } |
| 1231 |
| 1232 |
| 1233 void HLoadGlobal::PrintDataTo(StringStream* stream) { |
| 1206 stream->Add("[%p]", *cell()); | 1234 stream->Add("[%p]", *cell()); |
| 1207 if (check_hole_value()) stream->Add(" (deleteable/read-only)"); | 1235 if (check_hole_value()) stream->Add(" (deleteable/read-only)"); |
| 1208 } | 1236 } |
| 1209 | 1237 |
| 1210 | 1238 |
| 1211 void HStoreGlobal::PrintDataTo(StringStream* stream) const { | 1239 void HStoreGlobal::PrintDataTo(StringStream* stream) { |
| 1212 stream->Add("[%p] = ", *cell()); | 1240 stream->Add("[%p] = ", *cell()); |
| 1213 value()->PrintNameTo(stream); | 1241 value()->PrintNameTo(stream); |
| 1214 } | 1242 } |
| 1215 | 1243 |
| 1216 | 1244 |
| 1217 void HLoadContextSlot::PrintDataTo(StringStream* stream) const { | 1245 void HLoadContextSlot::PrintDataTo(StringStream* stream) { |
| 1218 value()->PrintNameTo(stream); | 1246 value()->PrintNameTo(stream); |
| 1219 stream->Add("[%d]", slot_index()); | 1247 stream->Add("[%d]", slot_index()); |
| 1220 } | 1248 } |
| 1221 | 1249 |
| 1222 | 1250 |
| 1223 void HStoreContextSlot::PrintDataTo(StringStream* stream) const { | 1251 void HStoreContextSlot::PrintDataTo(StringStream* stream) { |
| 1224 context()->PrintNameTo(stream); | 1252 context()->PrintNameTo(stream); |
| 1225 stream->Add("[%d] = ", slot_index()); | 1253 stream->Add("[%d] = ", slot_index()); |
| 1226 value()->PrintNameTo(stream); | 1254 value()->PrintNameTo(stream); |
| 1227 } | 1255 } |
| 1228 | 1256 |
| 1229 | 1257 |
| 1230 // Implementation of type inference and type conversions. Calculates | 1258 // Implementation of type inference and type conversions. Calculates |
| 1231 // the inferred type of this instruction based on the input operands. | 1259 // the inferred type of this instruction based on the input operands. |
| 1232 | 1260 |
| 1233 HType HValue::CalculateInferredType() const { | 1261 HType HValue::CalculateInferredType() { |
| 1234 return type_; | 1262 return type_; |
| 1235 } | 1263 } |
| 1236 | 1264 |
| 1237 | 1265 |
| 1238 HType HCheckMap::CalculateInferredType() const { | 1266 HType HCheckMap::CalculateInferredType() { |
| 1239 return value()->type(); | 1267 return value()->type(); |
| 1240 } | 1268 } |
| 1241 | 1269 |
| 1242 | 1270 |
| 1243 HType HCheckFunction::CalculateInferredType() const { | 1271 HType HCheckFunction::CalculateInferredType() { |
| 1244 return value()->type(); | 1272 return value()->type(); |
| 1245 } | 1273 } |
| 1246 | 1274 |
| 1247 | 1275 |
| 1248 HType HCheckNonSmi::CalculateInferredType() const { | 1276 HType HCheckNonSmi::CalculateInferredType() { |
| 1249 // TODO(kasperl): Is there any way to signal that this isn't a smi? | 1277 // TODO(kasperl): Is there any way to signal that this isn't a smi? |
| 1250 return HType::Tagged(); | 1278 return HType::Tagged(); |
| 1251 } | 1279 } |
| 1252 | 1280 |
| 1253 | 1281 |
| 1254 HType HCheckSmi::CalculateInferredType() const { | 1282 HType HCheckSmi::CalculateInferredType() { |
| 1255 return HType::Smi(); | 1283 return HType::Smi(); |
| 1256 } | 1284 } |
| 1257 | 1285 |
| 1258 | 1286 |
| 1259 HType HPhi::CalculateInferredType() const { | 1287 HType HPhi::CalculateInferredType() { |
| 1260 HType result = HType::Uninitialized(); | 1288 HType result = HType::Uninitialized(); |
| 1261 for (int i = 0; i < OperandCount(); ++i) { | 1289 for (int i = 0; i < OperandCount(); ++i) { |
| 1262 HType current = OperandAt(i)->type(); | 1290 HType current = OperandAt(i)->type(); |
| 1263 result = result.Combine(current); | 1291 result = result.Combine(current); |
| 1264 } | 1292 } |
| 1265 return result; | 1293 return result; |
| 1266 } | 1294 } |
| 1267 | 1295 |
| 1268 | 1296 |
| 1269 HType HConstant::CalculateInferredType() const { | 1297 HType HConstant::CalculateInferredType() { |
| 1270 return constant_type_; | 1298 return constant_type_; |
| 1271 } | 1299 } |
| 1272 | 1300 |
| 1273 | 1301 |
| 1274 HType HCompare::CalculateInferredType() const { | 1302 HType HCompare::CalculateInferredType() { |
| 1275 return HType::Boolean(); | 1303 return HType::Boolean(); |
| 1276 } | 1304 } |
| 1277 | 1305 |
| 1278 | 1306 |
| 1279 HType HCompareJSObjectEq::CalculateInferredType() const { | 1307 HType HCompareJSObjectEq::CalculateInferredType() { |
| 1280 return HType::Boolean(); | 1308 return HType::Boolean(); |
| 1281 } | 1309 } |
| 1282 | 1310 |
| 1283 | 1311 |
| 1284 HType HUnaryPredicate::CalculateInferredType() const { | 1312 HType HUnaryPredicate::CalculateInferredType() { |
| 1285 return HType::Boolean(); | 1313 return HType::Boolean(); |
| 1286 } | 1314 } |
| 1287 | 1315 |
| 1288 | 1316 |
| 1289 HType HBitwiseBinaryOperation::CalculateInferredType() const { | 1317 HType HBitwiseBinaryOperation::CalculateInferredType() { |
| 1290 return HType::TaggedNumber(); | 1318 return HType::TaggedNumber(); |
| 1291 } | 1319 } |
| 1292 | 1320 |
| 1293 | 1321 |
| 1294 HType HArithmeticBinaryOperation::CalculateInferredType() const { | 1322 HType HArithmeticBinaryOperation::CalculateInferredType() { |
| 1295 return HType::TaggedNumber(); | 1323 return HType::TaggedNumber(); |
| 1296 } | 1324 } |
| 1297 | 1325 |
| 1298 | 1326 |
| 1299 HType HAdd::CalculateInferredType() const { | 1327 HType HAdd::CalculateInferredType() { |
| 1300 return HType::Tagged(); | 1328 return HType::Tagged(); |
| 1301 } | 1329 } |
| 1302 | 1330 |
| 1303 | 1331 |
| 1304 HType HBitAnd::CalculateInferredType() const { | 1332 HType HBitAnd::CalculateInferredType() { |
| 1305 return HType::TaggedNumber(); | 1333 return HType::TaggedNumber(); |
| 1306 } | 1334 } |
| 1307 | 1335 |
| 1308 | 1336 |
| 1309 HType HBitXor::CalculateInferredType() const { | 1337 HType HBitXor::CalculateInferredType() { |
| 1310 return HType::TaggedNumber(); | 1338 return HType::TaggedNumber(); |
| 1311 } | 1339 } |
| 1312 | 1340 |
| 1313 | 1341 |
| 1314 HType HBitOr::CalculateInferredType() const { | 1342 HType HBitOr::CalculateInferredType() { |
| 1315 return HType::TaggedNumber(); | 1343 return HType::TaggedNumber(); |
| 1316 } | 1344 } |
| 1317 | 1345 |
| 1318 | 1346 |
| 1319 HType HBitNot::CalculateInferredType() const { | 1347 HType HBitNot::CalculateInferredType() { |
| 1320 return HType::TaggedNumber(); | 1348 return HType::TaggedNumber(); |
| 1321 } | 1349 } |
| 1322 | 1350 |
| 1323 | 1351 |
| 1324 HType HUnaryMathOperation::CalculateInferredType() const { | 1352 HType HUnaryMathOperation::CalculateInferredType() { |
| 1325 return HType::TaggedNumber(); | 1353 return HType::TaggedNumber(); |
| 1326 } | 1354 } |
| 1327 | 1355 |
| 1328 | 1356 |
| 1329 HType HShl::CalculateInferredType() const { | 1357 HType HShl::CalculateInferredType() { |
| 1330 return HType::TaggedNumber(); | 1358 return HType::TaggedNumber(); |
| 1331 } | 1359 } |
| 1332 | 1360 |
| 1333 | 1361 |
| 1334 HType HShr::CalculateInferredType() const { | 1362 HType HShr::CalculateInferredType() { |
| 1335 return HType::TaggedNumber(); | 1363 return HType::TaggedNumber(); |
| 1336 } | 1364 } |
| 1337 | 1365 |
| 1338 | 1366 |
| 1339 HType HSar::CalculateInferredType() const { | 1367 HType HSar::CalculateInferredType() { |
| 1340 return HType::TaggedNumber(); | 1368 return HType::TaggedNumber(); |
| 1341 } | 1369 } |
| 1342 | 1370 |
| 1343 | 1371 |
| 1344 HValue* HUnaryMathOperation::EnsureAndPropagateNotMinusZero( | 1372 HValue* HUnaryMathOperation::EnsureAndPropagateNotMinusZero( |
| 1345 BitVector* visited) { | 1373 BitVector* visited) { |
| 1346 visited->Add(id()); | 1374 visited->Add(id()); |
| 1347 if (representation().IsInteger32() && | 1375 if (representation().IsInteger32() && |
| 1348 !value()->representation().IsInteger32()) { | 1376 !value()->representation().IsInteger32()) { |
| 1349 if (value()->range() == NULL || value()->range()->CanBeMinusZero()) { | 1377 if (value()->range() == NULL || value()->range()->CanBeMinusZero()) { |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1479 | 1507 |
| 1480 | 1508 |
| 1481 void HCheckPrototypeMaps::Verify() { | 1509 void HCheckPrototypeMaps::Verify() { |
| 1482 HInstruction::Verify(); | 1510 HInstruction::Verify(); |
| 1483 ASSERT(HasNoUses()); | 1511 ASSERT(HasNoUses()); |
| 1484 } | 1512 } |
| 1485 | 1513 |
| 1486 #endif | 1514 #endif |
| 1487 | 1515 |
| 1488 } } // namespace v8::internal | 1516 } } // namespace v8::internal |
| OLD | NEW |