Chromium Code Reviews| Index: src/hydrogen-instructions.h |
| diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h |
| index e0c443a6c378c9f9352868a73a985a590a2591f7..b8db717631b9a8781709e1a77a682b1c87afa801 100644 |
| --- a/src/hydrogen-instructions.h |
| +++ b/src/hydrogen-instructions.h |
| @@ -2451,20 +2451,37 @@ class HArgumentsObject: public HTemplateInstruction<0> { |
| class HConstant: public HTemplateInstruction<0> { |
| public: |
| HConstant(Handle<Object> handle, Representation r); |
| + HConstant(int32_t integer_value, Representation r, Handle<Object> handle); |
|
Michael Starzinger
2012/07/09 09:57:09
I think we can get by with just two constructors.
sanjoy
2012/07/09 13:47:37
We need the double-only constructor when folding d
Michael Starzinger
2012/07/09 15:36:22
Yes, but isn't that only called during building of
|
| + HConstant(double double_value, Representation r, Handle<Object> handle); |
| - Handle<Object> handle() const { return handle_; } |
| + Handle<Object> handle() const { |
| + ASSERT(!handle_.is_null()); |
|
Michael Starzinger
2012/07/09 09:57:09
This change introduces a large amount of complexit
sanjoy
2012/07/09 13:47:37
Fixed. handle() now lazily allocates a Handle.
|
| + return handle_; |
| + } |
| bool InOldSpace() const { return !HEAP->InNewSpace(*handle_); } |
| bool ImmortalImmovable() const { |
| + if (has_int32_value_) { |
| + return false; |
| + } |
| + if (has_double_value_) { |
| + if (BitCast<int64_t>(double_value_) == BitCast<int64_t>(-0.0) || |
| + isnan(double_value_)) { |
| + return true; |
| + } |
| + return false; |
| + } |
| Heap* heap = HEAP; |
| + // We should have handled minus_zero_value and nan_value in the |
| + // has_double_value_ clause above. |
| + ASSERT(*handle_ != heap->minus_zero_value()); |
| + ASSERT(*handle_ != heap->nan_value()); |
| if (*handle_ == heap->undefined_value()) return true; |
| if (*handle_ == heap->null_value()) return true; |
| if (*handle_ == heap->true_value()) return true; |
| if (*handle_ == heap->false_value()) return true; |
| if (*handle_ == heap->the_hole_value()) return true; |
| - if (*handle_ == heap->minus_zero_value()) return true; |
| - if (*handle_ == heap->nan_value()) return true; |
| if (*handle_ == heap->empty_string()) return true; |
| return false; |
| } |
| @@ -2473,19 +2490,21 @@ class HConstant: public HTemplateInstruction<0> { |
| return Representation::None(); |
| } |
| + void EnsureHasHandle(Factory* factory); |
| + bool IsTagged() { |
| + ASSERT(has_int32_value_ || has_double_value_ || !handle_.is_null()); |
| + return !(has_int32_value_ || has_double_value_); |
| + } |
| + |
| virtual bool IsConvertibleToInteger() const { |
| - if (handle_->IsSmi()) return true; |
| - if (handle_->IsHeapNumber() && |
| - (HeapNumber::cast(*handle_)->value() == |
| - static_cast<double>(NumberToInt32(*handle_)))) return true; |
| - return false; |
| + return has_int32_value_; |
| } |
| virtual bool EmitAtUses() { return !representation().IsDouble(); } |
| virtual HValue* Canonicalize(); |
| virtual void PrintDataTo(StringStream* stream); |
| virtual HType CalculateInferredType(); |
| - bool IsInteger() const { return handle_->IsSmi(); } |
| + bool IsInteger() const { return handle_was_smi_; } |
| HConstant* CopyToRepresentation(Representation r, Zone* zone) const; |
| HConstant* CopyToTruncatedInt32(Zone* zone) const; |
| bool HasInteger32Value() const { return has_int32_value_; } |
| @@ -2498,24 +2517,36 @@ class HConstant: public HTemplateInstruction<0> { |
| ASSERT(HasDoubleValue()); |
| return double_value_; |
| } |
| - bool HasNumberValue() const { return has_int32_value_ || has_double_value_; } |
| + bool HasNumberValue() const { return has_double_value_; } |
| int32_t NumberValueAsInteger32() const { |
| ASSERT(HasNumberValue()); |
| - if (has_int32_value_) return int32_value_; |
| - return DoubleToInt32(double_value_); |
| + return int32_value_; |
| } |
| - bool HasStringValue() const { return handle_->IsString(); } |
| + bool IsString() const { return is_string_; } |
| + bool IsBoolean() const { return is_boolean_; } |
| + bool IsSymbol() { return is_symbol_; } |
| bool ToBoolean() const; |
| virtual intptr_t Hashcode() { |
| ASSERT(!HEAP->allow_allocation(false)); |
| - intptr_t hash = reinterpret_cast<intptr_t>(*handle()); |
| - // Prevent smis from having fewer hash values when truncated to |
| - // the least significant bits. |
| - const int kShiftSize = kSmiShiftSize + kSmiTagSize; |
| - STATIC_ASSERT(kShiftSize != 0); |
| - return hash ^ (hash >> kShiftSize); |
| + intptr_t hash; |
| + |
| + if (has_int32_value_) { |
| + hash = static_cast<intptr_t>(int32_value_); |
| + // Prevent smis from having fewer hash values when truncated to |
| + // the least significant bits. |
| + const int kShiftSize = kSmiShiftSize + kSmiTagSize; |
| + STATIC_ASSERT(kShiftSize != 0); |
| + hash = hash ^ (hash >> kShiftSize); |
| + } else if (has_double_value_) { |
| + hash = static_cast<intptr_t>(BitCast<int64_t>(double_value_)); |
| + } else { |
| + ASSERT(!handle_.is_null()); |
| + hash = reinterpret_cast<intptr_t>(*handle_); |
| + } |
| + |
| + return hash; |
| } |
| #ifdef DEBUG |
| @@ -2529,17 +2560,40 @@ class HConstant: public HTemplateInstruction<0> { |
| virtual bool DataEquals(HValue* other) { |
| HConstant* other_constant = HConstant::cast(other); |
| - return handle().is_identical_to(other_constant->handle()); |
| + if (has_int32_value_) { |
| + return other_constant->has_int32_value_ && |
| + int32_value_ == other_constant->int32_value_; |
| + } else if (has_double_value_) { |
| + return other_constant->has_double_value_ && |
| + BitCast<int64_t>(double_value_) == |
| + BitCast<int64_t>(other_constant->double_value_); |
| + } else { |
| + ASSERT(!handle_.is_null()); |
| + return !other_constant->handle_.is_null() && |
| + *handle_ == *other_constant->handle_; |
| + } |
| } |
| private: |
| + // We store the HConstant in the most specific form safely possible. |
| + // The two flags, has_int32_value_ and has_double_value_ tell us if |
| + // int32_value_ and double_value_ hold valid, safe representations |
| + // of the constant. has_int32_value_ implies has_double_value_ but |
| + // not the converse. |
| + |
| + // If this is a numerical constant, handle_ either points to to the |
| + // HeapObject the constant originated from or is null. If the |
| + // constant is non-numeric, handle_ always points to a valid |
| + // constant HeapObject. |
| + |
| Handle<Object> handle_; |
| - // The following two values represent the int32 and the double value of the |
| - // given constant if there is a lossless conversion between the constant |
| - // and the specific representation. |
| bool has_int32_value_ : 1; |
| bool has_double_value_ : 1; |
| + bool handle_was_smi_ : 1; |
| + bool is_string_ : 1; |
| + bool is_symbol_ : 1; |
| + bool is_boolean_ : 1; |
| int32_t int32_value_; |
| double double_value_; |
| }; |