Index: src/hydrogen-instructions.h |
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h |
index bd1dd403a79cbd397b2a9c56a48a590c71443216..c9b88034a63634da1d4cb588e2ea0f9c3ddff99f 100644 |
--- a/src/hydrogen-instructions.h |
+++ b/src/hydrogen-instructions.h |
@@ -304,58 +304,6 @@ class Range: public ZoneObject { |
}; |
-class Representation { |
- public: |
- enum Kind { |
- kNone, |
- kInteger32, |
- kDouble, |
- kTagged, |
- kExternal, |
- kNumRepresentations |
- }; |
- |
- Representation() : kind_(kNone) { } |
- |
- static Representation None() { return Representation(kNone); } |
- static Representation Tagged() { return Representation(kTagged); } |
- static Representation Integer32() { return Representation(kInteger32); } |
- static Representation Double() { return Representation(kDouble); } |
- static Representation External() { return Representation(kExternal); } |
- |
- static Representation FromKind(Kind kind) { return Representation(kind); } |
- |
- bool Equals(const Representation& other) { |
- return kind_ == other.kind_; |
- } |
- |
- bool is_more_general_than(const Representation& other) { |
- ASSERT(kind_ != kExternal); |
- ASSERT(other.kind_ != kExternal); |
- return kind_ > other.kind_; |
- } |
- |
- Kind kind() const { return static_cast<Kind>(kind_); } |
- bool IsNone() const { return kind_ == kNone; } |
- bool IsTagged() const { return kind_ == kTagged; } |
- bool IsInteger32() const { return kind_ == kInteger32; } |
- bool IsDouble() const { return kind_ == kDouble; } |
- bool IsExternal() const { return kind_ == kExternal; } |
- bool IsSpecialization() const { |
- return kind_ == kInteger32 || kind_ == kDouble; |
- } |
- const char* Mnemonic() const; |
- |
- private: |
- explicit Representation(Kind k) : kind_(k) { } |
- |
- // Make sure kind fits in int8. |
- STATIC_ASSERT(kNumRepresentations <= (1 << kBitsPerByte)); |
- |
- int8_t kind_; |
-}; |
- |
- |
class UniqueValueId { |
public: |
UniqueValueId() : raw_address_(NULL) { } |
@@ -5211,15 +5159,24 @@ class HStoreContextSlot: public HTemplateInstruction<2> { |
class HLoadNamedField: public HTemplateInstruction<2> { |
public: |
- HLoadNamedField(HValue* object, bool is_in_object, int offset, |
- HValue* typecheck = NULL) |
+ HLoadNamedField(HValue* object, bool is_in_object, |
+ Representation field_representation, |
+ int offset, HValue* typecheck = NULL) |
: is_in_object_(is_in_object), |
+ field_representation_(field_representation), |
offset_(offset) { |
ASSERT(object != NULL); |
SetOperandAt(0, object); |
SetOperandAt(1, typecheck != NULL ? typecheck : object); |
- set_representation(Representation::Tagged()); |
+ if (FLAG_track_fields && field_representation.IsSmi()) { |
+ set_type(HType::Smi()); |
+ set_representation(Representation::Tagged()); |
+ } else if (FLAG_track_double_fields && field_representation.IsDouble()) { |
+ set_representation(field_representation); |
+ } else { |
+ set_representation(Representation::Tagged()); |
+ } |
SetFlag(kUseGVN); |
SetGVNFlag(kDependsOnMaps); |
if (is_in_object) { |
@@ -5232,8 +5189,10 @@ class HLoadNamedField: public HTemplateInstruction<2> { |
static HLoadNamedField* NewArrayLength(Zone* zone, HValue* object, |
HValue* typecheck, |
HType type = HType::Tagged()) { |
+ Representation representation = |
+ type.IsSmi() ? Representation::Smi() : Representation::Tagged(); |
HLoadNamedField* result = new(zone) HLoadNamedField( |
- object, true, JSArray::kLengthOffset, typecheck); |
+ object, true, representation, JSArray::kLengthOffset, typecheck); |
result->set_type(type); |
result->SetGVNFlag(kDependsOnArrayLengths); |
result->ClearGVNFlag(kDependsOnInobjectFields); |
@@ -5248,6 +5207,7 @@ class HLoadNamedField: public HTemplateInstruction<2> { |
bool HasTypeCheck() const { return OperandAt(0) != OperandAt(1); } |
bool is_in_object() const { return is_in_object_; } |
+ Representation field_representation() const { return representation_; } |
int offset() const { return offset_; } |
virtual Representation RequiredInputRepresentation(int index) { |
@@ -5267,6 +5227,7 @@ class HLoadNamedField: public HTemplateInstruction<2> { |
virtual bool IsDeletable() const { return true; } |
bool is_in_object_; |
+ Representation field_representation_; |
int offset_; |
}; |
@@ -5564,9 +5525,11 @@ class HStoreNamedField: public HTemplateInstruction<2> { |
Handle<String> name, |
HValue* val, |
bool in_object, |
+ Representation field_representation, |
int offset) |
: name_(name), |
is_in_object_(in_object), |
+ field_representation_(field_representation), |
offset_(offset), |
transition_unique_id_(), |
new_space_dominator_(NULL) { |
@@ -5584,6 +5547,9 @@ class HStoreNamedField: public HTemplateInstruction<2> { |
DECLARE_CONCRETE_INSTRUCTION(StoreNamedField) |
virtual Representation RequiredInputRepresentation(int index) { |
+ if (FLAG_track_fields && index == 1 && field_representation_.IsSmi()) { |
+ return Representation::Integer32(); |
+ } |
return Representation::Tagged(); |
} |
virtual void SetSideEffectDominator(GVNFlag side_effect, HValue* dominator) { |
@@ -5604,7 +5570,8 @@ class HStoreNamedField: public HTemplateInstruction<2> { |
HValue* new_space_dominator() const { return new_space_dominator_; } |
bool NeedsWriteBarrier() { |
- return StoringValueNeedsWriteBarrier(value()) && |
+ return (!FLAG_track_fields || !field_representation_.IsSmi()) && |
+ StoringValueNeedsWriteBarrier(value()) && |
ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); |
} |
@@ -5616,9 +5583,14 @@ class HStoreNamedField: public HTemplateInstruction<2> { |
transition_unique_id_ = UniqueValueId(transition_); |
} |
+ Representation field_representation() const { |
+ return field_representation_; |
+ } |
+ |
private: |
Handle<String> name_; |
bool is_in_object_; |
+ Representation field_representation_; |
int offset_; |
Handle<Map> transition_; |
UniqueValueId transition_unique_id_; |