Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(396)

Unified Diff: src/hydrogen-instructions.cc

Issue 10544196: Defer creating Handles for HConstants to the code generation phase. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebase & cosmetic changes. Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/hydrogen-instructions.cc
diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc
index d44e90ac04101799d3a6aa3b37178b430140f4fe..ff4a55638e90deac64ed1af00b378d967ab9730d 100644
--- a/src/hydrogen-instructions.cc
+++ b/src/hydrogen-instructions.cc
@@ -999,7 +999,7 @@ HValue* HCheckInstanceType::Canonicalize() {
}
if (check_ == IS_SYMBOL &&
value()->IsConstant() &&
- HConstant::cast(value())->handle()->IsSymbol()) {
+ HConstant::cast(value())->IsSymbol()) {
return NULL;
}
return this;
@@ -1384,33 +1384,135 @@ HConstant::HConstant(Handle<Object> handle, Representation r)
: handle_(handle),
has_int32_value_(false),
has_double_value_(false),
- int32_value_(0),
- double_value_(0) {
+ handle_was_smi_(handle->IsSmi()),
+ is_string_(false),
+ is_symbol_(false),
+ is_boolean_(false) {
set_representation(r);
SetFlag(kUseGVN);
- if (handle_->IsNumber()) {
+
+ // We try to use the fact that we've already checked if the handle
+ // is a Smi.
+ if (handle_was_smi_) {
+ has_int32_value_ = true;
+ has_double_value_ = true;
+ int32_value_ = Smi::cast(*handle)->value();
+ double_value_ = FastI2D(int32_value_);
+ } else if (handle_->IsHeapNumber()) {
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;
+ } else {
+ is_string_ = handle->IsString();
+ is_symbol_ = !is_string_ && handle->IsSymbol();
+ is_boolean_ = !is_symbol_ && !is_string_ && handle->IsBoolean();
+ }
+}
+
+
+HConstant::HConstant(int32_t integer_value, Representation r,
+ Handle<Object> handle)
+ : handle_(handle),
+ has_int32_value_(true),
+ has_double_value_(true),
+ is_string_(false),
+ is_symbol_(false),
+ is_boolean_(false) {
+ set_representation(r);
+ SetFlag(kUseGVN);
+ int32_value_ = integer_value;
+ double_value_ = FastI2D(integer_value);
+ if (handle.is_null()) {
+ // If we can safely represent this integer in 31 bits and we don't
+ // have a Handle to the HeapObject, we pretend it originated from
+ // a Smi. This is okay because when we _do_ create a HeapObject
+ // for this HConstant, it will be a Smi.
+ handle_was_smi_ = Smi::IsValid(static_cast<intptr_t>(integer_value));
+ } else {
+ handle_was_smi_ = handle->IsSmi();
+ }
+}
+
+
+HConstant::HConstant(double double_value, Representation r,
+ Handle<Object> handle)
+ : handle_(handle),
+ has_int32_value_(false),
+ has_double_value_(true),
+ handle_was_smi_(false),
+ is_string_(false),
+ is_symbol_(false),
+ is_boolean_(false),
+ 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);
+ if (handle.is_null()) {
+ handle_was_smi_ = has_int32_value_ && Smi::IsValid(static_cast<intptr_t>(
+ int32_value_));
+ } else {
+ handle_was_smi_ = handle->IsSmi();
+ }
+}
+
+
+void HConstant::EnsureHasHandle(Factory* factory) {
+ if (handle_.is_null()) {
+ ASSERT(has_int32_value_ || has_double_value_);
+ if (has_int32_value_) {
+ handle_ = factory->NewNumberFromInt(int32_value_, TENURED);
+ ASSERT(handle_->IsSmi() || !handle_was_smi_);
+ } else {
+ handle_ = factory->NewNumber(double_value_, TENURED);
+ }
}
}
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;
+ }
}
@@ -1432,7 +1534,13 @@ bool HConstant::ToBoolean() const {
}
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);
+ }
}
@@ -2077,7 +2185,9 @@ HType HPhi::CalculateInferredType() {
HType HConstant::CalculateInferredType() {
- return HType::TypeFromValue(handle_);
+ if (handle_was_smi_) return HType::Smi();
+ if (has_int32_value_ || has_double_value_) return HType::HeapNumber();
+ return HType::TypeFromValue(Handle<Object>(handle_));
}
@@ -2273,12 +2383,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, \

Powered by Google App Engine
This is Rietveld 408576698