Chromium Code Reviews| Index: src/hydrogen-instructions.cc |
| diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc |
| index 283e484041ca0f089efe1eecd32547f1e4423639..f629b0fc6839ebc1c719d4df4e57c94bc24234eb 100644 |
| --- a/src/hydrogen-instructions.cc |
| +++ b/src/hydrogen-instructions.cc |
| @@ -1388,38 +1388,89 @@ void HEnterInlined::PrintDataTo(StringStream* stream) { |
| HConstant::HConstant(Handle<Object> handle, Representation r) |
| : handle_(handle), |
| has_int32_value_(false), |
| - has_double_value_(false), |
| - int32_value_(0), |
| - double_value_(0) { |
| + has_double_value_(false) { |
| set_representation(r); |
| SetFlag(kUseGVN); |
| if (handle_->IsNumber()) { |
| double n = handle_->Number(); |
| double roundtrip_value = static_cast<double>(static_cast<int32_t>(n)); |
| - has_int32_value_ = BitCast<int64_t>(roundtrip_value) == BitCast<int64_t>(n); |
| - if (has_int32_value_) int32_value_ = static_cast<int32_t>(n); |
| + has_int32_value_ = BitCast<int64_t>(roundtrip_value) == |
| + BitCast<int64_t>(n); |
| + |
| + int32_value_ = DoubleToInt32(n); |
| double_value_ = n; |
| has_double_value_ = true; |
| } |
| } |
| +HConstant::HConstant(int32_t integer_value, Representation r, |
| + Handle<Object> handle) |
|
Michael Starzinger
2012/07/09 15:36:22
This should not take a handle parameter. This cons
sanjoy
2012/07/09 17:44:58
Done.
|
| + : handle_(handle), |
| + has_int32_value_(true), |
| + has_double_value_(true) { |
| + set_representation(r); |
| + SetFlag(kUseGVN); |
| + int32_value_ = integer_value; |
| + double_value_ = FastI2D(integer_value); |
| +} |
| + |
| + |
| +HConstant::HConstant(double double_value, Representation r, |
| + Handle<Object> handle) |
|
Michael Starzinger
2012/07/09 15:36:22
Likewise.
sanjoy
2012/07/09 17:44:58
Done.
|
| + : handle_(handle), |
| + has_int32_value_(false), |
| + has_double_value_(true), |
| + int32_value_(DoubleToInt32(double_value)), |
| + double_value_(double_value) { |
| + set_representation(r); |
| + SetFlag(kUseGVN); |
| + double roundtrip_value = static_cast<double>( |
| + static_cast<int32_t>(double_value)); |
| + has_int32_value_ = BitCast<int64_t>(roundtrip_value) == |
| + BitCast<int64_t>(double_value); |
| +} |
| + |
| + |
| HConstant* HConstant::CopyToRepresentation(Representation r, Zone* zone) const { |
| - if (r.IsInteger32() && !has_int32_value_) return NULL; |
| - if (r.IsDouble() && !has_double_value_) return NULL; |
| - return new(zone) HConstant(handle_, r); |
| + if (has_int32_value_) { |
| + return new(zone) HConstant(int32_value_, r, handle_); |
| + } else if (has_double_value_) { |
| + // A double can be safely converted only to a HeapNumber. If it |
| + // was possible to store this double as a integer, we'd have done |
| + // that and has_int32_value_ would be true. |
| + if (r.IsInteger32()) { |
| + return NULL; |
| + } else { |
| + return new(zone) HConstant(double_value_, r, handle_); |
| + } |
| + } else { |
| + // A generic tagged value cannot be safely converted to any other |
| + // representation. |
| + if (r.IsTagged()) { |
| + return new(zone) HConstant(handle_, r); |
| + } else { |
| + return NULL; |
| + } |
| + } |
| } |
| HConstant* HConstant::CopyToTruncatedInt32(Zone* zone) const { |
| - if (!has_double_value_) return NULL; |
| - int32_t truncated = NumberToInt32(*handle_); |
| - return new(zone) HConstant(FACTORY->NewNumberFromInt(truncated), |
| - Representation::Integer32()); |
| + if (has_int32_value_) { |
| + return new(zone) HConstant(int32_value_, Representation::Integer32(), |
| + handle_); |
| + } else if (has_double_value_) { |
| + return new(zone) HConstant(DoubleToInt32(double_value_), |
| + Representation::Integer32(), |
| + Handle<Object>::null()); |
| + } else { |
| + return NULL; |
| + } |
| } |
| -bool HConstant::ToBoolean() const { |
| +bool HConstant::ToBoolean() { |
| // Converts the constant's boolean value according to |
| // ECMAScript section 9.2 ToBoolean conversion. |
| if (HasInteger32Value()) return Integer32Value() != 0; |
| @@ -1427,17 +1478,25 @@ bool HConstant::ToBoolean() const { |
| double v = DoubleValue(); |
| return v != 0 && !isnan(v); |
| } |
| - if (handle()->IsTrue()) return true; |
| - if (handle()->IsFalse()) return false; |
| - if (handle()->IsUndefined()) return false; |
| - if (handle()->IsNull()) return false; |
| - if (handle()->IsString() && |
| - String::cast(*handle())->length() == 0) return false; |
| + Handle<Object> literal = handle(); |
| + if (literal->IsTrue()) return true; |
| + if (literal->IsFalse()) return false; |
| + if (literal->IsUndefined()) return false; |
| + if (literal->IsNull()) return false; |
| + if (literal->IsString() && String::cast(*literal)->length() == 0) { |
| + return false; |
| + } |
| return true; |
| } |
| void HConstant::PrintDataTo(StringStream* stream) { |
| - handle()->ShortPrint(stream); |
| + if (has_int32_value_) { |
| + stream->Add("%d ", int32_value_); |
| + } else if (has_double_value_) { |
| + stream->Add("%lf ", double_value_); |
| + } else { |
| + handle()->ShortPrint(stream); |
| + } |
| } |
| @@ -2089,7 +2148,11 @@ HType HPhi::CalculateInferredType() { |
| HType HConstant::CalculateInferredType() { |
| - return HType::TypeFromValue(handle_); |
| + if (has_int32_value_) { |
| + return Smi::IsValid(int32_value_) ? HType::Smi() : HType::HeapNumber(); |
| + } |
| + if (has_double_value_) return HType::HeapNumber(); |
| + return HType::TypeFromValue(Handle<Object>(handle_)); |
| } |
| @@ -2285,12 +2348,13 @@ bool HStoreKeyedFastDoubleElement::NeedsCanonicalization() { |
| } |
| -#define H_CONSTANT_INT32(val) \ |
| -new(zone) HConstant(FACTORY->NewNumberFromInt(val, TENURED), \ |
| - Representation::Integer32()) |
| +#define H_CONSTANT_INT32(val) \ |
| +new(zone) HConstant(static_cast<int32_t>(val), \ |
| + Representation::Integer32(), \ |
| + Handle<Object>::null()) |
| + |
| #define H_CONSTANT_DOUBLE(val) \ |
| -new(zone) HConstant(FACTORY->NewNumber(val, TENURED), \ |
| - Representation::Double()) |
| +new(zone) HConstant(val, Representation::Double(), Handle<Object>::null()) |
| #define DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HInstr, op) \ |
| HInstruction* HInstr::New##HInstr(Zone* zone, \ |