summaryrefslogtreecommitdiff
path: root/deps/v8/src/hydrogen-instructions.h
diff options
context:
space:
mode:
authorRyan Dahl <ry@tinyclouds.org>2011-07-08 16:40:11 -0700
committerRyan Dahl <ry@tinyclouds.org>2011-07-08 16:40:11 -0700
commite5564a3f29e0a818832a97c7c3b28d7c8b3b0460 (patch)
tree4b48a6577080d5e44da4d2cbebb7fe7951660de8 /deps/v8/src/hydrogen-instructions.h
parent0df2f74d364826053641395b01c2fcb1345057a9 (diff)
downloadnode-e5564a3f29e0a818832a97c7c3b28d7c8b3b0460.tar.gz
Upgrade V8 to 3.4.10
Diffstat (limited to 'deps/v8/src/hydrogen-instructions.h')
-rw-r--r--deps/v8/src/hydrogen-instructions.h1897
1 files changed, 1271 insertions, 626 deletions
diff --git a/deps/v8/src/hydrogen-instructions.h b/deps/v8/src/hydrogen-instructions.h
index 1bce34beb..cc32b9383 100644
--- a/deps/v8/src/hydrogen-instructions.h
+++ b/deps/v8/src/hydrogen-instructions.h
@@ -29,8 +29,14 @@
#define V8_HYDROGEN_INSTRUCTIONS_H_
#include "v8.h"
+
+#include "allocation.h"
#include "code-stubs.h"
+#include "data-flow.h"
+#include "small-pointer-list.h"
#include "string-stream.h"
+#include "v8conversions.h"
+#include "v8utils.h"
#include "zone.h"
namespace v8 {
@@ -46,18 +52,10 @@ class LInstruction;
class LChunkBuilder;
-#define HYDROGEN_ALL_INSTRUCTION_LIST(V) \
- V(ArithmeticBinaryOperation) \
- V(BinaryCall) \
- V(BinaryOperation) \
+#define HYDROGEN_ABSTRACT_INSTRUCTION_LIST(V) \
V(BitwiseBinaryOperation) \
V(ControlInstruction) \
V(Instruction) \
- V(Phi) \
- V(UnaryCall) \
- V(UnaryControlInstruction) \
- V(UnaryOperation) \
- HYDROGEN_CONCRETE_INSTRUCTION_LIST(V)
#define HYDROGEN_CONCRETE_INSTRUCTION_LIST(V) \
@@ -75,6 +73,7 @@ class LChunkBuilder;
V(BitXor) \
V(BlockEntry) \
V(BoundsCheck) \
+ V(Branch) \
V(CallConstantFunction) \
V(CallFunction) \
V(CallGlobal) \
@@ -91,49 +90,59 @@ class LChunkBuilder;
V(CheckNonSmi) \
V(CheckPrototypeMaps) \
V(CheckSmi) \
- V(Compare) \
- V(CompareJSObjectEq) \
+ V(ClampToUint8) \
+ V(ClassOfTestAndBranch) \
+ V(CompareIDAndBranch) \
+ V(CompareGeneric) \
+ V(CompareObjectEqAndBranch) \
V(CompareMap) \
+ V(CompareConstantEqAndBranch) \
V(Constant) \
V(Context) \
V(DeleteProperty) \
V(Deoptimize) \
V(Div) \
+ V(ElementsKind) \
V(EnterInlined) \
+ V(ExternalArrayLength) \
V(FixedArrayLength) \
+ V(ForceRepresentation) \
V(FunctionLiteral) \
V(GetCachedArrayIndex) \
V(GlobalObject) \
V(GlobalReceiver) \
V(Goto) \
+ V(HasCachedArrayIndexAndBranch) \
+ V(HasInstanceTypeAndBranch) \
+ V(In) \
V(InstanceOf) \
V(InstanceOfKnownGlobal) \
- V(IsNull) \
- V(IsObject) \
- V(IsSmi) \
- V(IsConstructCall) \
- V(HasInstanceType) \
- V(HasCachedArrayIndex) \
+ V(InvokeFunction) \
+ V(IsConstructCallAndBranch) \
+ V(IsNullAndBranch) \
+ V(IsObjectAndBranch) \
+ V(IsSmiAndBranch) \
+ V(IsUndetectableAndBranch) \
V(JSArrayLength) \
- V(ClassOfTest) \
V(LeaveInlined) \
V(LoadContextSlot) \
V(LoadElements) \
+ V(LoadExternalArrayPointer) \
V(LoadFunctionPrototype) \
- V(LoadGlobal) \
+ V(LoadGlobalCell) \
+ V(LoadGlobalGeneric) \
V(LoadKeyedFastElement) \
V(LoadKeyedGeneric) \
+ V(LoadKeyedSpecializedArrayElement) \
V(LoadNamedField) \
+ V(LoadNamedFieldPolymorphic) \
V(LoadNamedGeneric) \
- V(LoadPixelArrayElement) \
- V(LoadPixelArrayExternalPointer) \
V(Mod) \
V(Mul) \
V(ObjectLiteral) \
V(OsrEntry) \
V(OuterContext) \
V(Parameter) \
- V(PixelArrayLength) \
V(Power) \
V(PushArgument) \
V(RegExpLiteral) \
@@ -142,23 +151,30 @@ class LChunkBuilder;
V(Shl) \
V(Shr) \
V(Simulate) \
+ V(SoftDeoptimize) \
V(StackCheck) \
V(StoreContextSlot) \
- V(StoreGlobal) \
+ V(StoreGlobalCell) \
+ V(StoreGlobalGeneric) \
V(StoreKeyedFastElement) \
- V(StorePixelArrayElement) \
V(StoreKeyedGeneric) \
+ V(StoreKeyedSpecializedArrayElement) \
V(StoreNamedField) \
V(StoreNamedGeneric) \
+ V(StringAdd) \
V(StringCharCodeAt) \
+ V(StringCharFromCode) \
V(StringLength) \
V(Sub) \
- V(Test) \
+ V(ThisFunction) \
V(Throw) \
+ V(ToFastProperties) \
+ V(ToInt32) \
V(Typeof) \
- V(TypeofIs) \
+ V(TypeofIsAndBranch) \
V(UnaryMathOperation) \
V(UnknownOSRValue) \
+ V(UseConst) \
V(ValueOf)
#define GVN_FLAG_LIST(V) \
@@ -166,105 +182,74 @@ class LChunkBuilder;
V(InobjectFields) \
V(BackingStoreFields) \
V(ArrayElements) \
- V(PixelArrayElements) \
+ V(SpecializedArrayElements) \
V(GlobalVars) \
V(Maps) \
V(ArrayLengths) \
V(ContextSlots) \
V(OsrEntries)
-#define DECLARE_INSTRUCTION(type) \
+#define DECLARE_ABSTRACT_INSTRUCTION(type) \
virtual bool Is##type() const { return true; } \
static H##type* cast(HValue* value) { \
ASSERT(value->Is##type()); \
return reinterpret_cast<H##type*>(value); \
- } \
- Opcode opcode() const { return HValue::k##type; }
+ }
-#define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic) \
+#define DECLARE_CONCRETE_INSTRUCTION(type) \
virtual LInstruction* CompileToLithium(LChunkBuilder* builder); \
- virtual const char* Mnemonic() const { return mnemonic; } \
- DECLARE_INSTRUCTION(type)
+ static H##type* cast(HValue* value) { \
+ ASSERT(value->Is##type()); \
+ return reinterpret_cast<H##type*>(value); \
+ } \
+ virtual Opcode opcode() const { return HValue::k##type; }
class Range: public ZoneObject {
public:
- Range() : lower_(kMinInt),
- upper_(kMaxInt),
- next_(NULL),
- can_be_minus_zero_(false) { }
+ Range()
+ : lower_(kMinInt),
+ upper_(kMaxInt),
+ next_(NULL),
+ can_be_minus_zero_(false) { }
Range(int32_t lower, int32_t upper)
- : lower_(lower), upper_(upper), next_(NULL), can_be_minus_zero_(false) { }
+ : lower_(lower),
+ upper_(upper),
+ next_(NULL),
+ can_be_minus_zero_(false) { }
- bool IsInSmiRange() const {
- return lower_ >= Smi::kMinValue && upper_ <= Smi::kMaxValue;
- }
- void KeepOrder();
- void Verify() const;
int32_t upper() const { return upper_; }
int32_t lower() const { return lower_; }
Range* next() const { return next_; }
Range* CopyClearLower() const { return new Range(kMinInt, upper_); }
Range* CopyClearUpper() const { return new Range(lower_, kMaxInt); }
- void ClearLower() { lower_ = kMinInt; }
- void ClearUpper() { upper_ = kMaxInt; }
Range* Copy() const { return new Range(lower_, upper_); }
- bool IsMostGeneric() const { return lower_ == kMinInt && upper_ == kMaxInt; }
int32_t Mask() const;
void set_can_be_minus_zero(bool b) { can_be_minus_zero_ = b; }
bool CanBeMinusZero() const { return CanBeZero() && can_be_minus_zero_; }
bool CanBeZero() const { return upper_ >= 0 && lower_ <= 0; }
bool CanBeNegative() const { return lower_ < 0; }
- bool Includes(int value) const {
- return lower_ <= value && upper_ >= value;
- }
-
- void Sar(int32_t value) {
- int32_t bits = value & 0x1F;
- lower_ = lower_ >> bits;
- upper_ = upper_ >> bits;
- set_can_be_minus_zero(false);
- }
-
- void Shl(int32_t value) {
- int32_t bits = value & 0x1F;
- int old_lower = lower_;
- int old_upper = upper_;
- lower_ = lower_ << bits;
- upper_ = upper_ << bits;
- if (old_lower != lower_ >> bits || old_upper != upper_ >> bits) {
- upper_ = kMaxInt;
- lower_ = kMinInt;
- }
- set_can_be_minus_zero(false);
+ bool Includes(int value) const { return lower_ <= value && upper_ >= value; }
+ bool IsMostGeneric() const { return lower_ == kMinInt && upper_ == kMaxInt; }
+ bool IsInSmiRange() const {
+ return lower_ >= Smi::kMinValue && upper_ <= Smi::kMaxValue;
}
-
- // Adds a constant to the lower and upper bound of the range.
- void AddConstant(int32_t value);
+ void KeepOrder();
+ void Verify() const;
void StackUpon(Range* other) {
Intersect(other);
next_ = other;
}
- void Intersect(Range* other) {
- upper_ = Min(upper_, other->upper_);
- lower_ = Max(lower_, other->lower_);
- bool b = CanBeMinusZero() && other->CanBeMinusZero();
- set_can_be_minus_zero(b);
- }
+ void Intersect(Range* other);
+ void Union(Range* other);
- void Union(Range* other) {
- upper_ = Max(upper_, other->upper_);
- lower_ = Min(lower_, other->lower_);
- bool b = CanBeMinusZero() || other->CanBeMinusZero();
- set_can_be_minus_zero(b);
- }
-
- // Compute a new result range and return true, if the operation
- // can overflow.
+ void AddConstant(int32_t value);
+ void Sar(int32_t value);
+ void Shl(int32_t value);
bool AddAndCheckOverflow(Range* other);
bool SubAndCheckOverflow(Range* other);
bool MulAndCheckOverflow(Range* other);
@@ -300,7 +285,7 @@ class Representation {
return kind_ == other.kind_;
}
- Kind kind() const { return 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; }
@@ -314,7 +299,10 @@ class Representation {
private:
explicit Representation(Kind k) : kind_(k) { }
- Kind kind_;
+ // Make sure kind fits in int8.
+ STATIC_ASSERT(kNumRepresentations <= (1 << kBitsPerByte));
+
+ int8_t kind_;
};
@@ -417,13 +405,72 @@ class HType {
kBoolean = 0x85, // 0000 0000 1000 0101
kNonPrimitive = 0x101, // 0000 0001 0000 0001
kJSObject = 0x301, // 0000 0011 0000 0001
- kJSArray = 0x701, // 0000 0111 1000 0001
+ kJSArray = 0x701, // 0000 0111 0000 0001
kUninitialized = 0x1fff // 0001 1111 1111 1111
};
+ // Make sure type fits in int16.
+ STATIC_ASSERT(kUninitialized < (1 << (2 * kBitsPerByte)));
+
explicit HType(Type t) : type_(t) { }
- Type type_;
+ int16_t type_;
+};
+
+
+class HUseListNode: public ZoneObject {
+ public:
+ HUseListNode(HValue* value, int index, HUseListNode* tail)
+ : tail_(tail), value_(value), index_(index) {
+ }
+
+ HUseListNode* tail() const { return tail_; }
+ HValue* value() const { return value_; }
+ int index() const { return index_; }
+
+ void set_tail(HUseListNode* list) { tail_ = list; }
+
+#ifdef DEBUG
+ void Zap() {
+ tail_ = reinterpret_cast<HUseListNode*>(1);
+ value_ = NULL;
+ index_ = -1;
+ }
+#endif
+
+ private:
+ HUseListNode* tail_;
+ HValue* value_;
+ int index_;
+};
+
+
+// We reuse use list nodes behind the scenes as uses are added and deleted.
+// This class is the safe way to iterate uses while deleting them.
+class HUseIterator BASE_EMBEDDED {
+ public:
+ bool Done() { return current_ == NULL; }
+ void Advance();
+
+ HValue* value() {
+ ASSERT(!Done());
+ return value_;
+ }
+
+ int index() {
+ ASSERT(!Done());
+ return index_;
+ }
+
+ private:
+ explicit HUseIterator(HUseListNode* head);
+
+ HUseListNode* current_;
+ HUseListNode* next_;
+ HValue* value_;
+ int index_;
+
+ friend class HValue;
};
@@ -440,10 +487,15 @@ class HValue: public ZoneObject {
GVN_FLAG_LIST(DECLARE_DO)
#undef DECLARE_DO
kFlexibleRepresentation,
+ // Participate in Global Value Numbering, i.e. elimination of
+ // unnecessary recomputations. If an instruction sets this flag, it must
+ // implement DataEquals(), which will be used to determine if other
+ // occurrences of the instruction are indeed the same.
kUseGVN,
kCanOverflow,
kBailoutOnMinusZero,
kCanBeDivByZero,
+ kDeoptimizeOnUndefined,
kIsArguments,
kTruncatingToInt32,
kLastFlag = kTruncatingToInt32
@@ -474,16 +526,30 @@ class HValue: public ZoneObject {
enum Opcode {
// Declare a unique enum value for each hydrogen instruction.
- #define DECLARE_DO(type) k##type,
- HYDROGEN_ALL_INSTRUCTION_LIST(DECLARE_DO)
- #undef DECLARE_DO
- kMaxInstructionClass
+ #define DECLARE_OPCODE(type) k##type,
+ HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_OPCODE)
+ kPhi
+ #undef DECLARE_OPCODE
};
+ virtual Opcode opcode() const = 0;
+
+ // Declare a non-virtual predicates for each concrete HInstruction or HValue.
+ #define DECLARE_PREDICATE(type) \
+ bool Is##type() const { return opcode() == k##type; }
+ HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_PREDICATE)
+ #undef DECLARE_PREDICATE
+ bool IsPhi() const { return opcode() == kPhi; }
+
+ // Declare virtual predicates for abstract HInstruction or HValue
+ #define DECLARE_PREDICATE(type) \
+ virtual bool Is##type() const { return false; }
+ HYDROGEN_ABSTRACT_INSTRUCTION_LIST(DECLARE_PREDICATE)
+ #undef DECLARE_PREDICATE
HValue() : block_(NULL),
id_(kNoNumber),
- uses_(2),
type_(HType::Tagged()),
+ use_list_(NULL),
range_(NULL),
flags_(0) {}
virtual ~HValue() {}
@@ -494,22 +560,24 @@ class HValue: public ZoneObject {
int id() const { return id_; }
void set_id(int id) { id_ = id; }
- const ZoneList<HValue*>* uses() const { return &uses_; }
+ HUseIterator uses() const { return HUseIterator(use_list_); }
- virtual bool EmitAtUses() const { return false; }
+ virtual bool EmitAtUses() { return false; }
Representation representation() const { return representation_; }
void ChangeRepresentation(Representation r) {
// Representation was already set and is allowed to be changed.
- ASSERT(!representation_.IsNone());
ASSERT(!r.IsNone());
ASSERT(CheckFlag(kFlexibleRepresentation));
RepresentationChanged(r);
representation_ = r;
}
+ void AssumeRepresentation(Representation r);
+
+ virtual bool IsConvertibleToInteger() const { return true; }
HType type() const { return type_; }
void set_type(HType type) {
- ASSERT(uses_.length() == 0);
+ ASSERT(HasNoUses());
type_ = type;
}
@@ -535,16 +603,14 @@ class HValue: public ZoneObject {
virtual HValue* OperandAt(int index) = 0;
void SetOperandAt(int index, HValue* value);
- int LookupOperandIndex(int occurrence_index, HValue* op);
- bool UsesMultipleTimes(HValue* op);
-
- void ReplaceAndDelete(HValue* other);
- void ReplaceValue(HValue* other);
- void ReplaceAtUse(HValue* use, HValue* other);
- void ReplaceFirstAtUse(HValue* use, HValue* other, Representation r);
- bool HasNoUses() const { return uses_.is_empty(); }
+ void DeleteAndReplaceWith(HValue* other);
+ void ReplaceAllUsesWith(HValue* other);
+ bool HasNoUses() const { return use_list_ == NULL; }
+ bool HasMultipleUses() const {
+ return use_list_ != NULL && use_list_->tail() != NULL;
+ }
+ int UseCount() const;
void ClearOperands();
- void Delete();
int flags() const { return flags_; }
void SetFlag(Flag f) { flags_ |= (1 << f); }
@@ -574,21 +640,17 @@ class HValue: public ZoneObject {
// then return it. Return NULL to have the instruction deleted.
virtual HValue* Canonicalize() { return this; }
- // Declare virtual type testers.
-#define DECLARE_DO(type) virtual bool Is##type() const { return false; }
- HYDROGEN_ALL_INSTRUCTION_LIST(DECLARE_DO)
-#undef DECLARE_DO
-
bool Equals(HValue* other);
virtual intptr_t Hashcode();
// Printing support.
virtual void PrintTo(StringStream* stream) = 0;
void PrintNameTo(StringStream* stream);
- static void PrintTypeTo(HType type, StringStream* stream);
+ void PrintTypeTo(StringStream* stream);
+ void PrintRangeTo(StringStream* stream);
+ void PrintChangesTo(StringStream* stream);
- virtual const char* Mnemonic() const = 0;
- virtual Opcode opcode() const = 0;
+ const char* Mnemonic() const;
// Updated the inferred type of this instruction and returns true if
// it has changed.
@@ -628,7 +690,10 @@ class HValue: public ZoneObject {
return ChangesFlagsMask() & ~(1 << kChangesOsrEntries);
}
- void InternalReplaceAtUse(HValue* use, HValue* other);
+ // Remove the matching use from the use list if present. Returns the
+ // removed list node or NULL.
+ HUseListNode* RemoveUse(HValue* value, int index);
+
void RegisterUse(int index, HValue* new_value);
HBasicBlock* block_;
@@ -638,8 +703,8 @@ class HValue: public ZoneObject {
int id_;
Representation representation_;
- ZoneList<HValue*> uses_;
HType type_;
+ HUseListNode* use_list_;
Range* range_;
int flags_;
@@ -670,13 +735,9 @@ class HInstruction: public HValue {
virtual void Verify();
#endif
- // Returns whether this is some kind of deoptimizing check
- // instruction.
- virtual bool IsCheckInstruction() const { return false; }
-
virtual bool IsCall() { return false; }
- DECLARE_INSTRUCTION(Instruction)
+ DECLARE_ABSTRACT_INSTRUCTION(Instruction)
protected:
HInstruction()
@@ -694,6 +755,8 @@ class HInstruction: public HValue {
SetBlock(block);
}
+ void PrintMnemonicTo(StringStream* stream);
+
HInstruction* next_;
HInstruction* previous_;
int position_;
@@ -702,98 +765,100 @@ class HInstruction: public HValue {
};
-class HControlInstruction: public HInstruction {
+template<int V>
+class HTemplateInstruction : public HInstruction {
public:
- HControlInstruction(HBasicBlock* first, HBasicBlock* second)
- : first_successor_(first), second_successor_(second) {
- }
-
- HBasicBlock* FirstSuccessor() const { return first_successor_; }
- HBasicBlock* SecondSuccessor() const { return second_successor_; }
-
- virtual void PrintDataTo(StringStream* stream);
+ int OperandCount() { return V; }
+ HValue* OperandAt(int i) { return inputs_[i]; }
- DECLARE_INSTRUCTION(ControlInstruction)
+ protected:
+ void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
private:
- HBasicBlock* first_successor_;
- HBasicBlock* second_successor_;
+ EmbeddedContainer<HValue*, V> inputs_;
};
-template<int NumElements>
-class HOperandContainer {
+class HControlInstruction: public HInstruction {
public:
- HOperandContainer() : elems_() { }
+ virtual HBasicBlock* SuccessorAt(int i) = 0;
+ virtual int SuccessorCount() = 0;
+ virtual void SetSuccessorAt(int i, HBasicBlock* block) = 0;
+
+ virtual void PrintDataTo(StringStream* stream);
- int length() { return NumElements; }
- HValue*& operator[](int i) {
- ASSERT(i < length());
- return elems_[i];
+ HBasicBlock* FirstSuccessor() {
+ return SuccessorCount() > 0 ? SuccessorAt(0) : NULL;
+ }
+ HBasicBlock* SecondSuccessor() {
+ return SuccessorCount() > 1 ? SuccessorAt(1) : NULL;
}
- private:
- HValue* elems_[NumElements];
+ DECLARE_ABSTRACT_INSTRUCTION(ControlInstruction)
};
-template<>
-class HOperandContainer<0> {
+class HSuccessorIterator BASE_EMBEDDED {
public:
- int length() { return 0; }
- HValue*& operator[](int i) {
- UNREACHABLE();
- static HValue* t = 0;
- return t;
- }
+ explicit HSuccessorIterator(HControlInstruction* instr)
+ : instr_(instr), current_(0) { }
+
+ bool Done() { return current_ >= instr_->SuccessorCount(); }
+ HBasicBlock* Current() { return instr_->SuccessorAt(current_); }
+ void Advance() { current_++; }
+
+ private:
+ HControlInstruction* instr_;
+ int current_;
};
-template<int V>
-class HTemplateInstruction : public HInstruction {
+template<int S, int V>
+class HTemplateControlInstruction: public HControlInstruction {
public:
+ int SuccessorCount() { return S; }
+ HBasicBlock* SuccessorAt(int i) { return successors_[i]; }
+ void SetSuccessorAt(int i, HBasicBlock* block) { successors_[i] = block; }
+
int OperandCount() { return V; }
HValue* OperandAt(int i) { return inputs_[i]; }
+
protected:
void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
private:
- HOperandContainer<V> inputs_;
+ EmbeddedContainer<HBasicBlock*, S> successors_;
+ EmbeddedContainer<HValue*, V> inputs_;
};
-template<int V>
-class HTemplateControlInstruction : public HControlInstruction {
+class HBlockEntry: public HTemplateInstruction<0> {
public:
- HTemplateControlInstruction<V>(HBasicBlock* first, HBasicBlock* second)
- : HControlInstruction(first, second) { }
- int OperandCount() { return V; }
- HValue* OperandAt(int i) { return inputs_[i]; }
-
- protected:
- void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
+ virtual Representation RequiredInputRepresentation(int index) const {
+ return Representation::None();
+ }
- private:
- HOperandContainer<V> inputs_;
+ DECLARE_CONCRETE_INSTRUCTION(BlockEntry)
};
-class HBlockEntry: public HTemplateInstruction<0> {
+// We insert soft-deoptimize when we hit code with unknown typefeedback,
+// so that we get a chance of re-optimizing with useful typefeedback.
+// HSoftDeoptimize does not end a basic block as opposed to HDeoptimize.
+class HSoftDeoptimize: public HTemplateInstruction<0> {
public:
virtual Representation RequiredInputRepresentation(int index) const {
return Representation::None();
}
- DECLARE_CONCRETE_INSTRUCTION(BlockEntry, "block_entry")
+ DECLARE_CONCRETE_INSTRUCTION(SoftDeoptimize)
};
class HDeoptimize: public HControlInstruction {
public:
- explicit HDeoptimize(int environment_length)
- : HControlInstruction(NULL, NULL),
- values_(environment_length) { }
+ explicit HDeoptimize(int environment_length) : values_(environment_length) { }
virtual Representation RequiredInputRepresentation(int index) const {
return Representation::None();
@@ -801,13 +866,28 @@ class HDeoptimize: public HControlInstruction {
virtual int OperandCount() { return values_.length(); }
virtual HValue* OperandAt(int index) { return values_[index]; }
+ virtual void PrintDataTo(StringStream* stream);
+
+ virtual int SuccessorCount() { return 0; }
+ virtual HBasicBlock* SuccessorAt(int i) {
+ UNREACHABLE();
+ return NULL;
+ }
+ virtual void SetSuccessorAt(int i, HBasicBlock* block) {
+ UNREACHABLE();
+ }
void AddEnvironmentValue(HValue* value) {
values_.Add(NULL);
SetOperandAt(values_.length() - 1, value);
}
- DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize")
+ DECLARE_CONCRETE_INSTRUCTION(Deoptimize)
+
+ enum UseEnvironment {
+ kNoUses,
+ kUseAll
+ };
protected:
virtual void InternalSetOperandAt(int index, HValue* value) {
@@ -819,57 +899,51 @@ class HDeoptimize: public HControlInstruction {
};
-class HGoto: public HTemplateControlInstruction<0> {
+class HGoto: public HTemplateControlInstruction<1, 0> {
public:
- explicit HGoto(HBasicBlock* target)
- : HTemplateControlInstruction<0>(target, NULL),
- include_stack_check_(false) { }
-
- void set_include_stack_check(bool include_stack_check) {
- include_stack_check_ = include_stack_check;
- }
- bool include_stack_check() const { return include_stack_check_; }
+ explicit HGoto(HBasicBlock* target) {
+ SetSuccessorAt(0, target);
+ }
virtual Representation RequiredInputRepresentation(int index) const {
return Representation::None();
}
- DECLARE_CONCRETE_INSTRUCTION(Goto, "goto")
-
- private:
- bool include_stack_check_;
+ DECLARE_CONCRETE_INSTRUCTION(Goto)
};
-class HUnaryControlInstruction: public HTemplateControlInstruction<1> {
+class HUnaryControlInstruction: public HTemplateControlInstruction<2, 1> {
public:
- explicit HUnaryControlInstruction(HValue* value,
- HBasicBlock* true_target,
- HBasicBlock* false_target)
- : HTemplateControlInstruction<1>(true_target, false_target) {
+ HUnaryControlInstruction(HValue* value,
+ HBasicBlock* true_target,
+ HBasicBlock* false_target) {
SetOperandAt(0, value);
+ SetSuccessorAt(0, true_target);
+ SetSuccessorAt(1, false_target);
}
virtual void PrintDataTo(StringStream* stream);
HValue* value() { return OperandAt(0); }
-
- DECLARE_INSTRUCTION(UnaryControlInstruction)
};
-class HTest: public HUnaryControlInstruction {
+class HBranch: public HUnaryControlInstruction {
public:
- HTest(HValue* value, HBasicBlock* true_target, HBasicBlock* false_target)
+ HBranch(HValue* value, HBasicBlock* true_target, HBasicBlock* false_target)
: HUnaryControlInstruction(value, true_target, false_target) {
ASSERT(true_target != NULL && false_target != NULL);
}
+ explicit HBranch(HValue* value)
+ : HUnaryControlInstruction(value, NULL, NULL) { }
+
virtual Representation RequiredInputRepresentation(int index) const {
return Representation::None();
}
- DECLARE_CONCRETE_INSTRUCTION(Test, "test")
+ DECLARE_CONCRETE_INSTRUCTION(Branch)
};
@@ -894,36 +968,38 @@ class HCompareMap: public HUnaryControlInstruction {
return Representation::Tagged();
}
- DECLARE_CONCRETE_INSTRUCTION(CompareMap, "compare_map")
+ DECLARE_CONCRETE_INSTRUCTION(CompareMap)
private:
Handle<Map> map_;
};
-class HReturn: public HUnaryControlInstruction {
+class HReturn: public HTemplateControlInstruction<0, 1> {
public:
- explicit HReturn(HValue* value)
- : HUnaryControlInstruction(value, NULL, NULL) {
+ explicit HReturn(HValue* value) {
+ SetOperandAt(0, value);
}
virtual Representation RequiredInputRepresentation(int index) const {
return Representation::Tagged();
}
- DECLARE_CONCRETE_INSTRUCTION(Return, "return")
+ virtual void PrintDataTo(StringStream* stream);
+
+ HValue* value() { return OperandAt(0); }
+
+ DECLARE_CONCRETE_INSTRUCTION(Return)
};
-class HAbnormalExit: public HTemplateControlInstruction<0> {
+class HAbnormalExit: public HTemplateControlInstruction<0, 0> {
public:
- HAbnormalExit() : HTemplateControlInstruction<0>(NULL, NULL) { }
-
virtual Representation RequiredInputRepresentation(int index) const {
return Representation::None();
}
- DECLARE_CONCRETE_INSTRUCTION(AbnormalExit, "abnormal_exit")
+ DECLARE_CONCRETE_INSTRUCTION(AbnormalExit)
};
@@ -933,16 +1009,24 @@ class HUnaryOperation: public HTemplateInstruction<1> {
SetOperandAt(0, value);
}
+ static HUnaryOperation* cast(HValue* value) {
+ return reinterpret_cast<HUnaryOperation*>(value);
+ }
+
+ virtual bool CanTruncateToInt32() const {
+ return CheckFlag(kTruncatingToInt32);
+ }
+
HValue* value() { return OperandAt(0); }
virtual void PrintDataTo(StringStream* stream);
-
- DECLARE_INSTRUCTION(UnaryOperation)
};
-class HThrow: public HUnaryOperation {
+class HThrow: public HTemplateInstruction<2> {
public:
- explicit HThrow(HValue* value) : HUnaryOperation(value) {
+ HThrow(HValue* context, HValue* value) {
+ SetOperandAt(0, context);
+ SetOperandAt(1, value);
SetAllSideEffects();
}
@@ -950,7 +1034,41 @@ class HThrow: public HUnaryOperation {
return Representation::Tagged();
}
- DECLARE_CONCRETE_INSTRUCTION(Throw, "throw")
+ HValue* context() { return OperandAt(0); }
+ HValue* value() { return OperandAt(1); }
+
+ DECLARE_CONCRETE_INSTRUCTION(Throw)
+};
+
+
+class HUseConst: public HUnaryOperation {
+ public:
+ explicit HUseConst(HValue* old_value) : HUnaryOperation(old_value) { }
+
+ virtual Representation RequiredInputRepresentation(int index) const {
+ return Representation::None();
+ }
+
+ DECLARE_CONCRETE_INSTRUCTION(UseConst)
+};
+
+
+class HForceRepresentation: public HTemplateInstruction<1> {
+ public:
+ HForceRepresentation(HValue* value, Representation required_representation) {
+ SetOperandAt(0, value);
+ set_representation(required_representation);
+ }
+
+ HValue* value() { return OperandAt(0); }
+
+ virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
+
+ virtual Representation RequiredInputRepresentation(int index) const {
+ return representation(); // Same as the output representation.
+ }
+
+ DECLARE_CONCRETE_INSTRUCTION(ForceRepresentation)
};
@@ -958,13 +1076,17 @@ class HChange: public HUnaryOperation {
public:
HChange(HValue* value,
Representation from,
- Representation to)
- : HUnaryOperation(value), from_(from), to_(to) {
+ Representation to,
+ bool is_truncating,
+ bool deoptimize_on_undefined)
+ : HUnaryOperation(value),
+ from_(from),
+ deoptimize_on_undefined_(deoptimize_on_undefined) {
ASSERT(!from.IsNone() && !to.IsNone());
ASSERT(!from.Equals(to));
set_representation(to);
SetFlag(kUseGVN);
-
+ if (is_truncating) SetFlag(kTruncatingToInt32);
if (from.IsInteger32() && to.IsTagged() && value->range() != NULL &&
value->range()->IsInSmiRange()) {
set_type(HType::Smi());
@@ -974,44 +1096,106 @@ class HChange: public HUnaryOperation {
virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
Representation from() const { return from_; }
- Representation to() const { return to_; }
+ Representation to() const { return representation(); }
+ bool deoptimize_on_undefined() const { return deoptimize_on_undefined_; }
virtual Representation RequiredInputRepresentation(int index) const {
return from_;
}
- bool CanTruncateToInt32() const {
- for (int i = 0; i < uses()->length(); ++i) {
- if (!uses()->at(i)->CheckFlag(HValue::kTruncatingToInt32)) return false;
- }
- return true;
- }
-
virtual void PrintDataTo(StringStream* stream);
- DECLARE_CONCRETE_INSTRUCTION(Change,
- CanTruncateToInt32() ? "truncate" : "change")
+ DECLARE_CONCRETE_INSTRUCTION(Change)
protected:
virtual bool DataEquals(HValue* other) {
if (!other->IsChange()) return false;
HChange* change = HChange::cast(other);
- return value() == change->value()
- && to().Equals(change->to())
- && CanTruncateToInt32() == change->CanTruncateToInt32();
+ return to().Equals(change->to())
+ && deoptimize_on_undefined() == change->deoptimize_on_undefined();
}
private:
Representation from_;
- Representation to_;
+ bool deoptimize_on_undefined_;
+};
+
+
+class HClampToUint8: public HUnaryOperation {
+ public:
+ explicit HClampToUint8(HValue* value)
+ : HUnaryOperation(value),
+ input_rep_(Representation::None()) {
+ SetFlag(kFlexibleRepresentation);
+ set_representation(Representation::Tagged());
+ SetFlag(kUseGVN);
+ }
+
+ virtual Representation RequiredInputRepresentation(int index) const {
+ return input_rep_;
+ }
+
+ virtual Representation InferredRepresentation() {
+ // TODO(danno): Inference on input types should happen separately from
+ // return representation.
+ Representation new_rep = value()->representation();
+ if (input_rep_.IsNone()) {
+ if (!new_rep.IsNone()) {
+ input_rep_ = new_rep;
+ return Representation::Integer32();
+ } else {
+ return Representation::None();
+ }
+ } else {
+ return Representation::Integer32();
+ }
+ }
+
+ DECLARE_CONCRETE_INSTRUCTION(ClampToUint8)
+
+ protected:
+ virtual bool DataEquals(HValue* other) { return true; }
+
+ private:
+ Representation input_rep_;
+};
+
+
+class HToInt32: public HUnaryOperation {
+ public:
+ explicit HToInt32(HValue* value)
+ : HUnaryOperation(value) {
+ set_representation(Representation::Integer32());
+ SetFlag(kUseGVN);
+ }
+
+ virtual Representation RequiredInputRepresentation(int index) const {
+ return Representation::None();
+ }
+
+ virtual bool CanTruncateToInt32() const {
+ return true;
+ }
+
+ virtual HValue* Canonicalize() {
+ if (value()->representation().IsInteger32()) {
+ return value();
+ } else {
+ return this;
+ }
+ }
+
+ DECLARE_CONCRETE_INSTRUCTION(ToInt32)
+
+ protected:
+ virtual bool DataEquals(HValue* other) { return true; }
};
class HSimulate: public HInstruction {
public:
- HSimulate(int ast_id, int pop_count, int environment_length)
+ HSimulate(int ast_id, int pop_count)
: ast_id_(ast_id),
pop_count_(pop_count),
- environment_length_(environment_length),
values_(2),
assigned_indexes_(2) {}
virtual ~HSimulate() {}
@@ -1025,7 +1209,6 @@ class HSimulate: public HInstruction {
ast_id_ = id;
}
- int environment_length() const { return environment_length_; }
int pop_count() const { return pop_count_; }
const ZoneList<HValue*>* values() const { return &values_; }
int GetAssignedIndexAt(int index) const {
@@ -1048,7 +1231,7 @@ class HSimulate: public HInstruction {
return Representation::None();
}
- DECLARE_CONCRETE_INSTRUCTION(Simulate, "simulate")
+ DECLARE_CONCRETE_INSTRUCTION(Simulate)
#ifdef DEBUG
virtual void Verify();
@@ -1071,44 +1254,72 @@ class HSimulate: public HInstruction {
}
int ast_id_;
int pop_count_;
- int environment_length_;
ZoneList<HValue*> values_;
ZoneList<int> assigned_indexes_;
};
-class HStackCheck: public HTemplateInstruction<0> {
+class HStackCheck: public HTemplateInstruction<1> {
public:
- HStackCheck() { }
+ enum Type {
+ kFunctionEntry,
+ kBackwardsBranch
+ };
+
+ HStackCheck(HValue* context, Type type) : type_(type) {
+ SetOperandAt(0, context);
+ }
+
+ HValue* context() { return OperandAt(0); }
virtual Representation RequiredInputRepresentation(int index) const {
- return Representation::None();
+ return Representation::Tagged();
+ }
+
+ void Eliminate() {
+ // The stack check eliminator might try to eliminate the same stack
+ // check instruction multiple times.
+ if (IsLinked()) {
+ DeleteFromGraph();
+ }
}
- DECLARE_CONCRETE_INSTRUCTION(StackCheck, "stack_check")
+ bool is_function_entry() { return type_ == kFunctionEntry; }
+ bool is_backwards_branch() { return type_ == kBackwardsBranch; }
+
+ DECLARE_CONCRETE_INSTRUCTION(StackCheck)
+
+ private:
+ Type type_;
};
class HEnterInlined: public HTemplateInstruction<0> {
public:
- HEnterInlined(Handle<JSFunction> closure, FunctionLiteral* function)
- : closure_(closure), function_(function) {
+ HEnterInlined(Handle<JSFunction> closure,
+ FunctionLiteral* function,
+ CallKind call_kind)
+ : closure_(closure),
+ function_(function),
+ call_kind_(call_kind) {
}
virtual void PrintDataTo(StringStream* stream);
Handle<JSFunction> closure() const { return closure_; }
FunctionLiteral* function() const { return function_; }
+ CallKind call_kind() const { return call_kind_; }
virtual Representation RequiredInputRepresentation(int index) const {
return Representation::None();
}
- DECLARE_CONCRETE_INSTRUCTION(EnterInlined, "enter_inlined")
+ DECLARE_CONCRETE_INSTRUCTION(EnterInlined)
private:
Handle<JSFunction> closure_;
FunctionLiteral* function_;
+ CallKind call_kind_;
};
@@ -1120,7 +1331,7 @@ class HLeaveInlined: public HTemplateInstruction<0> {
return Representation::None();
}
- DECLARE_CONCRETE_INSTRUCTION(LeaveInlined, "leave_inlined")
+ DECLARE_CONCRETE_INSTRUCTION(LeaveInlined)
};
@@ -1136,7 +1347,25 @@ class HPushArgument: public HUnaryOperation {
HValue* argument() { return OperandAt(0); }
- DECLARE_CONCRETE_INSTRUCTION(PushArgument, "push_argument")
+ DECLARE_CONCRETE_INSTRUCTION(PushArgument)
+};
+
+
+class HThisFunction: public HTemplateInstruction<0> {
+ public:
+ HThisFunction() {
+ set_representation(Representation::Tagged());
+ SetFlag(kUseGVN);
+ }
+
+ virtual Representation RequiredInputRepresentation(int index) const {
+ return Representation::None();
+ }
+
+ DECLARE_CONCRETE_INSTRUCTION(ThisFunction)
+
+ protected:
+ virtual bool DataEquals(HValue* other) { return true; }
};
@@ -1151,7 +1380,7 @@ class HContext: public HTemplateInstruction<0> {
return Representation::None();
}
- DECLARE_CONCRETE_INSTRUCTION(Context, "context");
+ DECLARE_CONCRETE_INSTRUCTION(Context)
protected:
virtual bool DataEquals(HValue* other) { return true; }
@@ -1165,7 +1394,7 @@ class HOuterContext: public HUnaryOperation {
SetFlag(kUseGVN);
}
- DECLARE_CONCRETE_INSTRUCTION(OuterContext, "outer_context");
+ DECLARE_CONCRETE_INSTRUCTION(OuterContext);
virtual Representation RequiredInputRepresentation(int index) const {
return Representation::Tagged();
@@ -1183,7 +1412,7 @@ class HGlobalObject: public HUnaryOperation {
SetFlag(kUseGVN);
}
- DECLARE_CONCRETE_INSTRUCTION(GlobalObject, "global_object")
+ DECLARE_CONCRETE_INSTRUCTION(GlobalObject)
virtual Representation RequiredInputRepresentation(int index) const {
return Representation::Tagged();
@@ -1202,7 +1431,7 @@ class HGlobalReceiver: public HUnaryOperation {
SetFlag(kUseGVN);
}
- DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver, "global_receiver")
+ DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver)
virtual Representation RequiredInputRepresentation(int index) const {
return Representation::Tagged();
@@ -1247,8 +1476,6 @@ class HUnaryCall: public HCall<1> {
virtual void PrintDataTo(StringStream* stream);
HValue* value() { return OperandAt(0); }
-
- DECLARE_INSTRUCTION(UnaryCall)
};
@@ -1268,8 +1495,23 @@ class HBinaryCall: public HCall<2> {
HValue* first() { return OperandAt(0); }
HValue* second() { return OperandAt(1); }
+};
+
- DECLARE_INSTRUCTION(BinaryCall)
+class HInvokeFunction: public HBinaryCall {
+ public:
+ HInvokeFunction(HValue* context, HValue* function, int argument_count)
+ : HBinaryCall(context, function, argument_count) {
+ }
+
+ virtual Representation RequiredInputRepresentation(int index) const {
+ return Representation::Tagged();
+ }
+
+ HValue* context() { return first(); }
+ HValue* function() { return second(); }
+
+ DECLARE_CONCRETE_INSTRUCTION(InvokeFunction)
};
@@ -1281,7 +1523,8 @@ class HCallConstantFunction: public HCall<0> {
Handle<JSFunction> function() const { return function_; }
bool IsApplyFunction() const {
- return function_->code() == Builtins::builtin(Builtins::FunctionApply);
+ return function_->code() ==
+ Isolate::Current()->builtins()->builtin(Builtins::kFunctionApply);
}
virtual void PrintDataTo(StringStream* stream);
@@ -1290,7 +1533,7 @@ class HCallConstantFunction: public HCall<0> {
return Representation::None();
}
- DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction, "call_constant_function")
+ DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction)
private:
Handle<JSFunction> function_;
@@ -1310,7 +1553,7 @@ class HCallKeyed: public HBinaryCall {
HValue* context() { return first(); }
HValue* key() { return second(); }
- DECLARE_CONCRETE_INSTRUCTION(CallKeyed, "call_keyed")
+ DECLARE_CONCRETE_INSTRUCTION(CallKeyed)
};
@@ -1325,7 +1568,7 @@ class HCallNamed: public HUnaryCall {
HValue* context() { return value(); }
Handle<String> name() const { return name_; }
- DECLARE_CONCRETE_INSTRUCTION(CallNamed, "call_named")
+ DECLARE_CONCRETE_INSTRUCTION(CallNamed)
virtual Representation RequiredInputRepresentation(int index) const {
return Representation::Tagged();
@@ -1348,7 +1591,7 @@ class HCallFunction: public HUnaryCall {
return Representation::Tagged();
}
- DECLARE_CONCRETE_INSTRUCTION(CallFunction, "call_function")
+ DECLARE_CONCRETE_INSTRUCTION(CallFunction)
};
@@ -1367,7 +1610,7 @@ class HCallGlobal: public HUnaryCall {
return Representation::Tagged();
}
- DECLARE_CONCRETE_INSTRUCTION(CallGlobal, "call_global")
+ DECLARE_CONCRETE_INSTRUCTION(CallGlobal)
private:
Handle<String> name_;
@@ -1387,7 +1630,7 @@ class HCallKnownGlobal: public HCall<0> {
return Representation::None();
}
- DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal, "call_known_global")
+ DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal)
private:
Handle<JSFunction> target_;
@@ -1407,29 +1650,34 @@ class HCallNew: public HBinaryCall {
HValue* context() { return first(); }
HValue* constructor() { return second(); }
- DECLARE_CONCRETE_INSTRUCTION(CallNew, "call_new")
+ DECLARE_CONCRETE_INSTRUCTION(CallNew)
};
-class HCallRuntime: public HCall<0> {
+class HCallRuntime: public HCall<1> {
public:
- HCallRuntime(Handle<String> name,
- Runtime::Function* c_function,
+ HCallRuntime(HValue* context,
+ Handle<String> name,
+ const Runtime::Function* c_function,
int argument_count)
- : HCall<0>(argument_count), c_function_(c_function), name_(name) { }
+ : HCall<1>(argument_count), c_function_(c_function), name_(name) {
+ SetOperandAt(0, context);
+ }
+
virtual void PrintDataTo(StringStream* stream);
- Runtime::Function* function() const { return c_function_; }
+ HValue* context() { return OperandAt(0); }
+ const Runtime::Function* function() const { return c_function_; }
Handle<String> name() const { return name_; }
virtual Representation RequiredInputRepresentation(int index) const {
- return Representation::None();
+ return Representation::Tagged();
}
- DECLARE_CONCRETE_INSTRUCTION(CallRuntime, "call_runtime")
+ DECLARE_CONCRETE_INSTRUCTION(CallRuntime)
private:
- Runtime::Function* c_function_;
+ const Runtime::Function* c_function_;
Handle<String> name_;
};
@@ -1450,7 +1698,7 @@ class HJSArrayLength: public HUnaryOperation {
return Representation::Tagged();
}
- DECLARE_CONCRETE_INSTRUCTION(JSArrayLength, "js_array_length")
+ DECLARE_CONCRETE_INSTRUCTION(JSArrayLength)
protected:
virtual bool DataEquals(HValue* other) { return true; }
@@ -1469,16 +1717,16 @@ class HFixedArrayLength: public HUnaryOperation {
return Representation::Tagged();
}
- DECLARE_CONCRETE_INSTRUCTION(FixedArrayLength, "fixed_array_length")
+ DECLARE_CONCRETE_INSTRUCTION(FixedArrayLength)
protected:
virtual bool DataEquals(HValue* other) { return true; }
};
-class HPixelArrayLength: public HUnaryOperation {
+class HExternalArrayLength: public HUnaryOperation {
public:
- explicit HPixelArrayLength(HValue* value) : HUnaryOperation(value) {
+ explicit HExternalArrayLength(HValue* value) : HUnaryOperation(value) {
set_representation(Representation::Integer32());
// The result of this instruction is idempotent as long as its inputs don't
// change. The length of a pixel array cannot change once set, so it's not
@@ -1490,7 +1738,26 @@ class HPixelArrayLength: public HUnaryOperation {
return Representation::Tagged();
}
- DECLARE_CONCRETE_INSTRUCTION(PixelArrayLength, "pixel_array_length")
+ DECLARE_CONCRETE_INSTRUCTION(ExternalArrayLength)
+
+ protected:
+ virtual bool DataEquals(HValue* other) { return true; }
+};
+
+
+class HElementsKind: public HUnaryOperation {
+ public:
+ explicit HElementsKind(HValue* value) : HUnaryOperation(value) {
+ set_representation(Representation::Integer32());
+ SetFlag(kUseGVN);
+ SetFlag(kDependsOnMaps);
+ }
+
+ virtual Representation RequiredInputRepresentation(int index) const {
+ return Representation::Tagged();
+ }
+
+ DECLARE_CONCRETE_INSTRUCTION(ElementsKind)
protected:
virtual bool DataEquals(HValue* other) { return true; }
@@ -1510,17 +1777,19 @@ class HBitNot: public HUnaryOperation {
}
virtual HType CalculateInferredType();
- DECLARE_CONCRETE_INSTRUCTION(BitNot, "bit_not")
+ DECLARE_CONCRETE_INSTRUCTION(BitNot)
protected:
virtual bool DataEquals(HValue* other) { return true; }
};
-class HUnaryMathOperation: public HUnaryOperation {
+class HUnaryMathOperation: public HTemplateInstruction<2> {
public:
- HUnaryMathOperation(HValue* value, BuiltinFunctionId op)
- : HUnaryOperation(value), op_(op) {
+ HUnaryMathOperation(HValue* context, HValue* value, BuiltinFunctionId op)
+ : op_(op) {
+ SetOperandAt(0, context);
+ SetOperandAt(1, value);
switch (op) {
case kMathFloor:
case kMathRound:
@@ -1544,6 +1813,9 @@ class HUnaryMathOperation: public HUnaryOperation {
SetFlag(kUseGVN);
}
+ HValue* context() { return OperandAt(0); }
+ HValue* value() { return OperandAt(1); }
+
virtual void PrintDataTo(StringStream* stream);
virtual HType CalculateInferredType();
@@ -1551,21 +1823,25 @@ class HUnaryMathOperation: public HUnaryOperation {
virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
virtual Representation RequiredInputRepresentation(int index) const {
- switch (op_) {
- case kMathFloor:
- case kMathRound:
- case kMathCeil:
- case kMathSqrt:
- case kMathPowHalf:
- case kMathLog:
- case kMathSin:
- case kMathCos:
- return Representation::Double();
- case kMathAbs:
- return representation();
- default:
- UNREACHABLE();
- return Representation::None();
+ if (index == 0) {
+ return Representation::Tagged();
+ } else {
+ switch (op_) {
+ case kMathFloor:
+ case kMathRound:
+ case kMathCeil:
+ case kMathSqrt:
+ case kMathPowHalf:
+ case kMathLog:
+ case kMathSin:
+ case kMathCos:
+ return Representation::Double();
+ case kMathAbs:
+ return representation();
+ default:
+ UNREACHABLE();
+ return Representation::None();
+ }
}
}
@@ -1582,7 +1858,7 @@ class HUnaryMathOperation: public HUnaryOperation {
BuiltinFunctionId op() const { return op_; }
const char* OpName() const;
- DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation, "unary_math_operation")
+ DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation)
protected:
virtual bool DataEquals(HValue* other) {
@@ -1607,20 +1883,20 @@ class HLoadElements: public HUnaryOperation {
return Representation::Tagged();
}
- DECLARE_CONCRETE_INSTRUCTION(LoadElements, "load-elements")
+ DECLARE_CONCRETE_INSTRUCTION(LoadElements)
protected:
virtual bool DataEquals(HValue* other) { return true; }
};
-class HLoadPixelArrayExternalPointer: public HUnaryOperation {
+class HLoadExternalArrayPointer: public HUnaryOperation {
public:
- explicit HLoadPixelArrayExternalPointer(HValue* value)
+ explicit HLoadExternalArrayPointer(HValue* value)
: HUnaryOperation(value) {
set_representation(Representation::External());
// The result of this instruction is idempotent as long as its inputs don't
- // change. The external array of a pixel array elements object cannot
+ // change. The external array of a specialized array elements object cannot
// change once set, so it's no necessary to introduce any additional
// dependencies on top of the inputs.
SetFlag(kUseGVN);
@@ -1630,8 +1906,7 @@ class HLoadPixelArrayExternalPointer: public HUnaryOperation {
return Representation::Tagged();
}
- DECLARE_CONCRETE_INSTRUCTION(LoadPixelArrayExternalPointer,
- "load-pixel-array-external-pointer")
+ DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer)
protected:
virtual bool DataEquals(HValue* other) { return true; }
@@ -1647,8 +1922,6 @@ class HCheckMap: public HUnaryOperation {
SetFlag(kDependsOnMaps);
}
- virtual bool IsCheckInstruction() const { return true; }
-
virtual Representation RequiredInputRepresentation(int index) const {
return Representation::Tagged();
}
@@ -1661,7 +1934,7 @@ class HCheckMap: public HUnaryOperation {
Handle<Map> map() const { return map_; }
- DECLARE_CONCRETE_INSTRUCTION(CheckMap, "check_map")
+ DECLARE_CONCRETE_INSTRUCTION(CheckMap)
protected:
virtual bool DataEquals(HValue* other) {
@@ -1682,8 +1955,6 @@ class HCheckFunction: public HUnaryOperation {
SetFlag(kUseGVN);
}
- virtual bool IsCheckInstruction() const { return true; }
-
virtual Representation RequiredInputRepresentation(int index) const {
return Representation::Tagged();
}
@@ -1696,7 +1967,7 @@ class HCheckFunction: public HUnaryOperation {
Handle<JSFunction> target() const { return target_; }
- DECLARE_CONCRETE_INSTRUCTION(CheckFunction, "check_function")
+ DECLARE_CONCRETE_INSTRUCTION(CheckFunction)
protected:
virtual bool DataEquals(HValue* other) {
@@ -1711,22 +1982,18 @@ class HCheckFunction: public HUnaryOperation {
class HCheckInstanceType: public HUnaryOperation {
public:
- // Check that the instance type is in the range [first, last] where
- // both first and last are included.
- HCheckInstanceType(HValue* value, InstanceType first, InstanceType last)
- : HUnaryOperation(value), first_(first), last_(last) {
- ASSERT(first <= last);
- set_representation(Representation::Tagged());
- SetFlag(kUseGVN);
- if ((FIRST_STRING_TYPE < first && last <= LAST_STRING_TYPE) ||
- (FIRST_STRING_TYPE <= first && last < LAST_STRING_TYPE)) {
- // A particular string instance type can change because of GC or
- // externalization, but the value still remains a string.
- SetFlag(kDependsOnMaps);
- }
+ static HCheckInstanceType* NewIsSpecObject(HValue* value) {
+ return new HCheckInstanceType(value, IS_SPEC_OBJECT);
+ }
+ static HCheckInstanceType* NewIsJSArray(HValue* value) {
+ return new HCheckInstanceType(value, IS_JS_ARRAY);
+ }
+ static HCheckInstanceType* NewIsString(HValue* value) {
+ return new HCheckInstanceType(value, IS_STRING);
+ }
+ static HCheckInstanceType* NewIsSymbol(HValue* value) {
+ return new HCheckInstanceType(value, IS_SYMBOL);
}
-
- virtual bool IsCheckInstruction() const { return true; }
virtual Representation RequiredInputRepresentation(int index) const {
return Representation::Tagged();
@@ -1736,12 +2003,20 @@ class HCheckInstanceType: public HUnaryOperation {
virtual void Verify();
#endif
- static HCheckInstanceType* NewIsJSObjectOrJSFunction(HValue* value);
+ virtual HValue* Canonicalize() {
+ if (!value()->type().IsUninitialized() &&
+ value()->type().IsString() &&
+ check_ == IS_STRING) {
+ return NULL;
+ }
+ return this;
+ }
- InstanceType first() const { return first_; }
- InstanceType last() const { return last_; }
+ bool is_interval_check() const { return check_ <= LAST_INTERVAL_CHECK; }
+ void GetCheckInterval(InstanceType* first, InstanceType* last);
+ void GetCheckMaskAndTag(uint8_t* mask, uint8_t* tag);
- DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType, "check_instance_type")
+ DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType)
protected:
// TODO(ager): It could be nice to allow the ommision of instance
@@ -1749,12 +2024,25 @@ class HCheckInstanceType: public HUnaryOperation {
// with a larger range.
virtual bool DataEquals(HValue* other) {
HCheckInstanceType* b = HCheckInstanceType::cast(other);
- return (first_ == b->first()) && (last_ == b->last());
+ return check_ == b->check_;
}
private:
- InstanceType first_;
- InstanceType last_;
+ enum Check {
+ IS_SPEC_OBJECT,
+ IS_JS_ARRAY,
+ IS_STRING,
+ IS_SYMBOL,
+ LAST_INTERVAL_CHECK = IS_JS_ARRAY
+ };
+
+ HCheckInstanceType(HValue* value, Check check)
+ : HUnaryOperation(value), check_(check) {
+ set_representation(Representation::Tagged());
+ SetFlag(kUseGVN);
+ }
+
+ const Check check_;
};
@@ -1765,8 +2053,6 @@ class HCheckNonSmi: public HUnaryOperation {
SetFlag(kUseGVN);
}
- virtual bool IsCheckInstruction() const { return true; }
-
virtual Representation RequiredInputRepresentation(int index) const {
return Representation::Tagged();
}
@@ -1777,7 +2063,19 @@ class HCheckNonSmi: public HUnaryOperation {
virtual void Verify();
#endif
- DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi, "check_non_smi")
+ virtual HValue* Canonicalize() {
+ HType value_type = value()->type();
+ if (!value_type.IsUninitialized() &&
+ (value_type.IsHeapNumber() ||
+ value_type.IsString() ||
+ value_type.IsBoolean() ||
+ value_type.IsNonPrimitive())) {
+ return NULL;
+ }
+ return this;
+ }
+
+ DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi)
protected:
virtual bool DataEquals(HValue* other) { return true; }
@@ -1792,8 +2090,6 @@ class HCheckPrototypeMaps: public HTemplateInstruction<0> {
SetFlag(kDependsOnMaps);
}
- virtual bool IsCheckInstruction() const { return true; }
-
#ifdef DEBUG
virtual void Verify();
#endif
@@ -1801,14 +2097,14 @@ class HCheckPrototypeMaps: public HTemplateInstruction<0> {
Handle<JSObject> prototype() const { return prototype_; }
Handle<JSObject> holder() const { return holder_; }
- DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps, "check_prototype_maps")
+ DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps)
virtual Representation RequiredInputRepresentation(int index) const {
return Representation::None();
}
virtual intptr_t Hashcode() {
- ASSERT(!Heap::IsAllocationAllowed());
+ ASSERT(!HEAP->IsAllocationAllowed());
intptr_t hash = reinterpret_cast<intptr_t>(*prototype());
hash = 17 * hash + reinterpret_cast<intptr_t>(*holder());
return hash;
@@ -1834,8 +2130,6 @@ class HCheckSmi: public HUnaryOperation {
SetFlag(kUseGVN);
}
- virtual bool IsCheckInstruction() const { return true; }
-
virtual Representation RequiredInputRepresentation(int index) const {
return Representation::Tagged();
}
@@ -1845,7 +2139,7 @@ class HCheckSmi: public HUnaryOperation {
virtual void Verify();
#endif
- DECLARE_CONCRETE_INSTRUCTION(CheckSmi, "check_smi")
+ DECLARE_CONCRETE_INSTRUCTION(CheckSmi)
protected:
virtual bool DataEquals(HValue* other) { return true; }
@@ -1857,7 +2151,9 @@ class HPhi: public HValue {
explicit HPhi(int merged_index)
: inputs_(2),
merged_index_(merged_index),
- phi_id_(-1) {
+ phi_id_(-1),
+ is_live_(false),
+ is_convertible_to_integer_(true) {
for (int i = 0; i < Representation::kNumRepresentations; i++) {
non_phi_uses_[i] = 0;
indirect_uses_[i] = 0;
@@ -1891,21 +2187,18 @@ class HPhi: public HValue {
virtual HValue* OperandAt(int index) { return inputs_[index]; }
HValue* GetRedundantReplacement();
void AddInput(HValue* value);
+ bool HasRealUses();
bool IsReceiver() { return merged_index_ == 0; }
int merged_index() const { return merged_index_; }
- virtual const char* Mnemonic() const { return "phi"; }
-
virtual void PrintTo(StringStream* stream);
#ifdef DEBUG
virtual void Verify();
#endif
- DECLARE_INSTRUCTION(Phi)
-
void InitRealUses(int id);
void AddNonPhiUsesFrom(HPhi* other);
void AddIndirectUsesTo(int* use_count);
@@ -1929,6 +2222,22 @@ class HPhi: public HValue {
return indirect_uses_[Representation::kDouble];
}
int phi_id() { return phi_id_; }
+ bool is_live() { return is_live_; }
+ void set_is_live(bool b) { is_live_ = b; }
+
+ static HPhi* cast(HValue* value) {
+ ASSERT(value->IsPhi());
+ return reinterpret_cast<HPhi*>(value);
+ }
+ virtual Opcode opcode() const { return HValue::kPhi; }
+
+ virtual bool IsConvertibleToInteger() const {
+ return is_convertible_to_integer_;
+ }
+
+ void set_is_convertible_to_integer(bool b) {
+ is_convertible_to_integer_ = b;
+ }
protected:
virtual void DeleteFromGraph();
@@ -1943,6 +2252,8 @@ class HPhi: public HValue {
int non_phi_uses_[Representation::kNumRepresentations];
int indirect_uses_[Representation::kNumRepresentations];
int phi_id_;
+ bool is_live_;
+ bool is_convertible_to_integer_;
};
@@ -1957,7 +2268,7 @@ class HArgumentsObject: public HTemplateInstruction<0> {
return Representation::None();
}
- DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject, "arguments-object")
+ DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject)
};
@@ -1967,13 +2278,21 @@ class HConstant: public HTemplateInstruction<0> {
Handle<Object> handle() const { return handle_; }
- bool InOldSpace() const { return !Heap::InNewSpace(*handle_); }
+ bool InOldSpace() const { return !HEAP->InNewSpace(*handle_); }
virtual Representation RequiredInputRepresentation(int index) const {
return Representation::None();
}
- virtual bool EmitAtUses() const { return !representation().IsDouble(); }
+ 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;
+ }
+
+ virtual bool EmitAtUses() { return !representation().IsDouble(); }
virtual void PrintDataTo(StringStream* stream);
virtual HType CalculateInferredType();
bool IsInteger() const { return handle_->IsSmi(); }
@@ -1991,8 +2310,10 @@ class HConstant: public HTemplateInstruction<0> {
}
bool HasStringValue() const { return handle_->IsString(); }
+ bool ToBoolean() const;
+
virtual intptr_t Hashcode() {
- ASSERT(!Heap::allow_allocation(false));
+ ASSERT(!HEAP->allow_allocation(false));
return reinterpret_cast<intptr_t>(*handle());
}
@@ -2000,7 +2321,7 @@ class HConstant: public HTemplateInstruction<0> {
virtual void Verify() { }
#endif
- DECLARE_CONCRETE_INSTRUCTION(Constant, "constant")
+ DECLARE_CONCRETE_INSTRUCTION(Constant)
protected:
virtual Range* InferRange();
@@ -2012,28 +2333,29 @@ class HConstant: public HTemplateInstruction<0> {
private:
Handle<Object> handle_;
- HType constant_type_;
// 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.
- bool has_int32_value_;
+ bool has_int32_value_ : 1;
+ bool has_double_value_ : 1;
int32_t int32_value_;
- bool has_double_value_;
double double_value_;
};
-class HBinaryOperation: public HTemplateInstruction<2> {
+class HBinaryOperation: public HTemplateInstruction<3> {
public:
- HBinaryOperation(HValue* left, HValue* right) {
+ HBinaryOperation(HValue* context, HValue* left, HValue* right) {
ASSERT(left != NULL && right != NULL);
- SetOperandAt(0, left);
- SetOperandAt(1, right);
+ SetOperandAt(0, context);
+ SetOperandAt(1, left);
+ SetOperandAt(2, right);
}
- HValue* left() { return OperandAt(0); }
- HValue* right() { return OperandAt(1); }
+ HValue* context() { return OperandAt(0); }
+ HValue* left() { return OperandAt(1); }
+ HValue* right() { return OperandAt(2); }
// TODO(kasperl): Move these helpers to the IA-32 Lithium
// instruction sequence builder.
@@ -2049,8 +2371,6 @@ class HBinaryOperation: public HTemplateInstruction<2> {
virtual bool IsCommutative() const { return false; }
virtual void PrintDataTo(StringStream* stream);
-
- DECLARE_INSTRUCTION(BinaryOperation)
};
@@ -2080,7 +2400,7 @@ class HApplyArguments: public HTemplateInstruction<4> {
HValue* length() { return OperandAt(2); }
HValue* elements() { return OperandAt(3); }
- DECLARE_CONCRETE_INSTRUCTION(ApplyArguments, "apply_arguments")
+ DECLARE_CONCRETE_INSTRUCTION(ApplyArguments)
};
@@ -2093,7 +2413,7 @@ class HArgumentsElements: public HTemplateInstruction<0> {
SetFlag(kUseGVN);
}
- DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements, "arguments_elements")
+ DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements)
virtual Representation RequiredInputRepresentation(int index) const {
return Representation::None();
@@ -2115,7 +2435,7 @@ class HArgumentsLength: public HUnaryOperation {
return Representation::Tagged();
}
- DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength, "arguments_length")
+ DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength)
protected:
virtual bool DataEquals(HValue* other) { return true; }
@@ -2145,21 +2465,21 @@ class HAccessArgumentsAt: public HTemplateInstruction<3> {
HValue* length() { return OperandAt(1); }
HValue* index() { return OperandAt(2); }
- DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt, "access_arguments_at")
+ DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt)
virtual bool DataEquals(HValue* other) { return true; }
};
-class HBoundsCheck: public HBinaryOperation {
+class HBoundsCheck: public HTemplateInstruction<2> {
public:
- HBoundsCheck(HValue* index, HValue* length)
- : HBinaryOperation(index, length) {
+ HBoundsCheck(HValue* index, HValue* length) {
+ SetOperandAt(0, index);
+ SetOperandAt(1, length);
+ set_representation(Representation::Integer32());
SetFlag(kUseGVN);
}
- virtual bool IsCheckInstruction() const { return true; }
-
virtual Representation RequiredInputRepresentation(int index) const {
return Representation::Integer32();
}
@@ -2168,10 +2488,10 @@ class HBoundsCheck: public HBinaryOperation {
virtual void Verify();
#endif
- HValue* index() { return left(); }
- HValue* length() { return right(); }
+ HValue* index() { return OperandAt(0); }
+ HValue* length() { return OperandAt(1); }
- DECLARE_CONCRETE_INSTRUCTION(BoundsCheck, "bounds_check")
+ DECLARE_CONCRETE_INSTRUCTION(BoundsCheck)
protected:
virtual bool DataEquals(HValue* other) { return true; }
@@ -2180,15 +2500,17 @@ class HBoundsCheck: public HBinaryOperation {
class HBitwiseBinaryOperation: public HBinaryOperation {
public:
- HBitwiseBinaryOperation(HValue* left, HValue* right)
- : HBinaryOperation(left, right) {
+ HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right)
+ : HBinaryOperation(context, left, right) {
set_representation(Representation::Tagged());
SetFlag(kFlexibleRepresentation);
SetAllSideEffects();
}
virtual Representation RequiredInputRepresentation(int index) const {
- return representation();
+ return index == 0
+ ? Representation::Tagged()
+ : representation();
}
virtual void RepresentationChanged(Representation to) {
@@ -2202,14 +2524,14 @@ class HBitwiseBinaryOperation: public HBinaryOperation {
virtual HType CalculateInferredType();
- DECLARE_INSTRUCTION(BitwiseBinaryOperation)
+ DECLARE_ABSTRACT_INSTRUCTION(BitwiseBinaryOperation)
};
class HArithmeticBinaryOperation: public HBinaryOperation {
public:
- HArithmeticBinaryOperation(HValue* left, HValue* right)
- : HBinaryOperation(left, right) {
+ HArithmeticBinaryOperation(HValue* context, HValue* left, HValue* right)
+ : HBinaryOperation(context, left, right) {
set_representation(Representation::Tagged());
SetFlag(kFlexibleRepresentation);
SetAllSideEffects();
@@ -2224,56 +2546,76 @@ class HArithmeticBinaryOperation: public HBinaryOperation {
virtual HType CalculateInferredType();
virtual Representation RequiredInputRepresentation(int index) const {
- return representation();
+ return index == 0
+ ? Representation::Tagged()
+ : representation();
}
+
virtual Representation InferredRepresentation() {
if (left()->representation().Equals(right()->representation())) {
return left()->representation();
}
return HValue::InferredRepresentation();
}
-
- DECLARE_INSTRUCTION(ArithmeticBinaryOperation)
};
-class HCompare: public HBinaryOperation {
+class HCompareGeneric: public HBinaryOperation {
public:
- HCompare(HValue* left, HValue* right, Token::Value token)
- : HBinaryOperation(left, right), token_(token) {
+ HCompareGeneric(HValue* context,
+ HValue* left,
+ HValue* right,
+ Token::Value token)
+ : HBinaryOperation(context, left, right), token_(token) {
ASSERT(Token::IsCompareOp(token));
set_representation(Representation::Tagged());
SetAllSideEffects();
}
- void SetInputRepresentation(Representation r);
-
- virtual bool EmitAtUses() const {
- return !HasSideEffects() && (uses()->length() <= 1);
- }
-
virtual Representation RequiredInputRepresentation(int index) const {
- return input_representation_;
+ return Representation::Tagged();
}
+
Representation GetInputRepresentation() const {
- return input_representation_;
+ return Representation::Tagged();
}
+
Token::Value token() const { return token_; }
virtual void PrintDataTo(StringStream* stream);
virtual HType CalculateInferredType();
- virtual intptr_t Hashcode() {
- return HValue::Hashcode() * 7 + token_;
+ DECLARE_CONCRETE_INSTRUCTION(CompareGeneric)
+
+ private:
+ Token::Value token_;
+};
+
+
+class HCompareIDAndBranch: public HTemplateControlInstruction<2, 2> {
+ public:
+ HCompareIDAndBranch(HValue* left, HValue* right, Token::Value token)
+ : token_(token) {
+ ASSERT(Token::IsCompareOp(token));
+ SetOperandAt(0, left);
+ SetOperandAt(1, right);
}
- DECLARE_CONCRETE_INSTRUCTION(Compare, "compare")
+ HValue* left() { return OperandAt(0); }
+ HValue* right() { return OperandAt(1); }
+ Token::Value token() const { return token_; }
- protected:
- virtual bool DataEquals(HValue* other) {
- HCompare* comp = HCompare::cast(other);
- return token_ == comp->token();
+ void SetInputRepresentation(Representation r);
+ Representation GetInputRepresentation() const {
+ return input_representation_;
+ }
+
+ virtual Representation RequiredInputRepresentation(int index) const {
+ return input_representation_;
}
+ virtual void PrintDataTo(StringStream* stream);
+
+ DECLARE_CONCRETE_INSTRUCTION(CompareIDAndBranch)
private:
Representation input_representation_;
@@ -2281,119 +2623,123 @@ class HCompare: public HBinaryOperation {
};
-class HCompareJSObjectEq: public HBinaryOperation {
+class HCompareObjectEqAndBranch: public HTemplateControlInstruction<2, 2> {
public:
- HCompareJSObjectEq(HValue* left, HValue* right)
- : HBinaryOperation(left, right) {
- set_representation(Representation::Tagged());
- SetFlag(kUseGVN);
- SetFlag(kDependsOnMaps);
+ HCompareObjectEqAndBranch(HValue* left, HValue* right) {
+ SetOperandAt(0, left);
+ SetOperandAt(1, right);
}
- virtual bool EmitAtUses() const {
- return !HasSideEffects() && (uses()->length() <= 1);
- }
+ HValue* left() { return OperandAt(0); }
+ HValue* right() { return OperandAt(1); }
virtual Representation RequiredInputRepresentation(int index) const {
return Representation::Tagged();
}
- virtual HType CalculateInferredType();
-
- DECLARE_CONCRETE_INSTRUCTION(CompareJSObjectEq, "compare-js-object-eq")
- protected:
- virtual bool DataEquals(HValue* other) { return true; }
+ DECLARE_CONCRETE_INSTRUCTION(CompareObjectEqAndBranch)
};
-class HUnaryPredicate: public HUnaryOperation {
+class HCompareConstantEqAndBranch: public HUnaryControlInstruction {
public:
- explicit HUnaryPredicate(HValue* value) : HUnaryOperation(value) {
- set_representation(Representation::Tagged());
- SetFlag(kUseGVN);
+ HCompareConstantEqAndBranch(HValue* left, int right, Token::Value op)
+ : HUnaryControlInstruction(left, NULL, NULL), op_(op), right_(right) {
+ ASSERT(op == Token::EQ_STRICT);
}
- virtual bool EmitAtUses() const {
- return !HasSideEffects() && (uses()->length() <= 1);
- }
+ Token::Value op() const { return op_; }
+ HValue* left() { return value(); }
+ int right() const { return right_; }
virtual Representation RequiredInputRepresentation(int index) const {
- return Representation::Tagged();
+ return Representation::Integer32();
}
- virtual HType CalculateInferredType();
+
+ DECLARE_CONCRETE_INSTRUCTION(CompareConstantEqAndBranch);
+
+ private:
+ const Token::Value op_;
+ const int right_;
};
-class HIsNull: public HUnaryPredicate {
+class HIsNullAndBranch: public HUnaryControlInstruction {
public:
- HIsNull(HValue* value, bool is_strict)
- : HUnaryPredicate(value), is_strict_(is_strict) { }
+ HIsNullAndBranch(HValue* value, bool is_strict)
+ : HUnaryControlInstruction(value, NULL, NULL), is_strict_(is_strict) { }
bool is_strict() const { return is_strict_; }
- DECLARE_CONCRETE_INSTRUCTION(IsNull, "is_null")
-
- protected:
- virtual bool DataEquals(HValue* other) {
- HIsNull* b = HIsNull::cast(other);
- return is_strict_ == b->is_strict();
+ virtual Representation RequiredInputRepresentation(int index) const {
+ return Representation::Tagged();
}
+ DECLARE_CONCRETE_INSTRUCTION(IsNullAndBranch)
+
private:
bool is_strict_;
};
-class HIsObject: public HUnaryPredicate {
+class HIsObjectAndBranch: public HUnaryControlInstruction {
public:
- explicit HIsObject(HValue* value) : HUnaryPredicate(value) { }
+ explicit HIsObjectAndBranch(HValue* value)
+ : HUnaryControlInstruction(value, NULL, NULL) { }
- DECLARE_CONCRETE_INSTRUCTION(IsObject, "is_object")
+ virtual Representation RequiredInputRepresentation(int index) const {
+ return Representation::Tagged();
+ }
- protected:
- virtual bool DataEquals(HValue* other) { return true; }
+ DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch)
};
-class HIsSmi: public HUnaryPredicate {
+class HIsSmiAndBranch: public HUnaryControlInstruction {
public:
- explicit HIsSmi(HValue* value) : HUnaryPredicate(value) { }
+ explicit HIsSmiAndBranch(HValue* value)
+ : HUnaryControlInstruction(value, NULL, NULL) { }
+
+ DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch)
- DECLARE_CONCRETE_INSTRUCTION(IsSmi, "is_smi")
+ virtual Representation RequiredInputRepresentation(int index) const {
+ return Representation::Tagged();
+ }
protected:
virtual bool DataEquals(HValue* other) { return true; }
};
-class HIsConstructCall: public HTemplateInstruction<0> {
+class HIsUndetectableAndBranch: public HUnaryControlInstruction {
public:
- HIsConstructCall() {
- set_representation(Representation::Tagged());
- SetFlag(kUseGVN);
- }
+ explicit HIsUndetectableAndBranch(HValue* value)
+ : HUnaryControlInstruction(value, NULL, NULL) { }
- virtual bool EmitAtUses() const {
- return !HasSideEffects() && (uses()->length() <= 1);
+ virtual Representation RequiredInputRepresentation(int index) const {
+ return Representation::Tagged();
}
+ DECLARE_CONCRETE_INSTRUCTION(IsUndetectableAndBranch)
+};
+
+
+class HIsConstructCallAndBranch: public HTemplateControlInstruction<2, 0> {
+ public:
virtual Representation RequiredInputRepresentation(int index) const {
return Representation::None();
}
- DECLARE_CONCRETE_INSTRUCTION(IsConstructCall, "is_construct_call")
-
- protected:
- virtual bool DataEquals(HValue* other) { return true; }
+ DECLARE_CONCRETE_INSTRUCTION(IsConstructCallAndBranch)
};
-class HHasInstanceType: public HUnaryPredicate {
+class HHasInstanceTypeAndBranch: public HUnaryControlInstruction {
public:
- HHasInstanceType(HValue* value, InstanceType type)
- : HUnaryPredicate(value), from_(type), to_(type) { }
- HHasInstanceType(HValue* value, InstanceType from, InstanceType to)
- : HUnaryPredicate(value), from_(from), to_(to) {
+ HHasInstanceTypeAndBranch(HValue* value, InstanceType type)
+ : HUnaryControlInstruction(value, NULL, NULL), from_(type), to_(type) { }
+ HHasInstanceTypeAndBranch(HValue* value, InstanceType from, InstanceType to)
+ : HUnaryControlInstruction(value, NULL, NULL), from_(from), to_(to) {
ASSERT(to == LAST_TYPE); // Others not implemented yet in backend.
}
@@ -2402,78 +2748,83 @@ class HHasInstanceType: public HUnaryPredicate {
virtual void PrintDataTo(StringStream* stream);
- DECLARE_CONCRETE_INSTRUCTION(HasInstanceType, "has_instance_type")
-
- protected:
- virtual bool DataEquals(HValue* other) {
- HHasInstanceType* b = HHasInstanceType::cast(other);
- return (from_ == b->from()) && (to_ == b->to());
+ virtual Representation RequiredInputRepresentation(int index) const {
+ return Representation::Tagged();
}
+ DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch)
+
private:
InstanceType from_;
InstanceType to_; // Inclusive range, not all combinations work.
};
-class HHasCachedArrayIndex: public HUnaryPredicate {
+class HHasCachedArrayIndexAndBranch: public HUnaryControlInstruction {
public:
- explicit HHasCachedArrayIndex(HValue* value) : HUnaryPredicate(value) { }
+ explicit HHasCachedArrayIndexAndBranch(HValue* value)
+ : HUnaryControlInstruction(value, NULL, NULL) { }
- DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndex, "has_cached_array_index")
+ virtual Representation RequiredInputRepresentation(int index) const {
+ return Representation::Tagged();
+ }
- protected:
- virtual bool DataEquals(HValue* other) { return true; }
+ DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndexAndBranch)
};
-class HGetCachedArrayIndex: public HUnaryPredicate {
+class HGetCachedArrayIndex: public HUnaryOperation {
public:
- explicit HGetCachedArrayIndex(HValue* value) : HUnaryPredicate(value) { }
+ explicit HGetCachedArrayIndex(HValue* value) : HUnaryOperation(value) {
+ set_representation(Representation::Tagged());
+ SetFlag(kUseGVN);
+ }
- DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex, "get_cached_array_index")
+ virtual Representation RequiredInputRepresentation(int index) const {
+ return Representation::Tagged();
+ }
+
+ DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex)
protected:
virtual bool DataEquals(HValue* other) { return true; }
};
-class HClassOfTest: public HUnaryPredicate {
+class HClassOfTestAndBranch: public HUnaryControlInstruction {
public:
- HClassOfTest(HValue* value, Handle<String> class_name)
- : HUnaryPredicate(value), class_name_(class_name) { }
+ HClassOfTestAndBranch(HValue* value, Handle<String> class_name)
+ : HUnaryControlInstruction(value, NULL, NULL),
+ class_name_(class_name) { }
- DECLARE_CONCRETE_INSTRUCTION(ClassOfTest, "class_of_test")
+ DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch)
+
+ virtual Representation RequiredInputRepresentation(int index) const {
+ return Representation::Tagged();
+ }
virtual void PrintDataTo(StringStream* stream);
Handle<String> class_name() const { return class_name_; }
- protected:
- virtual bool DataEquals(HValue* other) {
- HClassOfTest* b = HClassOfTest::cast(other);
- return class_name_.is_identical_to(b->class_name_);
- }
-
private:
Handle<String> class_name_;
};
-class HTypeofIs: public HUnaryPredicate {
+class HTypeofIsAndBranch: public HUnaryControlInstruction {
public:
- HTypeofIs(HValue* value, Handle<String> type_literal)
- : HUnaryPredicate(value), type_literal_(type_literal) { }
+ HTypeofIsAndBranch(HValue* value, Handle<String> type_literal)
+ : HUnaryControlInstruction(value, NULL, NULL),
+ type_literal_(type_literal) { }
Handle<String> type_literal() { return type_literal_; }
virtual void PrintDataTo(StringStream* stream);
- DECLARE_CONCRETE_INSTRUCTION(TypeofIs, "typeof_is")
+ DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch)
- protected:
- virtual bool DataEquals(HValue* other) {
- HTypeofIs* b = HTypeofIs::cast(other);
- return type_literal_.is_identical_to(b->type_literal_);
+ virtual Representation RequiredInputRepresentation(int index) const {
+ return Representation::Tagged();
}
private:
@@ -2481,69 +2832,74 @@ class HTypeofIs: public HUnaryPredicate {
};
-class HInstanceOf: public HTemplateInstruction<3> {
+class HInstanceOf: public HBinaryOperation {
public:
- HInstanceOf(HValue* context, HValue* left, HValue* right) {
- SetOperandAt(0, context);
- SetOperandAt(1, left);
- SetOperandAt(2, right);
+ HInstanceOf(HValue* context, HValue* left, HValue* right)
+ : HBinaryOperation(context, left, right) {
set_representation(Representation::Tagged());
SetAllSideEffects();
}
- HValue* context() { return OperandAt(0); }
- HValue* left() { return OperandAt(1); }
- HValue* right() { return OperandAt(2); }
-
- virtual bool EmitAtUses() const {
- return !HasSideEffects() && (uses()->length() <= 1);
- }
-
virtual Representation RequiredInputRepresentation(int index) const {
return Representation::Tagged();
}
+ virtual HType CalculateInferredType();
+
virtual void PrintDataTo(StringStream* stream);
- DECLARE_CONCRETE_INSTRUCTION(InstanceOf, "instance_of")
+ DECLARE_CONCRETE_INSTRUCTION(InstanceOf)
};
-class HInstanceOfKnownGlobal: public HUnaryOperation {
+class HInstanceOfKnownGlobal: public HTemplateInstruction<2> {
public:
- HInstanceOfKnownGlobal(HValue* left, Handle<JSFunction> right)
- : HUnaryOperation(left), function_(right) {
+ HInstanceOfKnownGlobal(HValue* context,
+ HValue* left,
+ Handle<JSFunction> right)
+ : function_(right) {
+ SetOperandAt(0, context);
+ SetOperandAt(1, left);
set_representation(Representation::Tagged());
SetAllSideEffects();
}
+ HValue* context() { return OperandAt(0); }
+ HValue* left() { return OperandAt(1); }
Handle<JSFunction> function() { return function_; }
virtual Representation RequiredInputRepresentation(int index) const {
return Representation::Tagged();
}
- DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal,
- "instance_of_known_global")
+ virtual HType CalculateInferredType();
+
+ DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal)
private:
Handle<JSFunction> function_;
};
-class HPower: public HBinaryOperation {
+class HPower: public HTemplateInstruction<2> {
public:
- HPower(HValue* left, HValue* right)
- : HBinaryOperation(left, right) {
+ HPower(HValue* left, HValue* right) {
+ SetOperandAt(0, left);
+ SetOperandAt(1, right);
set_representation(Representation::Double());
SetFlag(kUseGVN);
}
+ HValue* left() { return OperandAt(0); }
+ HValue* right() { return OperandAt(1); }
+
virtual Representation RequiredInputRepresentation(int index) const {
- return (index == 1) ? Representation::None() : Representation::Double();
+ return index == 0
+ ? Representation::Double()
+ : Representation::None();
}
- DECLARE_CONCRETE_INSTRUCTION(Power, "power")
+ DECLARE_CONCRETE_INSTRUCTION(Power)
protected:
virtual bool DataEquals(HValue* other) { return true; }
@@ -2552,7 +2908,8 @@ class HPower: public HBinaryOperation {
class HAdd: public HArithmeticBinaryOperation {
public:
- HAdd(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
+ HAdd(HValue* context, HValue* left, HValue* right)
+ : HArithmeticBinaryOperation(context, left, right) {
SetFlag(kCanOverflow);
}
@@ -2566,7 +2923,7 @@ class HAdd: public HArithmeticBinaryOperation {
virtual HType CalculateInferredType();
- DECLARE_CONCRETE_INSTRUCTION(Add, "add")
+ DECLARE_CONCRETE_INSTRUCTION(Add)
protected:
virtual bool DataEquals(HValue* other) { return true; }
@@ -2577,13 +2934,14 @@ class HAdd: public HArithmeticBinaryOperation {
class HSub: public HArithmeticBinaryOperation {
public:
- HSub(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
+ HSub(HValue* context, HValue* left, HValue* right)
+ : HArithmeticBinaryOperation(context, left, right) {
SetFlag(kCanOverflow);
}
virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
- DECLARE_CONCRETE_INSTRUCTION(Sub, "sub")
+ DECLARE_CONCRETE_INSTRUCTION(Sub)
protected:
virtual bool DataEquals(HValue* other) { return true; }
@@ -2594,7 +2952,8 @@ class HSub: public HArithmeticBinaryOperation {
class HMul: public HArithmeticBinaryOperation {
public:
- HMul(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
+ HMul(HValue* context, HValue* left, HValue* right)
+ : HArithmeticBinaryOperation(context, left, right) {
SetFlag(kCanOverflow);
}
@@ -2605,7 +2964,7 @@ class HMul: public HArithmeticBinaryOperation {
return !representation().IsTagged();
}
- DECLARE_CONCRETE_INSTRUCTION(Mul, "mul")
+ DECLARE_CONCRETE_INSTRUCTION(Mul)
protected:
virtual bool DataEquals(HValue* other) { return true; }
@@ -2616,13 +2975,24 @@ class HMul: public HArithmeticBinaryOperation {
class HMod: public HArithmeticBinaryOperation {
public:
- HMod(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
+ HMod(HValue* context, HValue* left, HValue* right)
+ : HArithmeticBinaryOperation(context, left, right) {
SetFlag(kCanBeDivByZero);
}
+ bool HasPowerOf2Divisor() {
+ if (right()->IsConstant() &&
+ HConstant::cast(right())->HasInteger32Value()) {
+ int32_t value = HConstant::cast(right())->Integer32Value();
+ return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value));
+ }
+
+ return false;
+ }
+
virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
- DECLARE_CONCRETE_INSTRUCTION(Mod, "mod")
+ DECLARE_CONCRETE_INSTRUCTION(Mod)
protected:
virtual bool DataEquals(HValue* other) { return true; }
@@ -2633,14 +3003,15 @@ class HMod: public HArithmeticBinaryOperation {
class HDiv: public HArithmeticBinaryOperation {
public:
- HDiv(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
+ HDiv(HValue* context, HValue* left, HValue* right)
+ : HArithmeticBinaryOperation(context, left, right) {
SetFlag(kCanBeDivByZero);
SetFlag(kCanOverflow);
}
virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
- DECLARE_CONCRETE_INSTRUCTION(Div, "div")
+ DECLARE_CONCRETE_INSTRUCTION(Div)
protected:
virtual bool DataEquals(HValue* other) { return true; }
@@ -2651,13 +3022,13 @@ class HDiv: public HArithmeticBinaryOperation {
class HBitAnd: public HBitwiseBinaryOperation {
public:
- HBitAnd(HValue* left, HValue* right)
- : HBitwiseBinaryOperation(left, right) { }
+ HBitAnd(HValue* context, HValue* left, HValue* right)
+ : HBitwiseBinaryOperation(context, left, right) { }
virtual bool IsCommutative() const { return true; }
virtual HType CalculateInferredType();
- DECLARE_CONCRETE_INSTRUCTION(BitAnd, "bit_and")
+ DECLARE_CONCRETE_INSTRUCTION(BitAnd)
protected:
virtual bool DataEquals(HValue* other) { return true; }
@@ -2668,13 +3039,13 @@ class HBitAnd: public HBitwiseBinaryOperation {
class HBitXor: public HBitwiseBinaryOperation {
public:
- HBitXor(HValue* left, HValue* right)
- : HBitwiseBinaryOperation(left, right) { }
+ HBitXor(HValue* context, HValue* left, HValue* right)
+ : HBitwiseBinaryOperation(context, left, right) { }
virtual bool IsCommutative() const { return true; }
virtual HType CalculateInferredType();
- DECLARE_CONCRETE_INSTRUCTION(BitXor, "bit_xor")
+ DECLARE_CONCRETE_INSTRUCTION(BitXor)
protected:
virtual bool DataEquals(HValue* other) { return true; }
@@ -2683,13 +3054,13 @@ class HBitXor: public HBitwiseBinaryOperation {
class HBitOr: public HBitwiseBinaryOperation {
public:
- HBitOr(HValue* left, HValue* right)
- : HBitwiseBinaryOperation(left, right) { }
+ HBitOr(HValue* context, HValue* left, HValue* right)
+ : HBitwiseBinaryOperation(context, left, right) { }
virtual bool IsCommutative() const { return true; }
virtual HType CalculateInferredType();
- DECLARE_CONCRETE_INSTRUCTION(BitOr, "bit_or")
+ DECLARE_CONCRETE_INSTRUCTION(BitOr)
protected:
virtual bool DataEquals(HValue* other) { return true; }
@@ -2700,13 +3071,13 @@ class HBitOr: public HBitwiseBinaryOperation {
class HShl: public HBitwiseBinaryOperation {
public:
- HShl(HValue* left, HValue* right)
- : HBitwiseBinaryOperation(left, right) { }
+ HShl(HValue* context, HValue* left, HValue* right)
+ : HBitwiseBinaryOperation(context, left, right) { }
virtual Range* InferRange();
virtual HType CalculateInferredType();
- DECLARE_CONCRETE_INSTRUCTION(Shl, "shl")
+ DECLARE_CONCRETE_INSTRUCTION(Shl)
protected:
virtual bool DataEquals(HValue* other) { return true; }
@@ -2715,12 +3086,12 @@ class HShl: public HBitwiseBinaryOperation {
class HShr: public HBitwiseBinaryOperation {
public:
- HShr(HValue* left, HValue* right)
- : HBitwiseBinaryOperation(left, right) { }
+ HShr(HValue* context, HValue* left, HValue* right)
+ : HBitwiseBinaryOperation(context, left, right) { }
virtual HType CalculateInferredType();
- DECLARE_CONCRETE_INSTRUCTION(Shr, "shr")
+ DECLARE_CONCRETE_INSTRUCTION(Shr)
protected:
virtual bool DataEquals(HValue* other) { return true; }
@@ -2729,13 +3100,13 @@ class HShr: public HBitwiseBinaryOperation {
class HSar: public HBitwiseBinaryOperation {
public:
- HSar(HValue* left, HValue* right)
- : HBitwiseBinaryOperation(left, right) { }
+ HSar(HValue* context, HValue* left, HValue* right)
+ : HBitwiseBinaryOperation(context, left, right) { }
virtual Range* InferRange();
virtual HType CalculateInferredType();
- DECLARE_CONCRETE_INSTRUCTION(Sar, "sar")
+ DECLARE_CONCRETE_INSTRUCTION(Sar)
protected:
virtual bool DataEquals(HValue* other) { return true; }
@@ -2754,7 +3125,7 @@ class HOsrEntry: public HTemplateInstruction<0> {
return Representation::None();
}
- DECLARE_CONCRETE_INSTRUCTION(OsrEntry, "osr_entry")
+ DECLARE_CONCRETE_INSTRUCTION(OsrEntry)
private:
int ast_id_;
@@ -2775,7 +3146,7 @@ class HParameter: public HTemplateInstruction<0> {
return Representation::None();
}
- DECLARE_CONCRETE_INSTRUCTION(Parameter, "parameter")
+ DECLARE_CONCRETE_INSTRUCTION(Parameter)
private:
unsigned index_;
@@ -2807,7 +3178,7 @@ class HCallStub: public HUnaryCall {
return Representation::Tagged();
}
- DECLARE_CONCRETE_INSTRUCTION(CallStub, "call_stub")
+ DECLARE_CONCRETE_INSTRUCTION(CallStub)
private:
CodeStub::Major major_key_;
@@ -2823,13 +3194,13 @@ class HUnknownOSRValue: public HTemplateInstruction<0> {
return Representation::None();
}
- DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue, "unknown_osr_value")
+ DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue)
};
-class HLoadGlobal: public HTemplateInstruction<0> {
+class HLoadGlobalCell: public HTemplateInstruction<0> {
public:
- HLoadGlobal(Handle<JSGlobalPropertyCell> cell, bool check_hole_value)
+ HLoadGlobalCell(Handle<JSGlobalPropertyCell> cell, bool check_hole_value)
: cell_(cell), check_hole_value_(check_hole_value) {
set_representation(Representation::Tagged());
SetFlag(kUseGVN);
@@ -2842,7 +3213,7 @@ class HLoadGlobal: public HTemplateInstruction<0> {
virtual void PrintDataTo(StringStream* stream);
virtual intptr_t Hashcode() {
- ASSERT(!Heap::allow_allocation(false));
+ ASSERT(!HEAP->allow_allocation(false));
return reinterpret_cast<intptr_t>(*cell_);
}
@@ -2850,11 +3221,11 @@ class HLoadGlobal: public HTemplateInstruction<0> {
return Representation::None();
}
- DECLARE_CONCRETE_INSTRUCTION(LoadGlobal, "load_global")
+ DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell)
protected:
virtual bool DataEquals(HValue* other) {
- HLoadGlobal* b = HLoadGlobal::cast(other);
+ HLoadGlobalCell* b = HLoadGlobalCell::cast(other);
return cell_.is_identical_to(b->cell());
}
@@ -2864,11 +3235,44 @@ class HLoadGlobal: public HTemplateInstruction<0> {
};
-class HStoreGlobal: public HUnaryOperation {
+class HLoadGlobalGeneric: public HTemplateInstruction<2> {
+ public:
+ HLoadGlobalGeneric(HValue* context,
+ HValue* global_object,
+ Handle<Object> name,
+ bool for_typeof)
+ : name_(name),
+ for_typeof_(for_typeof) {
+ SetOperandAt(0, context);
+ SetOperandAt(1, global_object);
+ set_representation(Representation::Tagged());
+ SetAllSideEffects();
+ }
+
+ HValue* context() { return OperandAt(0); }
+ HValue* global_object() { return OperandAt(1); }
+ Handle<Object> name() const { return name_; }
+ bool for_typeof() const { return for_typeof_; }
+
+ virtual void PrintDataTo(StringStream* stream);
+
+ virtual Representation RequiredInputRepresentation(int index) const {
+ return Representation::Tagged();
+ }
+
+ DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric)
+
+ private:
+ Handle<Object> name_;
+ bool for_typeof_;
+};
+
+
+class HStoreGlobalCell: public HUnaryOperation {
public:
- HStoreGlobal(HValue* value,
- Handle<JSGlobalPropertyCell> cell,
- bool check_hole_value)
+ HStoreGlobalCell(HValue* value,
+ Handle<JSGlobalPropertyCell> cell,
+ bool check_hole_value)
: HUnaryOperation(value),
cell_(cell),
check_hole_value_(check_hole_value) {
@@ -2883,7 +3287,7 @@ class HStoreGlobal: public HUnaryOperation {
}
virtual void PrintDataTo(StringStream* stream);
- DECLARE_CONCRETE_INSTRUCTION(StoreGlobal, "store_global")
+ DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell)
private:
Handle<JSGlobalPropertyCell> cell_;
@@ -2891,6 +3295,42 @@ class HStoreGlobal: public HUnaryOperation {
};
+class HStoreGlobalGeneric: public HTemplateInstruction<3> {
+ public:
+ HStoreGlobalGeneric(HValue* context,
+ HValue* global_object,
+ Handle<Object> name,
+ HValue* value,
+ bool strict_mode)
+ : name_(name),
+ strict_mode_(strict_mode) {
+ SetOperandAt(0, context);
+ SetOperandAt(1, global_object);
+ SetOperandAt(2, value);
+ set_representation(Representation::Tagged());
+ SetAllSideEffects();
+ }
+
+ HValue* context() { return OperandAt(0); }
+ HValue* global_object() { return OperandAt(1); }
+ Handle<Object> name() const { return name_; }
+ HValue* value() { return OperandAt(2); }
+ bool strict_mode() { return strict_mode_; }
+
+ virtual void PrintDataTo(StringStream* stream);
+
+ virtual Representation RequiredInputRepresentation(int index) const {
+ return Representation::Tagged();
+ }
+
+ DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric)
+
+ private:
+ Handle<Object> name_;
+ bool strict_mode_;
+};
+
+
class HLoadContextSlot: public HUnaryOperation {
public:
HLoadContextSlot(HValue* context , int slot_index)
@@ -2908,7 +3348,7 @@ class HLoadContextSlot: public HUnaryOperation {
virtual void PrintDataTo(StringStream* stream);
- DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot, "load_context_slot")
+ DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot)
protected:
virtual bool DataEquals(HValue* other) {
@@ -2927,10 +3367,12 @@ static inline bool StoringValueNeedsWriteBarrier(HValue* value) {
}
-class HStoreContextSlot: public HBinaryOperation {
+class HStoreContextSlot: public HTemplateInstruction<2> {
public:
HStoreContextSlot(HValue* context, int slot_index, HValue* value)
- : HBinaryOperation(context, value), slot_index_(slot_index) {
+ : slot_index_(slot_index) {
+ SetOperandAt(0, context);
+ SetOperandAt(1, value);
SetFlag(kChangesContextSlots);
}
@@ -2948,7 +3390,7 @@ class HStoreContextSlot: public HBinaryOperation {
virtual void PrintDataTo(StringStream* stream);
- DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot, "store_context_slot")
+ DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot)
private:
int slot_index_;
@@ -2980,7 +3422,7 @@ class HLoadNamedField: public HUnaryOperation {
}
virtual void PrintDataTo(StringStream* stream);
- DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load_named_field")
+ DECLARE_CONCRETE_INSTRUCTION(LoadNamedField)
protected:
virtual bool DataEquals(HValue* other) {
@@ -2994,10 +3436,44 @@ class HLoadNamedField: public HUnaryOperation {
};
-class HLoadNamedGeneric: public HBinaryOperation {
+class HLoadNamedFieldPolymorphic: public HTemplateInstruction<2> {
+ public:
+ HLoadNamedFieldPolymorphic(HValue* context,
+ HValue* object,
+ ZoneMapList* types,
+ Handle<String> name);
+
+ HValue* context() { return OperandAt(0); }
+ HValue* object() { return OperandAt(1); }
+ ZoneMapList* types() { return &types_; }
+ Handle<String> name() { return name_; }
+ bool need_generic() { return need_generic_; }
+
+ virtual Representation RequiredInputRepresentation(int index) const {
+ return Representation::Tagged();
+ }
+
+ DECLARE_CONCRETE_INSTRUCTION(LoadNamedFieldPolymorphic)
+
+ static const int kMaxLoadPolymorphism = 4;
+
+ protected:
+ virtual bool DataEquals(HValue* value);
+
+ private:
+ ZoneMapList types_;
+ Handle<String> name_;
+ bool need_generic_;
+};
+
+
+
+class HLoadNamedGeneric: public HTemplateInstruction<2> {
public:
HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name)
- : HBinaryOperation(context, object), name_(name) {
+ : name_(name) {
+ SetOperandAt(0, context);
+ SetOperandAt(1, object);
set_representation(Representation::Tagged());
SetAllSideEffects();
}
@@ -3010,7 +3486,7 @@ class HLoadNamedGeneric: public HBinaryOperation {
return Representation::Tagged();
}
- DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric, "load_named_generic")
+ DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric)
private:
Handle<Object> name_;
@@ -3032,16 +3508,18 @@ class HLoadFunctionPrototype: public HUnaryOperation {
return Representation::Tagged();
}
- DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype, "load_function_prototype")
+ DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype)
protected:
virtual bool DataEquals(HValue* other) { return true; }
};
-class HLoadKeyedFastElement: public HBinaryOperation {
+class HLoadKeyedFastElement: public HTemplateInstruction<2> {
public:
- HLoadKeyedFastElement(HValue* obj, HValue* key) : HBinaryOperation(obj, key) {
+ HLoadKeyedFastElement(HValue* obj, HValue* key) {
+ SetOperandAt(0, obj);
+ SetOperandAt(1, key);
set_representation(Representation::Tagged());
SetFlag(kDependsOnArrayElements);
SetFlag(kUseGVN);
@@ -3052,27 +3530,38 @@ class HLoadKeyedFastElement: public HBinaryOperation {
virtual Representation RequiredInputRepresentation(int index) const {
// The key is supposed to be Integer32.
- return (index == 1) ? Representation::Integer32()
- : Representation::Tagged();
+ return index == 0
+ ? Representation::Tagged()
+ : Representation::Integer32();
}
virtual void PrintDataTo(StringStream* stream);
- DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement,
- "load_keyed_fast_element")
+ bool RequiresHoleCheck() const;
+
+ DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement)
protected:
virtual bool DataEquals(HValue* other) { return true; }
};
-class HLoadPixelArrayElement: public HBinaryOperation {
+class HLoadKeyedSpecializedArrayElement: public HTemplateInstruction<2> {
public:
- HLoadPixelArrayElement(HValue* external_elements, HValue* key)
- : HBinaryOperation(external_elements, key) {
- set_representation(Representation::Integer32());
- SetFlag(kDependsOnPixelArrayElements);
- // Native code could change the pixel array.
+ HLoadKeyedSpecializedArrayElement(HValue* external_elements,
+ HValue* key,
+ JSObject::ElementsKind elements_kind)
+ : elements_kind_(elements_kind) {
+ SetOperandAt(0, external_elements);
+ SetOperandAt(1, key);
+ if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS ||
+ elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) {
+ set_representation(Representation::Double());
+ } else {
+ set_representation(Representation::Integer32());
+ }
+ SetFlag(kDependsOnSpecializedArrayElements);
+ // Native code could change the specialized array.
SetFlag(kDependsOnCalls);
SetFlag(kUseGVN);
}
@@ -3082,24 +3571,33 @@ class HLoadPixelArrayElement: public HBinaryOperation {
virtual Representation RequiredInputRepresentation(int index) const {
// The key is supposed to be Integer32, but the base pointer
// for the element load is a naked pointer.
- return (index == 1) ? Representation::Integer32()
- : Representation::External();
+ return index == 0
+ ? Representation::External()
+ : Representation::Integer32();
}
HValue* external_pointer() { return OperandAt(0); }
HValue* key() { return OperandAt(1); }
+ JSObject::ElementsKind elements_kind() const { return elements_kind_; }
- DECLARE_CONCRETE_INSTRUCTION(LoadPixelArrayElement,
- "load_pixel_array_element")
+ DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement)
protected:
- virtual bool DataEquals(HValue* other) { return true; }
+ virtual bool DataEquals(HValue* other) {
+ if (!other->IsLoadKeyedSpecializedArrayElement()) return false;
+ HLoadKeyedSpecializedArrayElement* cast_other =
+ HLoadKeyedSpecializedArrayElement::cast(other);
+ return elements_kind_ == cast_other->elements_kind();
+ }
+
+ private:
+ JSObject::ElementsKind elements_kind_;
};
class HLoadKeyedGeneric: public HTemplateInstruction<3> {
public:
- HLoadKeyedGeneric(HContext* context, HValue* obj, HValue* key) {
+ HLoadKeyedGeneric(HValue* context, HValue* obj, HValue* key) {
set_representation(Representation::Tagged());
SetOperandAt(0, obj);
SetOperandAt(1, key);
@@ -3117,21 +3615,22 @@ class HLoadKeyedGeneric: public HTemplateInstruction<3> {
return Representation::Tagged();
}
- DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric, "load_keyed_generic")
+ DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric)
};
-class HStoreNamedField: public HBinaryOperation {
+class HStoreNamedField: public HTemplateInstruction<2> {
public:
HStoreNamedField(HValue* obj,
Handle<String> name,
HValue* val,
bool in_object,
int offset)
- : HBinaryOperation(obj, val),
- name_(name),
+ : name_(name),
is_in_object_(in_object),
offset_(offset) {
+ SetOperandAt(0, obj);
+ SetOperandAt(1, val);
if (is_in_object_) {
SetFlag(kChangesInobjectFields);
} else {
@@ -3139,7 +3638,7 @@ class HStoreNamedField: public HBinaryOperation {
}
}
- DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store_named_field")
+ DECLARE_CONCRETE_INSTRUCTION(StoreNamedField)
virtual Representation RequiredInputRepresentation(int index) const {
return Representation::Tagged();
@@ -3172,8 +3671,10 @@ class HStoreNamedGeneric: public HTemplateInstruction<3> {
HStoreNamedGeneric(HValue* context,
HValue* object,
Handle<String> name,
- HValue* value)
- : name_(name) {
+ HValue* value,
+ bool strict_mode)
+ : name_(name),
+ strict_mode_(strict_mode) {
SetOperandAt(0, object);
SetOperandAt(1, value);
SetOperandAt(2, context);
@@ -3184,6 +3685,7 @@ class HStoreNamedGeneric: public HTemplateInstruction<3> {
HValue* value() { return OperandAt(1); }
HValue* context() { return OperandAt(2); }
Handle<String> name() { return name_; }
+ bool strict_mode() { return strict_mode_; }
virtual void PrintDataTo(StringStream* stream);
@@ -3191,10 +3693,11 @@ class HStoreNamedGeneric: public HTemplateInstruction<3> {
return Representation::Tagged();
}
- DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric, "store_named_generic")
+ DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric)
private:
Handle<String> name_;
+ bool strict_mode_;
};
@@ -3209,7 +3712,8 @@ class HStoreKeyedFastElement: public HTemplateInstruction<3> {
virtual Representation RequiredInputRepresentation(int index) const {
// The key is supposed to be Integer32.
- return (index == 1) ? Representation::Integer32()
+ return index == 1
+ ? Representation::Integer32()
: Representation::Tagged();
}
@@ -3223,15 +3727,18 @@ class HStoreKeyedFastElement: public HTemplateInstruction<3> {
virtual void PrintDataTo(StringStream* stream);
- DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement,
- "store_keyed_fast_element")
+ DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement)
};
-class HStorePixelArrayElement: public HTemplateInstruction<3> {
+class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> {
public:
- HStorePixelArrayElement(HValue* external_elements, HValue* key, HValue* val) {
- SetFlag(kChangesPixelArrayElements);
+ HStoreKeyedSpecializedArrayElement(HValue* external_elements,
+ HValue* key,
+ HValue* val,
+ JSObject::ElementsKind elements_kind)
+ : elements_kind_(elements_kind) {
+ SetFlag(kChangesSpecializedArrayElements);
SetOperandAt(0, external_elements);
SetOperandAt(1, key);
SetOperandAt(2, val);
@@ -3243,16 +3750,26 @@ class HStorePixelArrayElement: public HTemplateInstruction<3> {
if (index == 0) {
return Representation::External();
} else {
- return Representation::Integer32();
+ bool float_or_double_elements =
+ elements_kind() == JSObject::EXTERNAL_FLOAT_ELEMENTS ||
+ elements_kind() == JSObject::EXTERNAL_DOUBLE_ELEMENTS;
+ if (index == 2 && float_or_double_elements) {
+ return Representation::Double();
+ } else {
+ return Representation::Integer32();
+ }
}
}
HValue* external_pointer() { return OperandAt(0); }
HValue* key() { return OperandAt(1); }
HValue* value() { return OperandAt(2); }
+ JSObject::ElementsKind elements_kind() const { return elements_kind_; }
+
+ DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement)
- DECLARE_CONCRETE_INSTRUCTION(StorePixelArrayElement,
- "store_pixel_array_element")
+ private:
+ JSObject::ElementsKind elements_kind_;
};
@@ -3261,7 +3778,9 @@ class HStoreKeyedGeneric: public HTemplateInstruction<4> {
HStoreKeyedGeneric(HValue* context,
HValue* object,
HValue* key,
- HValue* value) {
+ HValue* value,
+ bool strict_mode)
+ : strict_mode_(strict_mode) {
SetOperandAt(0, object);
SetOperandAt(1, key);
SetOperandAt(2, value);
@@ -3273,6 +3792,7 @@ class HStoreKeyedGeneric: public HTemplateInstruction<4> {
HValue* key() { return OperandAt(1); }
HValue* value() { return OperandAt(2); }
HValue* context() { return OperandAt(3); }
+ bool strict_mode() { return strict_mode_; }
virtual Representation RequiredInputRepresentation(int index) const {
return Representation::Tagged();
@@ -3280,14 +3800,43 @@ class HStoreKeyedGeneric: public HTemplateInstruction<4> {
virtual void PrintDataTo(StringStream* stream);
- DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store_keyed_generic")
+ DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric)
+
+ private:
+ bool strict_mode_;
+};
+
+
+class HStringAdd: public HBinaryOperation {
+ public:
+ HStringAdd(HValue* context, HValue* left, HValue* right)
+ : HBinaryOperation(context, left, right) {
+ set_representation(Representation::Tagged());
+ SetFlag(kUseGVN);
+ SetFlag(kDependsOnMaps);
+ }
+
+ virtual Representation RequiredInputRepresentation(int index) const {
+ return Representation::Tagged();
+ }
+
+ virtual HType CalculateInferredType() {
+ return HType::String();
+ }
+
+ DECLARE_CONCRETE_INSTRUCTION(StringAdd)
+
+ protected:
+ virtual bool DataEquals(HValue* other) { return true; }
};
-class HStringCharCodeAt: public HBinaryOperation {
+class HStringCharCodeAt: public HTemplateInstruction<3> {
public:
- HStringCharCodeAt(HValue* string, HValue* index)
- : HBinaryOperation(string, index) {
+ HStringCharCodeAt(HValue* context, HValue* string, HValue* index) {
+ SetOperandAt(0, context);
+ SetOperandAt(1, string);
+ SetOperandAt(2, index);
set_representation(Representation::Integer32());
SetFlag(kUseGVN);
SetFlag(kDependsOnMaps);
@@ -3295,14 +3844,16 @@ class HStringCharCodeAt: public HBinaryOperation {
virtual Representation RequiredInputRepresentation(int index) const {
// The index is supposed to be Integer32.
- return (index == 1) ? Representation::Integer32()
+ return index == 2
+ ? Representation::Integer32()
: Representation::Tagged();
}
- HValue* string() { return OperandAt(0); }
- HValue* index() { return OperandAt(1); }
+ HValue* context() { return OperandAt(0); }
+ HValue* string() { return OperandAt(1); }
+ HValue* index() { return OperandAt(2); }
- DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt, "string_char_code_at")
+ DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt)
protected:
virtual bool DataEquals(HValue* other) { return true; }
@@ -3313,6 +3864,30 @@ class HStringCharCodeAt: public HBinaryOperation {
};
+class HStringCharFromCode: public HTemplateInstruction<2> {
+ public:
+ HStringCharFromCode(HValue* context, HValue* char_code) {
+ SetOperandAt(0, context);
+ SetOperandAt(1, char_code);
+ set_representation(Representation::Tagged());
+ SetFlag(kUseGVN);
+ }
+
+ virtual Representation RequiredInputRepresentation(int index) const {
+ return index == 0
+ ? Representation::Tagged()
+ : Representation::Integer32();
+ }
+
+ HValue* context() { return OperandAt(0); }
+ HValue* value() { return OperandAt(1); }
+
+ virtual bool DataEquals(HValue* other) { return true; }
+
+ DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode)
+};
+
+
class HStringLength: public HUnaryOperation {
public:
explicit HStringLength(HValue* string) : HUnaryOperation(string) {
@@ -3330,7 +3905,7 @@ class HStringLength: public HUnaryOperation {
return HType::Smi();
}
- DECLARE_CONCRETE_INSTRUCTION(StringLength, "string_length")
+ DECLARE_CONCRETE_INSTRUCTION(StringLength)
protected:
virtual bool DataEquals(HValue* other) { return true; }
@@ -3358,26 +3933,30 @@ class HMaterializedLiteral: public HTemplateInstruction<V> {
};
-class HArrayLiteral: public HMaterializedLiteral<0> {
+class HArrayLiteral: public HMaterializedLiteral<1> {
public:
- HArrayLiteral(Handle<FixedArray> constant_elements,
+ HArrayLiteral(HValue* context,
+ Handle<FixedArray> constant_elements,
int length,
int literal_index,
int depth)
- : HMaterializedLiteral<0>(literal_index, depth),
+ : HMaterializedLiteral<1>(literal_index, depth),
length_(length),
- constant_elements_(constant_elements) {}
+ constant_elements_(constant_elements) {
+ SetOperandAt(0, context);
+ }
+ HValue* context() { return OperandAt(0); }
Handle<FixedArray> constant_elements() const { return constant_elements_; }
int length() const { return length_; }
bool IsCopyOnWrite() const;
virtual Representation RequiredInputRepresentation(int index) const {
- return Representation::None();
+ return Representation::Tagged();
}
- DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral, "array_literal")
+ DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral)
private:
int length_;
@@ -3391,10 +3970,12 @@ class HObjectLiteral: public HMaterializedLiteral<1> {
Handle<FixedArray> constant_properties,
bool fast_elements,
int literal_index,
- int depth)
+ int depth,
+ bool has_function)
: HMaterializedLiteral<1>(literal_index, depth),
constant_properties_(constant_properties),
- fast_elements_(fast_elements) {
+ fast_elements_(fast_elements),
+ has_function_(has_function) {
SetOperandAt(0, context);
}
@@ -3403,36 +3984,42 @@ class HObjectLiteral: public HMaterializedLiteral<1> {
return constant_properties_;
}
bool fast_elements() const { return fast_elements_; }
+ bool has_function() const { return has_function_; }
virtual Representation RequiredInputRepresentation(int index) const {
return Representation::Tagged();
}
- DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral, "object_literal")
+ DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral)
private:
Handle<FixedArray> constant_properties_;
bool fast_elements_;
+ bool has_function_;
};
-class HRegExpLiteral: public HMaterializedLiteral<0> {
+class HRegExpLiteral: public HMaterializedLiteral<1> {
public:
- HRegExpLiteral(Handle<String> pattern,
+ HRegExpLiteral(HValue* context,
+ Handle<String> pattern,
Handle<String> flags,
int literal_index)
- : HMaterializedLiteral<0>(literal_index, 0),
+ : HMaterializedLiteral<1>(literal_index, 0),
pattern_(pattern),
- flags_(flags) { }
+ flags_(flags) {
+ SetOperandAt(0, context);
+ }
+ HValue* context() { return OperandAt(0); }
Handle<String> pattern() { return pattern_; }
Handle<String> flags() { return flags_; }
virtual Representation RequiredInputRepresentation(int index) const {
- return Representation::None();
+ return Representation::Tagged();
}
- DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral, "regexp_literal")
+ DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral)
private:
Handle<String> pattern_;
@@ -3440,18 +4027,23 @@ class HRegExpLiteral: public HMaterializedLiteral<0> {
};
-class HFunctionLiteral: public HTemplateInstruction<0> {
+class HFunctionLiteral: public HTemplateInstruction<1> {
public:
- HFunctionLiteral(Handle<SharedFunctionInfo> shared, bool pretenure)
+ HFunctionLiteral(HValue* context,
+ Handle<SharedFunctionInfo> shared,
+ bool pretenure)
: shared_info_(shared), pretenure_(pretenure) {
+ SetOperandAt(0, context);
set_representation(Representation::Tagged());
}
+ HValue* context() { return OperandAt(0); }
+
virtual Representation RequiredInputRepresentation(int index) const {
- return Representation::None();
+ return Representation::Tagged();
}
- DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral, "function_literal")
+ DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral)
Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
bool pretenure() const { return pretenure_; }
@@ -3462,9 +4054,32 @@ class HFunctionLiteral: public HTemplateInstruction<0> {
};
-class HTypeof: public HUnaryOperation {
+class HTypeof: public HTemplateInstruction<2> {
+ public:
+ explicit HTypeof(HValue* context, HValue* value) {
+ SetOperandAt(0, context);
+ SetOperandAt(1, value);
+ set_representation(Representation::Tagged());
+ }
+
+ HValue* context() { return OperandAt(0); }
+ HValue* value() { return OperandAt(1); }
+
+ virtual Representation RequiredInputRepresentation(int index) const {
+ return Representation::Tagged();
+ }
+
+ DECLARE_CONCRETE_INSTRUCTION(Typeof)
+};
+
+
+class HToFastProperties: public HUnaryOperation {
public:
- explicit HTypeof(HValue* value) : HUnaryOperation(value) {
+ explicit HToFastProperties(HValue* value) : HUnaryOperation(value) {
+ // This instruction is not marked as having side effects, but
+ // changes the map of the input operand. Use it only when creating
+ // object literals.
+ ASSERT(value->IsObjectLiteral());
set_representation(Representation::Tagged());
}
@@ -3472,7 +4087,7 @@ class HTypeof: public HUnaryOperation {
return Representation::Tagged();
}
- DECLARE_CONCRETE_INSTRUCTION(Typeof, "typeof")
+ DECLARE_CONCRETE_INSTRUCTION(ToFastProperties)
};
@@ -3486,14 +4101,14 @@ class HValueOf: public HUnaryOperation {
return Representation::Tagged();
}
- DECLARE_CONCRETE_INSTRUCTION(ValueOf, "value_of")
+ DECLARE_CONCRETE_INSTRUCTION(ValueOf)
};
class HDeleteProperty: public HBinaryOperation {
public:
- HDeleteProperty(HValue* obj, HValue* key)
- : HBinaryOperation(obj, key) {
+ HDeleteProperty(HValue* context, HValue* obj, HValue* key)
+ : HBinaryOperation(context, obj, key) {
set_representation(Representation::Tagged());
SetAllSideEffects();
}
@@ -3502,12 +4117,42 @@ class HDeleteProperty: public HBinaryOperation {
return Representation::Tagged();
}
- DECLARE_CONCRETE_INSTRUCTION(DeleteProperty, "delete_property")
+ virtual HType CalculateInferredType();
+
+ DECLARE_CONCRETE_INSTRUCTION(DeleteProperty)
HValue* object() { return left(); }
HValue* key() { return right(); }
};
+
+class HIn: public HTemplateInstruction<3> {
+ public:
+ HIn(HValue* context, HValue* key, HValue* object) {
+ SetOperandAt(0, context);
+ SetOperandAt(1, key);
+ SetOperandAt(2, object);
+ set_representation(Representation::Tagged());
+ SetAllSideEffects();
+ }
+
+ HValue* context() { return OperandAt(0); }
+ HValue* key() { return OperandAt(1); }
+ HValue* object() { return OperandAt(2); }
+
+ virtual Representation RequiredInputRepresentation(int index) const {
+ return Representation::Tagged();
+ }
+
+ virtual HType CalculateInferredType() {
+ return HType::Boolean();
+ }
+
+ virtual void PrintDataTo(StringStream* stream);
+
+ DECLARE_CONCRETE_INSTRUCTION(In)
+};
+
#undef DECLARE_INSTRUCTION
#undef DECLARE_CONCRETE_INSTRUCTION