| Index: src/hydrogen-instructions.cc
|
| diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc
|
| index 283e484041ca0f089efe1eecd32547f1e4423639..a3d8fca2caa2f18bb21630a8f60a2ef153a12387 100644
|
| --- a/src/hydrogen-instructions.cc
|
| +++ b/src/hydrogen-instructions.cc
|
| @@ -1385,41 +1385,78 @@ void HEnterInlined::PrintDataTo(StringStream* stream) {
|
| }
|
|
|
|
|
| +static bool IsInteger32(double value) {
|
| + double roundtrip_value = static_cast<double>(static_cast<int32_t>(value));
|
| + return BitCast<int64_t>(roundtrip_value) == BitCast<int64_t>(value);
|
| +}
|
| +
|
| +
|
| 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_ = IsInteger32(n);
|
| + int32_value_ = DoubleToInt32(n);
|
| double_value_ = n;
|
| has_double_value_ = true;
|
| }
|
| }
|
|
|
|
|
| +HConstant::HConstant(int32_t integer_value, Representation r)
|
| + : has_int32_value_(true),
|
| + has_double_value_(true),
|
| + int32_value_(integer_value),
|
| + double_value_(FastI2D(integer_value)) {
|
| + set_representation(r);
|
| + SetFlag(kUseGVN);
|
| +}
|
| +
|
| +
|
| +HConstant::HConstant(double double_value, Representation r)
|
| + : has_int32_value_(IsInteger32(double_value)),
|
| + has_double_value_(true),
|
| + int32_value_(DoubleToInt32(double_value)),
|
| + double_value_(double_value) {
|
| + set_representation(r);
|
| + SetFlag(kUseGVN);
|
| +}
|
| +
|
| +
|
| HConstant* HConstant::CopyToRepresentation(Representation r, Zone* zone) const {
|
| if (r.IsInteger32() && !has_int32_value_) return NULL;
|
| if (r.IsDouble() && !has_double_value_) return NULL;
|
| + if (handle_.is_null()) {
|
| + ASSERT(has_int32_value_ || has_double_value_);
|
| + if (has_int32_value_) return new(zone) HConstant(int32_value_, r);
|
| + return new(zone) HConstant(double_value_, r);
|
| + }
|
| return new(zone) HConstant(handle_, r);
|
| }
|
|
|
|
|
| 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_) {
|
| + if (handle_.is_null()) {
|
| + return new(zone) HConstant(int32_value_, Representation::Integer32());
|
| + } else {
|
| + // Re-use the existing Handle if possible.
|
| + return new(zone) HConstant(handle_, Representation::Integer32());
|
| + }
|
| + } else if (has_double_value_) {
|
| + return new(zone) HConstant(DoubleToInt32(double_value_),
|
| + Representation::Integer32());
|
| + } 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 +1464,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,6 +2134,10 @@ HType HPhi::CalculateInferredType() {
|
|
|
|
|
| HType HConstant::CalculateInferredType() {
|
| + if (has_int32_value_) {
|
| + return Smi::IsValid(int32_value_) ? HType::Smi() : HType::HeapNumber();
|
| + }
|
| + if (has_double_value_) return HType::HeapNumber();
|
| return HType::TypeFromValue(handle_);
|
| }
|
|
|
|
|