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

Unified Diff: src/hydrogen-instructions.h

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: Review. Created 8 years, 5 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.h
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index fb6fe29ed6bdbd7a87be40825fa1ee0a4de246ac..8fe31f0dc143bb4d1f65ba96f086202f2bff7915 100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -2453,20 +2453,42 @@ class HArgumentsObject: public HTemplateInstruction<0> {
class HConstant: public HTemplateInstruction<0> {
public:
HConstant(Handle<Object> handle, Representation r);
+ HConstant(int32_t value, Representation r);
+ HConstant(double value, Representation r);
- Handle<Object> handle() const { return handle_; }
+ Handle<Object> handle() {
+ if (handle_.is_null()) {
+ handle_ = FACTORY->NewNumber(double_value_, TENURED);
+ }
+ ASSERT(has_int32_value_ || !handle_->IsSmi());
+ 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;
+ }
+
+ ASSERT(!handle_.is_null());
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;
}
@@ -2475,19 +2497,20 @@ class HConstant: public HTemplateInstruction<0> {
return Representation::None();
}
+ 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.
+ 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() { return handle()->IsSmi(); }
HConstant* CopyToRepresentation(Representation r, Zone* zone) const;
HConstant* CopyToTruncatedInt32(Zone* zone) const;
bool HasInteger32Value() const { return has_int32_value_; }
@@ -2500,24 +2523,33 @@ 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_;
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.
}
- bool HasStringValue() const { return handle_->IsString(); }
- bool ToBoolean() const;
+ bool ToBoolean();
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;
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.
+ 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
@@ -2531,15 +2563,32 @@ 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:
+ // 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.
+ // 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.
bool has_int32_value_ : 1;
bool has_double_value_ : 1;
int32_t int32_value_;

Powered by Google App Engine
This is Rietveld 408576698