| Index: src/hydrogen-instructions.h
|
| diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
|
| index 74faf556ca57253bdaf3c15979c7684a9a8b8587..908faa8011d90142295ee522345fbaf69c0ac181 100644
|
| --- a/src/hydrogen-instructions.h
|
| +++ b/src/hydrogen-instructions.h
|
| @@ -12,6 +12,7 @@
|
| #include "conversions.h"
|
| #include "data-flow.h"
|
| #include "deoptimizer.h"
|
| +#include "hydrogen-types.h"
|
| #include "small-pointer-list.h"
|
| #include "string-stream.h"
|
| #include "unique.h"
|
| @@ -282,124 +283,6 @@ class Range V8_FINAL : public ZoneObject {
|
| };
|
|
|
|
|
| -class HType V8_FINAL {
|
| - public:
|
| - static HType None() { return HType(kNone); }
|
| - static HType Tagged() { return HType(kTagged); }
|
| - static HType TaggedPrimitive() { return HType(kTaggedPrimitive); }
|
| - static HType TaggedNumber() { return HType(kTaggedNumber); }
|
| - static HType Smi() { return HType(kSmi); }
|
| - static HType HeapNumber() { return HType(kHeapNumber); }
|
| - static HType String() { return HType(kString); }
|
| - static HType Boolean() { return HType(kBoolean); }
|
| - static HType NonPrimitive() { return HType(kNonPrimitive); }
|
| - static HType JSArray() { return HType(kJSArray); }
|
| - static HType JSObject() { return HType(kJSObject); }
|
| -
|
| - // Return the weakest (least precise) common type.
|
| - HType Combine(HType other) {
|
| - return HType(static_cast<Type>(type_ & other.type_));
|
| - }
|
| -
|
| - bool Equals(const HType& other) const {
|
| - return type_ == other.type_;
|
| - }
|
| -
|
| - bool IsSubtypeOf(const HType& other) {
|
| - return Combine(other).Equals(other);
|
| - }
|
| -
|
| - bool IsTaggedPrimitive() const {
|
| - return ((type_ & kTaggedPrimitive) == kTaggedPrimitive);
|
| - }
|
| -
|
| - bool IsTaggedNumber() const {
|
| - return ((type_ & kTaggedNumber) == kTaggedNumber);
|
| - }
|
| -
|
| - bool IsSmi() const {
|
| - return ((type_ & kSmi) == kSmi);
|
| - }
|
| -
|
| - bool IsHeapNumber() const {
|
| - return ((type_ & kHeapNumber) == kHeapNumber);
|
| - }
|
| -
|
| - bool IsString() const {
|
| - return ((type_ & kString) == kString);
|
| - }
|
| -
|
| - bool IsNonString() const {
|
| - return IsTaggedPrimitive() || IsSmi() || IsHeapNumber() ||
|
| - IsBoolean() || IsJSArray();
|
| - }
|
| -
|
| - bool IsBoolean() const {
|
| - return ((type_ & kBoolean) == kBoolean);
|
| - }
|
| -
|
| - bool IsNonPrimitive() const {
|
| - return ((type_ & kNonPrimitive) == kNonPrimitive);
|
| - }
|
| -
|
| - bool IsJSArray() const {
|
| - return ((type_ & kJSArray) == kJSArray);
|
| - }
|
| -
|
| - bool IsJSObject() const {
|
| - return ((type_ & kJSObject) == kJSObject);
|
| - }
|
| -
|
| - bool IsHeapObject() const {
|
| - return IsHeapNumber() || IsString() || IsBoolean() || IsNonPrimitive();
|
| - }
|
| -
|
| - bool ToStringOrToNumberCanBeObserved(Representation representation) {
|
| - switch (type_) {
|
| - case kTaggedPrimitive: // fallthru
|
| - case kTaggedNumber: // fallthru
|
| - case kSmi: // fallthru
|
| - case kHeapNumber: // fallthru
|
| - case kString: // fallthru
|
| - case kBoolean:
|
| - return false;
|
| - case kJSArray: // fallthru
|
| - case kJSObject:
|
| - return true;
|
| - case kTagged:
|
| - break;
|
| - }
|
| - return !representation.IsSmiOrInteger32() && !representation.IsDouble();
|
| - }
|
| -
|
| - static HType TypeFromValue(Handle<Object> value);
|
| -
|
| - const char* ToString();
|
| -
|
| - private:
|
| - enum Type {
|
| - kNone = 0x0, // 0000 0000 0000 0000
|
| - kTagged = 0x1, // 0000 0000 0000 0001
|
| - kTaggedPrimitive = 0x5, // 0000 0000 0000 0101
|
| - kTaggedNumber = 0xd, // 0000 0000 0000 1101
|
| - kSmi = 0x1d, // 0000 0000 0001 1101
|
| - kHeapNumber = 0x2d, // 0000 0000 0010 1101
|
| - kString = 0x45, // 0000 0000 0100 0101
|
| - kBoolean = 0x85, // 0000 0000 1000 0101
|
| - kNonPrimitive = 0x101, // 0000 0001 0000 0001
|
| - kJSObject = 0x301, // 0000 0011 0000 0001
|
| - kJSArray = 0x701 // 0000 0111 0000 0001
|
| - };
|
| -
|
| - // Make sure type fits in int16.
|
| - STATIC_ASSERT(kJSArray < (1 << (2 * kBitsPerByte)));
|
| -
|
| - explicit HType(Type t) : type_(t) { }
|
| -
|
| - int16_t type_;
|
| -};
|
| -
|
| -
|
| class HUseListNode: public ZoneObject {
|
| public:
|
| HUseListNode(HValue* value, int index, HUseListNode* tail)
|
| @@ -727,10 +610,6 @@ class HValue : public ZoneObject {
|
| type_ = new_type;
|
| }
|
|
|
| - bool IsHeapObject() {
|
| - return representation_.IsHeapObject() || type_.IsHeapObject();
|
| - }
|
| -
|
| // There are HInstructions that do not really change a value, they
|
| // only add pieces of information to it (like bounds checks, map checks,
|
| // smi checks...).
|
| @@ -933,13 +812,13 @@ class HValue : public ZoneObject {
|
| // Returns true conservatively if the program might be able to observe a
|
| // ToString() operation on this value.
|
| bool ToStringCanBeObserved() const {
|
| - return type().ToStringOrToNumberCanBeObserved(representation());
|
| + return ToStringOrToNumberCanBeObserved();
|
| }
|
|
|
| // Returns true conservatively if the program might be able to observe a
|
| // ToNumber() operation on this value.
|
| bool ToNumberCanBeObserved() const {
|
| - return type().ToStringOrToNumberCanBeObserved(representation());
|
| + return ToStringOrToNumberCanBeObserved();
|
| }
|
|
|
| MinusZeroMode GetMinusZeroMode() {
|
| @@ -955,6 +834,12 @@ class HValue : public ZoneObject {
|
| return false;
|
| }
|
|
|
| + bool ToStringOrToNumberCanBeObserved() const {
|
| + if (type().IsTaggedPrimitive()) return false;
|
| + if (type().IsJSObject()) return true;
|
| + return !representation().IsSmiOrInteger32() && !representation().IsDouble();
|
| + }
|
| +
|
| virtual Representation RepresentationFromInputs() {
|
| return representation();
|
| }
|
| @@ -2839,10 +2724,16 @@ class HCheckMaps V8_FINAL : public HTemplateInstruction<2> {
|
| virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
|
| return Representation::Tagged();
|
| }
|
| +
|
| + virtual HType CalculateInferredType() V8_OVERRIDE {
|
| + if (value()->type().IsHeapObject()) return value()->type();
|
| + return HType::HeapObject();
|
| + }
|
| +
|
| virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
|
|
|
| - HValue* value() { return OperandAt(0); }
|
| - HValue* typecheck() { return OperandAt(1); }
|
| + HValue* value() const { return OperandAt(0); }
|
| + HValue* typecheck() const { return OperandAt(1); }
|
|
|
| const UniqueSet<Map>* maps() const { return maps_; }
|
| void set_maps(const UniqueSet<Map>* maps) { maps_ = maps; }
|
| @@ -2881,7 +2772,7 @@ class HCheckMaps V8_FINAL : public HTemplateInstruction<2> {
|
|
|
| private:
|
| HCheckMaps(HValue* value, const UniqueSet<Map>* maps, bool maps_are_stable)
|
| - : HTemplateInstruction<2>(value->type()), maps_(maps),
|
| + : HTemplateInstruction<2>(HType::HeapObject()), maps_(maps),
|
| has_migration_target_(false), is_stability_check_(false),
|
| maps_are_stable_(maps_are_stable) {
|
| ASSERT_NE(0, maps->size());
|
| @@ -2895,7 +2786,7 @@ class HCheckMaps V8_FINAL : public HTemplateInstruction<2> {
|
| }
|
|
|
| HCheckMaps(HValue* value, const UniqueSet<Map>* maps, HValue* typecheck)
|
| - : HTemplateInstruction<2>(value->type()), maps_(maps),
|
| + : HTemplateInstruction<2>(HType::HeapObject()), maps_(maps),
|
| has_migration_target_(false), is_stability_check_(false),
|
| maps_are_stable_(true) {
|
| ASSERT_NE(0, maps->size());
|
| @@ -2999,6 +2890,17 @@ class HCheckInstanceType V8_FINAL : public HUnaryOperation {
|
| return Representation::Tagged();
|
| }
|
|
|
| + virtual HType CalculateInferredType() V8_OVERRIDE {
|
| + switch (check_) {
|
| + case IS_SPEC_OBJECT: return HType::JSObject();
|
| + case IS_JS_ARRAY: return HType::JSArray();
|
| + case IS_STRING: return HType::String();
|
| + case IS_INTERNALIZED_STRING: return HType::String();
|
| + }
|
| + UNREACHABLE();
|
| + return HType::Tagged();
|
| + }
|
| +
|
| virtual HValue* Canonicalize() V8_OVERRIDE;
|
|
|
| bool is_interval_check() const { return check_ <= LAST_INTERVAL_CHECK; }
|
| @@ -3022,7 +2924,7 @@ class HCheckInstanceType V8_FINAL : public HUnaryOperation {
|
| const char* GetCheckName();
|
|
|
| HCheckInstanceType(HValue* value, Check check)
|
| - : HUnaryOperation(value), check_(check) {
|
| + : HUnaryOperation(value, HType::HeapObject()), check_(check) {
|
| set_representation(Representation::Tagged());
|
| SetFlag(kUseGVN);
|
| }
|
| @@ -3069,6 +2971,11 @@ class HCheckHeapObject V8_FINAL : public HUnaryOperation {
|
| return Representation::Tagged();
|
| }
|
|
|
| + virtual HType CalculateInferredType() V8_OVERRIDE {
|
| + if (value()->type().IsHeapObject()) return value()->type();
|
| + return HType::HeapObject();
|
| + }
|
| +
|
| #ifdef DEBUG
|
| virtual void Verify() V8_OVERRIDE;
|
| #endif
|
| @@ -3083,8 +2990,7 @@ class HCheckHeapObject V8_FINAL : public HUnaryOperation {
|
| virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; }
|
|
|
| private:
|
| - explicit HCheckHeapObject(HValue* value)
|
| - : HUnaryOperation(value, HType::NonPrimitive()) {
|
| + explicit HCheckHeapObject(HValue* value) : HUnaryOperation(value) {
|
| set_representation(Representation::Tagged());
|
| SetFlag(kUseGVN);
|
| }
|
| @@ -3566,7 +3472,7 @@ class HConstant V8_FINAL : public HTemplateInstruction<0> {
|
| HInstruction* instruction) {
|
| return instruction->Prepend(new(zone) HConstant(
|
| map, Unique<Map>(Handle<Map>::null()), map_is_stable,
|
| - Representation::Tagged(), HType::Tagged(), true,
|
| + Representation::Tagged(), HType::HeapObject(), true,
|
| false, false, MAP_TYPE));
|
| }
|
|
|
| @@ -3576,7 +3482,7 @@ class HConstant V8_FINAL : public HTemplateInstruction<0> {
|
| HInstruction* instruction) {
|
| return instruction->Append(new(zone) HConstant(
|
| map, Unique<Map>(Handle<Map>::null()), map_is_stable,
|
| - Representation::Tagged(), HType::Tagged(), true,
|
| + Representation::Tagged(), HType::HeapObject(), true,
|
| false, false, MAP_TYPE));
|
| }
|
|
|
| @@ -4187,7 +4093,7 @@ class HBoundsCheckBaseIndexInformation V8_FINAL
|
| class HBitwiseBinaryOperation : public HBinaryOperation {
|
| public:
|
| HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right,
|
| - HType type = HType::Tagged())
|
| + HType type = HType::TaggedNumber())
|
| : HBinaryOperation(context, left, right, type) {
|
| SetFlag(kFlexibleRepresentation);
|
| SetFlag(kTruncatingToInt32);
|
| @@ -5140,7 +5046,7 @@ class HBitwise V8_FINAL : public HBitwiseBinaryOperation {
|
| Token::Value op,
|
| HValue* left,
|
| HValue* right)
|
| - : HBitwiseBinaryOperation(context, left, right, HType::TaggedNumber()),
|
| + : HBitwiseBinaryOperation(context, left, right),
|
| op_(op) {
|
| ASSERT(op == Token::BIT_AND || op == Token::BIT_OR || op == Token::BIT_XOR);
|
| // BIT_AND with a smi-range positive value will always unset the
|
| @@ -5719,7 +5625,7 @@ class HInnerAllocatedObject V8_FINAL : public HTemplateInstruction<2> {
|
| HValue* context,
|
| HValue* value,
|
| HValue* offset,
|
| - HType type = HType::Tagged()) {
|
| + HType type) {
|
| return new(zone) HInnerAllocatedObject(value, offset, type);
|
| }
|
|
|
| @@ -5737,20 +5643,21 @@ class HInnerAllocatedObject V8_FINAL : public HTemplateInstruction<2> {
|
| private:
|
| HInnerAllocatedObject(HValue* value,
|
| HValue* offset,
|
| - HType type = HType::Tagged())
|
| - : HTemplateInstruction<2>(type) {
|
| + HType type) : HTemplateInstruction<2>(type) {
|
| ASSERT(value->IsAllocate());
|
| + ASSERT(type.IsHeapObject());
|
| SetOperandAt(0, value);
|
| SetOperandAt(1, offset);
|
| - set_type(type);
|
| set_representation(Representation::Tagged());
|
| }
|
| };
|
|
|
|
|
| inline bool StoringValueNeedsWriteBarrier(HValue* value) {
|
| - return !value->type().IsBoolean()
|
| - && !value->type().IsSmi()
|
| + return !value->type().IsSmi()
|
| + && !value->type().IsNull()
|
| + && !value->type().IsBoolean()
|
| + && !value->type().IsUndefined()
|
| && !(value->IsConstant() && HConstant::cast(value)->ImmortalImmovable());
|
| }
|
|
|
| @@ -6371,9 +6278,7 @@ class HLoadNamedField V8_FINAL : public HTemplateInstruction<2> {
|
| representation.IsInteger32()) {
|
| set_representation(representation);
|
| } else if (representation.IsHeapObject()) {
|
| - // TODO(bmeurer): This is probably broken. What we actually want to to
|
| - // instead is set_representation(Representation::HeapObject()).
|
| - set_type(HType::NonPrimitive());
|
| + set_type(HType::HeapObject());
|
| set_representation(Representation::Tagged());
|
| } else {
|
| set_representation(Representation::Tagged());
|
| @@ -6395,9 +6300,7 @@ class HLoadNamedField V8_FINAL : public HTemplateInstruction<2> {
|
| SetOperandAt(1, dependency ? dependency : object);
|
|
|
| ASSERT(access.representation().IsHeapObject());
|
| - // TODO(bmeurer): This is probably broken. What we actually want to to
|
| - // instead is set_representation(Representation::HeapObject()).
|
| - if (!type.IsHeapObject()) set_type(HType::NonPrimitive());
|
| + ASSERT(type.IsHeapObject());
|
| set_representation(Representation::Tagged());
|
|
|
| access.SetGVNFlags(this, LOAD);
|
| @@ -6813,7 +6716,7 @@ class HStoreNamedField V8_FINAL : public HTemplateInstruction<3> {
|
|
|
| SmiCheck SmiCheckForWriteBarrier() const {
|
| if (field_representation().IsHeapObject()) return OMIT_SMI_CHECK;
|
| - if (value()->IsHeapObject()) return OMIT_SMI_CHECK;
|
| + if (value()->type().IsHeapObject()) return OMIT_SMI_CHECK;
|
| return INLINE_SMI_CHECK;
|
| }
|
|
|
| @@ -7673,11 +7576,12 @@ class HCheckMapValue V8_FINAL : public HTemplateInstruction<2> {
|
| virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
|
|
|
| virtual HType CalculateInferredType() V8_OVERRIDE {
|
| - return HType::Tagged();
|
| + if (value()->type().IsHeapObject()) return value()->type();
|
| + return HType::HeapObject();
|
| }
|
|
|
| - HValue* value() { return OperandAt(0); }
|
| - HValue* map() { return OperandAt(1); }
|
| + HValue* value() const { return OperandAt(0); }
|
| + HValue* map() const { return OperandAt(1); }
|
|
|
| virtual HValue* Canonicalize() V8_OVERRIDE;
|
|
|
| @@ -7691,8 +7595,8 @@ class HCheckMapValue V8_FINAL : public HTemplateInstruction<2> {
|
| }
|
|
|
| private:
|
| - HCheckMapValue(HValue* value,
|
| - HValue* map) {
|
| + HCheckMapValue(HValue* value, HValue* map)
|
| + : HTemplateInstruction<2>(HType::HeapObject()) {
|
| SetOperandAt(0, value);
|
| SetOperandAt(1, map);
|
| set_representation(Representation::Tagged());
|
|
|