OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 2435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2446 return Representation::None(); | 2446 return Representation::None(); |
2447 } | 2447 } |
2448 | 2448 |
2449 DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject) | 2449 DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject) |
2450 }; | 2450 }; |
2451 | 2451 |
2452 | 2452 |
2453 class HConstant: public HTemplateInstruction<0> { | 2453 class HConstant: public HTemplateInstruction<0> { |
2454 public: | 2454 public: |
2455 HConstant(Handle<Object> handle, Representation r); | 2455 HConstant(Handle<Object> handle, Representation r); |
2456 HConstant(int32_t value, Representation r); | |
2457 HConstant(double value, Representation r); | |
2456 | 2458 |
2457 Handle<Object> handle() const { return handle_; } | 2459 Handle<Object> handle() { |
2460 if (handle_.is_null()) { | |
2461 handle_ = FACTORY->NewNumber(double_value_, TENURED); | |
2462 } | |
2463 ASSERT(has_int32_value_ || !handle_->IsSmi()); | |
2464 return handle_; | |
2465 } | |
2458 | 2466 |
2459 bool InOldSpace() const { return !HEAP->InNewSpace(*handle_); } | 2467 bool InOldSpace() const { return !HEAP->InNewSpace(*handle_); } |
2460 | 2468 |
2461 bool ImmortalImmovable() const { | 2469 bool ImmortalImmovable() const { |
2470 if (has_int32_value_) { | |
2471 return false; | |
2472 } | |
2473 if (has_double_value_) { | |
2474 if (BitCast<int64_t>(double_value_) == BitCast<int64_t>(-0.0) || | |
2475 isnan(double_value_)) { | |
2476 return true; | |
2477 } | |
2478 return false; | |
2479 } | |
2480 | |
2481 ASSERT(!handle_.is_null()); | |
2462 Heap* heap = HEAP; | 2482 Heap* heap = HEAP; |
2483 // We should have handled minus_zero_value and nan_value in the | |
2484 // has_double_value_ clause above. | |
2485 ASSERT(*handle_ != heap->minus_zero_value()); | |
2486 ASSERT(*handle_ != heap->nan_value()); | |
2463 if (*handle_ == heap->undefined_value()) return true; | 2487 if (*handle_ == heap->undefined_value()) return true; |
2464 if (*handle_ == heap->null_value()) return true; | 2488 if (*handle_ == heap->null_value()) return true; |
2465 if (*handle_ == heap->true_value()) return true; | 2489 if (*handle_ == heap->true_value()) return true; |
2466 if (*handle_ == heap->false_value()) return true; | 2490 if (*handle_ == heap->false_value()) return true; |
2467 if (*handle_ == heap->the_hole_value()) return true; | 2491 if (*handle_ == heap->the_hole_value()) return true; |
2468 if (*handle_ == heap->minus_zero_value()) return true; | |
2469 if (*handle_ == heap->nan_value()) return true; | |
2470 if (*handle_ == heap->empty_string()) return true; | 2492 if (*handle_ == heap->empty_string()) return true; |
2471 return false; | 2493 return false; |
2472 } | 2494 } |
2473 | 2495 |
2474 virtual Representation RequiredInputRepresentation(int index) { | 2496 virtual Representation RequiredInputRepresentation(int index) { |
2475 return Representation::None(); | 2497 return Representation::None(); |
2476 } | 2498 } |
2477 | 2499 |
2500 bool IsTagged() { | |
Michael Starzinger
2012/07/11 09:16:10
This method doesn't seem to be used at all. Let's
sanjoy
2012/07/11 10:54:08
Done.
| |
2501 ASSERT(has_int32_value_ || has_double_value_ || !handle_.is_null()); | |
2502 return !(has_int32_value_ || has_double_value_); | |
2503 } | |
2504 | |
2478 virtual bool IsConvertibleToInteger() const { | 2505 virtual bool IsConvertibleToInteger() const { |
2479 if (handle_->IsSmi()) return true; | 2506 return has_int32_value_; |
2480 if (handle_->IsHeapNumber() && | |
2481 (HeapNumber::cast(*handle_)->value() == | |
2482 static_cast<double>(NumberToInt32(*handle_)))) return true; | |
2483 return false; | |
2484 } | 2507 } |
2485 | 2508 |
2486 virtual bool EmitAtUses() { return !representation().IsDouble(); } | 2509 virtual bool EmitAtUses() { return !representation().IsDouble(); } |
2487 virtual HValue* Canonicalize(); | 2510 virtual HValue* Canonicalize(); |
2488 virtual void PrintDataTo(StringStream* stream); | 2511 virtual void PrintDataTo(StringStream* stream); |
2489 virtual HType CalculateInferredType(); | 2512 virtual HType CalculateInferredType(); |
2490 bool IsInteger() const { return handle_->IsSmi(); } | 2513 bool IsInteger() { return handle()->IsSmi(); } |
2491 HConstant* CopyToRepresentation(Representation r, Zone* zone) const; | 2514 HConstant* CopyToRepresentation(Representation r, Zone* zone) const; |
2492 HConstant* CopyToTruncatedInt32(Zone* zone) const; | 2515 HConstant* CopyToTruncatedInt32(Zone* zone) const; |
2493 bool HasInteger32Value() const { return has_int32_value_; } | 2516 bool HasInteger32Value() const { return has_int32_value_; } |
2494 int32_t Integer32Value() const { | 2517 int32_t Integer32Value() const { |
2495 ASSERT(HasInteger32Value()); | 2518 ASSERT(HasInteger32Value()); |
2496 return int32_value_; | 2519 return int32_value_; |
2497 } | 2520 } |
2498 bool HasDoubleValue() const { return has_double_value_; } | 2521 bool HasDoubleValue() const { return has_double_value_; } |
2499 double DoubleValue() const { | 2522 double DoubleValue() const { |
2500 ASSERT(HasDoubleValue()); | 2523 ASSERT(HasDoubleValue()); |
2501 return double_value_; | 2524 return double_value_; |
2502 } | 2525 } |
2503 bool HasNumberValue() const { return has_int32_value_ || has_double_value_; } | 2526 bool HasNumberValue() const { return has_double_value_; } |
2504 int32_t NumberValueAsInteger32() const { | 2527 int32_t NumberValueAsInteger32() const { |
2505 ASSERT(HasNumberValue()); | 2528 ASSERT(HasNumberValue()); |
2506 if (has_int32_value_) return int32_value_; | 2529 return int32_value_; |
Michael Starzinger
2012/07/11 09:16:10
I think "int32_value_" is only valid if "HasIntege
sanjoy
2012/07/11 10:54:08
Done.
| |
2507 return DoubleToInt32(double_value_); | |
2508 } | 2530 } |
2509 bool HasStringValue() const { return handle_->IsString(); } | |
2510 | 2531 |
2511 bool ToBoolean() const; | 2532 bool ToBoolean(); |
2512 | 2533 |
2513 virtual intptr_t Hashcode() { | 2534 virtual intptr_t Hashcode() { |
2514 ASSERT(!HEAP->allow_allocation(false)); | 2535 ASSERT(!HEAP->allow_allocation(false)); |
2515 intptr_t hash = reinterpret_cast<intptr_t>(*handle()); | 2536 intptr_t hash; |
2516 // Prevent smis from having fewer hash values when truncated to | 2537 |
2517 // the least significant bits. | 2538 if (has_int32_value_) { |
2518 const int kShiftSize = kSmiShiftSize + kSmiTagSize; | 2539 hash = static_cast<intptr_t>(int32_value_); |
2519 STATIC_ASSERT(kShiftSize != 0); | 2540 // Prevent smis from having fewer hash values when truncated to |
2520 return hash ^ (hash >> kShiftSize); | 2541 // the least significant bits. |
2542 const int kShiftSize = kSmiShiftSize + kSmiTagSize; | |
Michael Starzinger
2012/07/11 09:16:10
Since we are using the untagged int32 value here,
sanjoy
2012/07/11 10:54:08
Done.
| |
2543 STATIC_ASSERT(kShiftSize != 0); | |
2544 hash = hash ^ (hash >> kShiftSize); | |
2545 } else if (has_double_value_) { | |
2546 hash = static_cast<intptr_t>(BitCast<int64_t>(double_value_)); | |
2547 } else { | |
2548 ASSERT(!handle_.is_null()); | |
2549 hash = reinterpret_cast<intptr_t>(*handle_); | |
2550 } | |
2551 | |
2552 return hash; | |
2521 } | 2553 } |
2522 | 2554 |
2523 #ifdef DEBUG | 2555 #ifdef DEBUG |
2524 virtual void Verify() { } | 2556 virtual void Verify() { } |
2525 #endif | 2557 #endif |
2526 | 2558 |
2527 DECLARE_CONCRETE_INSTRUCTION(Constant) | 2559 DECLARE_CONCRETE_INSTRUCTION(Constant) |
2528 | 2560 |
2529 protected: | 2561 protected: |
2530 virtual Range* InferRange(Zone* zone); | 2562 virtual Range* InferRange(Zone* zone); |
2531 | 2563 |
2532 virtual bool DataEquals(HValue* other) { | 2564 virtual bool DataEquals(HValue* other) { |
2533 HConstant* other_constant = HConstant::cast(other); | 2565 HConstant* other_constant = HConstant::cast(other); |
2534 return handle().is_identical_to(other_constant->handle()); | 2566 if (has_int32_value_) { |
2567 return other_constant->has_int32_value_ && | |
2568 int32_value_ == other_constant->int32_value_; | |
2569 } else if (has_double_value_) { | |
2570 return other_constant->has_double_value_ && | |
2571 BitCast<int64_t>(double_value_) == | |
2572 BitCast<int64_t>(other_constant->double_value_); | |
2573 } else { | |
2574 ASSERT(!handle_.is_null()); | |
2575 return !other_constant->handle_.is_null() && | |
2576 *handle_ == *other_constant->handle_; | |
2577 } | |
2535 } | 2578 } |
2536 | 2579 |
2537 private: | 2580 private: |
2581 // If this is a numerical constant, handle_ either points to to the | |
2582 // HeapObject the constant originated from or is null. If the | |
2583 // constant is non-numeric, handle_ always points to a valid | |
2584 // constant HeapObject. | |
2538 Handle<Object> handle_; | 2585 Handle<Object> handle_; |
2539 | 2586 |
2540 // The following two values represent the int32 and the double value of the | 2587 // We store the HConstant in the most specific form safely possible. |
2541 // given constant if there is a lossless conversion between the constant | 2588 // The two flags, has_int32_value_ and has_double_value_ tell us if |
2542 // and the specific representation. | 2589 // int32_value_ and double_value_ hold valid, safe representations |
2590 // of the constant. has_int32_value_ implies has_double_value_ but | |
2591 // not the converse. | |
2543 bool has_int32_value_ : 1; | 2592 bool has_int32_value_ : 1; |
2544 bool has_double_value_ : 1; | 2593 bool has_double_value_ : 1; |
2545 int32_t int32_value_; | 2594 int32_t int32_value_; |
2546 double double_value_; | 2595 double double_value_; |
2547 }; | 2596 }; |
2548 | 2597 |
2549 | 2598 |
2550 class HBinaryOperation: public HTemplateInstruction<3> { | 2599 class HBinaryOperation: public HTemplateInstruction<3> { |
2551 public: | 2600 public: |
2552 HBinaryOperation(HValue* context, HValue* left, HValue* right) { | 2601 HBinaryOperation(HValue* context, HValue* left, HValue* right) { |
(...skipping 2550 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5103 DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex); | 5152 DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex); |
5104 }; | 5153 }; |
5105 | 5154 |
5106 | 5155 |
5107 #undef DECLARE_INSTRUCTION | 5156 #undef DECLARE_INSTRUCTION |
5108 #undef DECLARE_CONCRETE_INSTRUCTION | 5157 #undef DECLARE_CONCRETE_INSTRUCTION |
5109 | 5158 |
5110 } } // namespace v8::internal | 5159 } } // namespace v8::internal |
5111 | 5160 |
5112 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 5161 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
OLD | NEW |