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

Unified Diff: src/hydrogen-instructions.h

Issue 149413010: A64: Synchronize with r16024. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/hydrogen-bch.cc ('k') | src/hydrogen-instructions.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/hydrogen-instructions.h
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index c36388ee6abd359898fe1f57134b8e9f19311d81..eac5173f7d00748bec37cba8a7bb68990113342c 100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -135,7 +135,6 @@ class LChunkBuilder;
V(IsSmiAndBranch) \
V(IsUndetectableAndBranch) \
V(LeaveInlined) \
- V(LinkObjectInList) \
V(LoadContextSlot) \
V(LoadExternalArrayPointer) \
V(LoadFieldByIndex) \
@@ -179,7 +178,6 @@ class LChunkBuilder;
V(StringCharCodeAt) \
V(StringCharFromCode) \
V(StringCompareAndBranch) \
- V(StringLength) \
V(Sub) \
V(ThisFunction) \
V(Throw) \
@@ -201,6 +199,7 @@ class LChunkBuilder;
#define GVN_UNTRACKED_FLAG_LIST(V) \
V(ArrayElements) \
V(ArrayLengths) \
+ V(StringLengths) \
V(BackingStoreFields) \
V(Calls) \
V(ContextSlots) \
@@ -211,7 +210,7 @@ class LChunkBuilder;
V(GlobalVars) \
V(InobjectFields) \
V(OsrEntries) \
- V(SpecializedArrayElements)
+ V(ExternalMemory)
#define DECLARE_ABSTRACT_INSTRUCTION(type) \
@@ -350,8 +349,7 @@ class UniqueValueId {
class HType {
public:
- HType() : type_(kUninitialized) { }
-
+ static HType None() { return HType(kNone); }
static HType Tagged() { return HType(kTagged); }
static HType TaggedPrimitive() { return HType(kTaggedPrimitive); }
static HType TaggedNumber() { return HType(kTaggedNumber); }
@@ -362,7 +360,6 @@ class HType {
static HType NonPrimitive() { return HType(kNonPrimitive); }
static HType JSArray() { return HType(kJSArray); }
static HType JSObject() { return HType(kJSObject); }
- static HType Uninitialized() { return HType(kUninitialized); }
// Return the weakest (least precise) common type.
HType Combine(HType other) {
@@ -378,32 +375,26 @@ class HType {
}
bool IsTagged() const {
- ASSERT(type_ != kUninitialized);
return ((type_ & kTagged) == kTagged);
}
bool IsTaggedPrimitive() const {
- ASSERT(type_ != kUninitialized);
return ((type_ & kTaggedPrimitive) == kTaggedPrimitive);
}
bool IsTaggedNumber() const {
- ASSERT(type_ != kUninitialized);
return ((type_ & kTaggedNumber) == kTaggedNumber);
}
bool IsSmi() const {
- ASSERT(type_ != kUninitialized);
return ((type_ & kSmi) == kSmi);
}
bool IsHeapNumber() const {
- ASSERT(type_ != kUninitialized);
return ((type_ & kHeapNumber) == kHeapNumber);
}
bool IsString() const {
- ASSERT(type_ != kUninitialized);
return ((type_ & kString) == kString);
}
@@ -413,40 +404,50 @@ class HType {
}
bool IsBoolean() const {
- ASSERT(type_ != kUninitialized);
return ((type_ & kBoolean) == kBoolean);
}
bool IsNonPrimitive() const {
- ASSERT(type_ != kUninitialized);
return ((type_ & kNonPrimitive) == kNonPrimitive);
}
bool IsJSArray() const {
- ASSERT(type_ != kUninitialized);
return ((type_ & kJSArray) == kJSArray);
}
bool IsJSObject() const {
- ASSERT(type_ != kUninitialized);
return ((type_ & kJSObject) == kJSObject);
}
- bool IsUninitialized() const {
- return type_ == kUninitialized;
- }
-
bool IsHeapObject() const {
- ASSERT(type_ != kUninitialized);
return IsHeapNumber() || IsString() || IsBoolean() || IsNonPrimitive();
}
+ bool ToStringOrToNumberCanBeObserved(Representation representation) {
+ switch (type_) {
+ case kTaggedPrimitive: // fallthru
+ case kTaggedNumber: // fallthru
+ case kSmi: // fallthru
+ case kHeapNumber: // fallthru
+ case kString: // fallthru
+ case kBoolean:
+ return false;
+ case kJSArray: // fallthru
+ case kJSObject:
+ return true;
+ case kTagged:
+ break;
+ }
+ return !representation.IsSmiOrInteger32() && !representation.IsDouble();
+ }
+
static HType TypeFromValue(Handle<Object> value);
const char* ToString();
private:
enum Type {
+ kNone = 0x0, // 0000 0000 0000 0000
kTagged = 0x1, // 0000 0000 0000 0001
kTaggedPrimitive = 0x5, // 0000 0000 0000 0101
kTaggedNumber = 0xd, // 0000 0000 0000 1101
@@ -456,12 +457,11 @@ class HType {
kBoolean = 0x85, // 0000 0000 1000 0101
kNonPrimitive = 0x101, // 0000 0001 0000 0001
kJSObject = 0x301, // 0000 0011 0000 0001
- kJSArray = 0x701, // 0000 0111 0000 0001
- kUninitialized = 0x1fff // 0001 1111 1111 1111
+ kJSArray = 0x701 // 0000 0111 0000 0001
};
// Make sure type fits in int16.
- STATIC_ASSERT(kUninitialized < (1 << (2 * kBitsPerByte)));
+ STATIC_ASSERT(kJSArray < (1 << (2 * kBitsPerByte)));
explicit HType(Type t) : type_(t) { }
@@ -872,12 +872,13 @@ class HValue: public ZoneObject {
HYDROGEN_ABSTRACT_INSTRUCTION_LIST(DECLARE_PREDICATE)
#undef DECLARE_PREDICATE
- HValue() : block_(NULL),
- id_(kNoNumber),
- type_(HType::Tagged()),
- use_list_(NULL),
- range_(NULL),
- flags_(0) {}
+ HValue(HType type = HType::Tagged())
+ : block_(NULL),
+ id_(kNoNumber),
+ type_(type),
+ use_list_(NULL),
+ range_(NULL),
+ flags_(0) {}
virtual ~HValue() {}
HBasicBlock* block() const { return block_; }
@@ -1145,6 +1146,18 @@ class HValue: public ZoneObject {
}
}
+ // Returns true conservatively if the program might be able to observe a
+ // ToString() operation on this value.
+ bool ToStringCanBeObserved() const {
+ return type().ToStringOrToNumberCanBeObserved(representation());
+ }
+
+ // Returns true conservatively if the program might be able to observe a
+ // ToNumber() operation on this value.
+ bool ToNumberCanBeObserved() const {
+ return type().ToStringOrToNumberCanBeObserved(representation());
+ }
+
protected:
void TryGuaranteeRangeRecursive(RangeEvaluationContext* context);
@@ -1295,6 +1308,48 @@ class HValue: public ZoneObject {
};
+#define DECLARE_INSTRUCTION_FACTORY_P0(I) \
+ static I* New(Zone* zone, HValue* context) { \
+ return new(zone) I(); \
+}
+
+#define DECLARE_INSTRUCTION_FACTORY_P1(I, P1) \
+ static I* New(Zone* zone, HValue* context, P1 p1) { \
+ return new(zone) I(p1); \
+ }
+
+#define DECLARE_INSTRUCTION_FACTORY_P2(I, P1, P2) \
+ static I* New(Zone* zone, HValue* context, P1 p1, P2 p2) { \
+ return new(zone) I(p1, p2); \
+ }
+
+#define DECLARE_INSTRUCTION_FACTORY_P3(I, P1, P2, P3) \
+ static I* New(Zone* zone, HValue* context, P1 p1, P2 p2, P3 p3) { \
+ return new(zone) I(p1, p2, p3); \
+ }
+
+#define DECLARE_INSTRUCTION_FACTORY_P4(I, P1, P2, P3, P4) \
+ static I* New(Zone* zone, \
+ HValue* context, \
+ P1 p1, \
+ P2 p2, \
+ P3 p3, \
+ P4 p4) { \
+ return new(zone) I(p1, p2, p3, p4); \
+ }
+
+#define DECLARE_INSTRUCTION_FACTORY_P5(I, P1, P2, P3, P4, P5) \
+ static I* New(Zone* zone, \
+ HValue* context, \
+ P1 p1, \
+ P2 p2, \
+ P3 p3, \
+ P4 p4, \
+ P5 p5) { \
+ return new(zone) I(p1, p2, p3, p4, p5); \
+ }
+
+
class HInstruction: public HValue {
public:
HInstruction* next() const { return next_; }
@@ -1330,8 +1385,9 @@ class HInstruction: public HValue {
DECLARE_ABSTRACT_INSTRUCTION(Instruction)
protected:
- HInstruction()
- : next_(NULL),
+ HInstruction(HType type = HType::Tagged())
+ : HValue(type),
+ next_(NULL),
previous_(NULL),
position_(RelocInfo::kNoPosition) {
SetGVNFlag(kDependsOnOsrEntries);
@@ -1362,6 +1418,8 @@ class HTemplateInstruction : public HInstruction {
HValue* OperandAt(int i) const { return inputs_[i]; }
protected:
+ HTemplateInstruction(HType type = HType::Tagged()) : HInstruction(type) {}
+
void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
private:
@@ -1435,12 +1493,12 @@ class HBlockEntry: public HTemplateInstruction<0> {
class HDummyUse: public HTemplateInstruction<1> {
public:
- explicit HDummyUse(HValue* value) {
+ explicit HDummyUse(HValue* value)
+ : HTemplateInstruction<1>(HType::Smi()) {
SetOperandAt(0, value);
// Pretend to be a Smi so that the HChange instructions inserted
// before any use generate as little code as possible.
set_representation(Representation::Tagged());
- set_type(HType::Smi());
}
HValue* value() { return OperandAt(0); }
@@ -1504,7 +1562,7 @@ class HNumericConstraint : public HTemplateInstruction<2> {
class HDeoptimize: public HTemplateInstruction<0> {
public:
- explicit HDeoptimize(Deoptimizer::BailoutType type) : type_(type) {}
+ DECLARE_INSTRUCTION_FACTORY_P1(HDeoptimize, Deoptimizer::BailoutType);
virtual Representation RequiredInputRepresentation(int index) {
return Representation::None();
@@ -1515,6 +1573,8 @@ class HDeoptimize: public HTemplateInstruction<0> {
DECLARE_CONCRETE_INSTRUCTION(Deoptimize)
private:
+ explicit HDeoptimize(Deoptimizer::BailoutType type) : type_(type) {}
+
Deoptimizer::BailoutType type_;
};
@@ -1615,12 +1675,44 @@ class HCompareMap: public HUnaryControlInstruction {
};
+class HContext: public HTemplateInstruction<0> {
+ public:
+ static HContext* New(Zone* zone) {
+ return new(zone) HContext();
+ }
+
+ virtual Representation RequiredInputRepresentation(int index) {
+ return Representation::None();
+ }
+
+ DECLARE_CONCRETE_INSTRUCTION(Context)
+
+ protected:
+ virtual bool DataEquals(HValue* other) { return true; }
+
+ private:
+ HContext() {
+ set_representation(Representation::Tagged());
+ SetFlag(kUseGVN);
+ }
+
+ virtual bool IsDeletable() const { return true; }
+};
+
+
class HReturn: public HTemplateControlInstruction<0, 3> {
public:
- HReturn(HValue* value, HValue* context, HValue* parameter_count) {
- SetOperandAt(0, value);
- SetOperandAt(1, context);
- SetOperandAt(2, parameter_count);
+ static HInstruction* New(Zone* zone,
+ HValue* context,
+ HValue* value,
+ HValue* parameter_count) {
+ return new(zone) HReturn(value, context, parameter_count);
+ }
+
+ static HInstruction* New(Zone* zone,
+ HValue* context,
+ HValue* value) {
+ return new(zone) HReturn(value, context, 0);
}
virtual Representation RequiredInputRepresentation(int index) {
@@ -1634,6 +1726,13 @@ class HReturn: public HTemplateControlInstruction<0, 3> {
HValue* parameter_count() { return OperandAt(2); }
DECLARE_CONCRETE_INSTRUCTION(Return)
+
+ private:
+ HReturn(HValue* value, HValue* context, HValue* parameter_count) {
+ SetOperandAt(0, value);
+ SetOperandAt(1, context);
+ SetOperandAt(2, parameter_count);
+ }
};
@@ -1649,7 +1748,8 @@ class HAbnormalExit: public HTemplateControlInstruction<0, 0> {
class HUnaryOperation: public HTemplateInstruction<1> {
public:
- explicit HUnaryOperation(HValue* value) {
+ HUnaryOperation(HValue* value, HType type = HType::Tagged())
+ : HTemplateInstruction<1>(type) {
SetOperandAt(0, value);
}
@@ -1664,10 +1764,10 @@ class HUnaryOperation: public HTemplateInstruction<1> {
class HThrow: public HTemplateInstruction<2> {
public:
- HThrow(HValue* context, HValue* value) {
- SetOperandAt(0, context);
- SetOperandAt(1, value);
- SetAllSideEffects();
+ static HThrow* New(Zone* zone,
+ HValue* context,
+ HValue* value) {
+ return new(zone) HThrow(context, value);
}
virtual Representation RequiredInputRepresentation(int index) {
@@ -1678,27 +1778,34 @@ class HThrow: public HTemplateInstruction<2> {
HValue* value() { return OperandAt(1); }
DECLARE_CONCRETE_INSTRUCTION(Throw)
+
+ private:
+ HThrow(HValue* context, HValue* value) {
+ SetOperandAt(0, context);
+ SetOperandAt(1, value);
+ SetAllSideEffects();
+ }
};
class HUseConst: public HUnaryOperation {
public:
- explicit HUseConst(HValue* old_value) : HUnaryOperation(old_value) { }
+ DECLARE_INSTRUCTION_FACTORY_P1(HUseConst, HValue*);
virtual Representation RequiredInputRepresentation(int index) {
return Representation::None();
}
DECLARE_CONCRETE_INSTRUCTION(UseConst)
+
+ private:
+ explicit HUseConst(HValue* old_value) : HUnaryOperation(old_value) { }
};
class HForceRepresentation: public HTemplateInstruction<1> {
public:
- HForceRepresentation(HValue* value, Representation required_representation) {
- SetOperandAt(0, value);
- set_representation(required_representation);
- }
+ DECLARE_INSTRUCTION_FACTORY_P2(HForceRepresentation, HValue*, Representation);
HValue* value() { return OperandAt(0); }
@@ -1711,6 +1818,12 @@ class HForceRepresentation: public HTemplateInstruction<1> {
virtual void PrintDataTo(StringStream* stream);
DECLARE_CONCRETE_INSTRUCTION(ForceRepresentation)
+
+ private:
+ HForceRepresentation(HValue* value, Representation required_representation) {
+ SetOperandAt(0, value);
+ set_representation(required_representation);
+ }
};
@@ -1772,12 +1885,7 @@ class HChange: public HUnaryOperation {
class HClampToUint8: public HUnaryOperation {
public:
- explicit HClampToUint8(HValue* value)
- : HUnaryOperation(value) {
- set_representation(Representation::Integer32());
- SetFlag(kAllowUndefinedAsNaN);
- SetFlag(kUseGVN);
- }
+ DECLARE_INSTRUCTION_FACTORY_P1(HClampToUint8, HValue*);
virtual Representation RequiredInputRepresentation(int index) {
return Representation::None();
@@ -1789,6 +1897,13 @@ class HClampToUint8: public HUnaryOperation {
virtual bool DataEquals(HValue* other) { return true; }
private:
+ explicit HClampToUint8(HValue* value)
+ : HUnaryOperation(value) {
+ set_representation(Representation::Integer32());
+ SetFlag(kAllowUndefinedAsNaN);
+ SetFlag(kUseGVN);
+ }
+
virtual bool IsDeletable() const { return true; }
};
@@ -1945,10 +2060,7 @@ class HStackCheck: public HTemplateInstruction<1> {
kBackwardsBranch
};
- HStackCheck(HValue* context, Type type) : type_(type) {
- SetOperandAt(0, context);
- SetGVNFlag(kChangesNewSpacePromotion);
- }
+ DECLARE_INSTRUCTION_FACTORY_P2(HStackCheck, HValue*, Type);
HValue* context() { return OperandAt(0); }
@@ -1970,6 +2082,11 @@ class HStackCheck: public HTemplateInstruction<1> {
DECLARE_CONCRETE_INSTRUCTION(StackCheck)
private:
+ HStackCheck(HValue* context, Type type) : type_(type) {
+ SetOperandAt(0, context);
+ SetGVNFlag(kChangesNewSpacePromotion);
+ }
+
Type type_;
};
@@ -1988,23 +2105,18 @@ class HArgumentsObject;
class HEnterInlined: public HTemplateInstruction<0> {
public:
- HEnterInlined(Handle<JSFunction> closure,
- int arguments_count,
- FunctionLiteral* function,
- InliningKind inlining_kind,
- Variable* arguments_var,
- HArgumentsObject* arguments_object,
- bool undefined_receiver,
- Zone* zone)
- : closure_(closure),
- arguments_count_(arguments_count),
- arguments_pushed_(false),
- function_(function),
- inlining_kind_(inlining_kind),
- arguments_var_(arguments_var),
- arguments_object_(arguments_object),
- undefined_receiver_(undefined_receiver),
- return_targets_(2, zone) {
+ static HEnterInlined* New(Zone* zone,
+ HValue* context,
+ Handle<JSFunction> closure,
+ int arguments_count,
+ FunctionLiteral* function,
+ InliningKind inlining_kind,
+ Variable* arguments_var,
+ HArgumentsObject* arguments_object,
+ bool undefined_receiver) {
+ return new(zone) HEnterInlined(closure, arguments_count, function,
+ inlining_kind, arguments_var,
+ arguments_object, undefined_receiver, zone);
}
void RegisterReturnTarget(HBasicBlock* return_target, Zone* zone);
@@ -2030,6 +2142,25 @@ class HEnterInlined: public HTemplateInstruction<0> {
DECLARE_CONCRETE_INSTRUCTION(EnterInlined)
private:
+ HEnterInlined(Handle<JSFunction> closure,
+ int arguments_count,
+ FunctionLiteral* function,
+ InliningKind inlining_kind,
+ Variable* arguments_var,
+ HArgumentsObject* arguments_object,
+ bool undefined_receiver,
+ Zone* zone)
+ : closure_(closure),
+ arguments_count_(arguments_count),
+ arguments_pushed_(false),
+ function_(function),
+ inlining_kind_(inlining_kind),
+ arguments_var_(arguments_var),
+ arguments_object_(arguments_object),
+ undefined_receiver_(undefined_receiver),
+ return_targets_(2, zone) {
+ }
+
Handle<JSFunction> closure_;
int arguments_count_;
bool arguments_pushed_;
@@ -2056,9 +2187,7 @@ class HLeaveInlined: public HTemplateInstruction<0> {
class HPushArgument: public HUnaryOperation {
public:
- explicit HPushArgument(HValue* value) : HUnaryOperation(value) {
- set_representation(Representation::Tagged());
- }
+ DECLARE_INSTRUCTION_FACTORY_P1(HPushArgument, HValue*);
virtual Representation RequiredInputRepresentation(int index) {
return Representation::Tagged();
@@ -2067,6 +2196,11 @@ class HPushArgument: public HUnaryOperation {
HValue* argument() { return OperandAt(0); }
DECLARE_CONCRETE_INSTRUCTION(PushArgument)
+
+ private:
+ explicit HPushArgument(HValue* value) : HUnaryOperation(value) {
+ set_representation(Representation::Tagged());
+ }
};
@@ -2091,44 +2225,25 @@ class HThisFunction: public HTemplateInstruction<0> {
};
-class HContext: public HTemplateInstruction<0> {
+class HOuterContext: public HUnaryOperation {
public:
- HContext() {
- set_representation(Representation::Tagged());
- SetFlag(kUseGVN);
- }
+ DECLARE_INSTRUCTION_FACTORY_P1(HOuterContext, HValue*);
+
+ DECLARE_CONCRETE_INSTRUCTION(OuterContext);
virtual Representation RequiredInputRepresentation(int index) {
- return Representation::None();
+ return Representation::Tagged();
}
- DECLARE_CONCRETE_INSTRUCTION(Context)
-
protected:
virtual bool DataEquals(HValue* other) { return true; }
private:
- virtual bool IsDeletable() const { return true; }
-};
-
-
-class HOuterContext: public HUnaryOperation {
- public:
explicit HOuterContext(HValue* inner) : HUnaryOperation(inner) {
set_representation(Representation::Tagged());
SetFlag(kUseGVN);
}
- DECLARE_CONCRETE_INSTRUCTION(OuterContext);
-
- virtual Representation RequiredInputRepresentation(int index) {
- return Representation::Tagged();
- }
-
- protected:
- virtual bool DataEquals(HValue* other) { return true; }
-
- private:
virtual bool IsDeletable() const { return true; }
};
@@ -2145,6 +2260,13 @@ class HDeclareGlobals: public HUnaryOperation {
SetAllSideEffects();
}
+ static HDeclareGlobals* New(Zone* zone,
+ HValue* context,
+ Handle<FixedArray> pairs,
+ int flags) {
+ return new(zone) HDeclareGlobals(context, pairs, flags);
+ }
+
HValue* context() { return OperandAt(0); }
Handle<FixedArray> pairs() const { return pairs_; }
int flags() const { return flags_; }
@@ -2154,6 +2276,7 @@ class HDeclareGlobals: public HUnaryOperation {
virtual Representation RequiredInputRepresentation(int index) {
return Representation::Tagged();
}
+
private:
Handle<FixedArray> pairs_;
int flags_;
@@ -2167,6 +2290,10 @@ class HGlobalObject: public HUnaryOperation {
SetFlag(kUseGVN);
}
+ static HGlobalObject* New(Zone* zone, HValue* context) {
+ return new(zone) HGlobalObject(context);
+ }
+
DECLARE_CONCRETE_INSTRUCTION(GlobalObject)
virtual Representation RequiredInputRepresentation(int index) {
@@ -2183,11 +2310,7 @@ class HGlobalObject: public HUnaryOperation {
class HGlobalReceiver: public HUnaryOperation {
public:
- explicit HGlobalReceiver(HValue* global_object)
- : HUnaryOperation(global_object) {
- set_representation(Representation::Tagged());
- SetFlag(kUseGVN);
- }
+ DECLARE_INSTRUCTION_FACTORY_P1(HGlobalReceiver, HValue*);
DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver)
@@ -2199,6 +2322,12 @@ class HGlobalReceiver: public HUnaryOperation {
virtual bool DataEquals(HValue* other) { return true; }
private:
+ explicit HGlobalReceiver(HValue* global_object)
+ : HUnaryOperation(global_object) {
+ set_representation(Representation::Tagged());
+ SetFlag(kUseGVN);
+ }
+
virtual bool IsDeletable() const { return true; }
};
@@ -2265,6 +2394,13 @@ class HInvokeFunction: public HBinaryCall {
: HBinaryCall(context, function, argument_count) {
}
+ static HInvokeFunction* New(Zone* zone,
+ HValue* context,
+ HValue* function,
+ int argument_count) {
+ return new(zone) HInvokeFunction(context, function, argument_count);
+ }
+
HInvokeFunction(HValue* context,
HValue* function,
Handle<JSFunction> known_function,
@@ -2275,6 +2411,15 @@ class HInvokeFunction: public HBinaryCall {
? 0 : known_function->shared()->formal_parameter_count();
}
+ static HInvokeFunction* New(Zone* zone,
+ HValue* context,
+ HValue* function,
+ Handle<JSFunction> known_function,
+ int argument_count) {
+ return new(zone) HInvokeFunction(context, function,
+ known_function, argument_count);
+ }
+
virtual Representation RequiredInputRepresentation(int index) {
return Representation::Tagged();
}
@@ -2366,6 +2511,13 @@ class HCallFunction: public HBinaryCall {
: HBinaryCall(context, function, argument_count) {
}
+ static HCallFunction* New(Zone* zone,
+ HValue* context,
+ HValue* function,
+ int argument_count) {
+ return new(zone) HCallFunction(context, function, argument_count);
+ }
+
HValue* context() { return first(); }
HValue* function() { return second(); }
@@ -2383,6 +2535,13 @@ class HCallGlobal: public HUnaryCall {
: HUnaryCall(context, argument_count), name_(name) {
}
+ static HCallGlobal* New(Zone* zone,
+ HValue* context,
+ Handle<String> name,
+ int argument_count) {
+ return new(zone) HCallGlobal(context, name, argument_count);
+ }
+
virtual void PrintDataTo(StringStream* stream);
HValue* context() { return value(); }
@@ -2466,12 +2625,12 @@ class HCallNewArray: public HCallNew {
class HCallRuntime: public HCall<1> {
public:
- HCallRuntime(HValue* context,
- Handle<String> name,
- const Runtime::Function* c_function,
- int argument_count)
- : HCall<1>(argument_count), c_function_(c_function), name_(name) {
- SetOperandAt(0, context);
+ static HCallRuntime* New(Zone* zone,
+ HValue* context,
+ Handle<String> name,
+ const Runtime::Function* c_function,
+ int argument_count) {
+ return new(zone) HCallRuntime(context, name, c_function, argument_count);
}
virtual void PrintDataTo(StringStream* stream);
@@ -2487,6 +2646,14 @@ class HCallRuntime: public HCall<1> {
DECLARE_CONCRETE_INSTRUCTION(CallRuntime)
private:
+ HCallRuntime(HValue* context,
+ Handle<String> name,
+ const Runtime::Function* c_function,
+ int argument_count)
+ : HCall<1>(argument_count), c_function_(c_function), name_(name) {
+ SetOperandAt(0, context);
+ }
+
const Runtime::Function* c_function_;
Handle<String> name_;
};
@@ -2494,12 +2661,7 @@ class HCallRuntime: public HCall<1> {
class HMapEnumLength: public HUnaryOperation {
public:
- explicit HMapEnumLength(HValue* value) : HUnaryOperation(value) {
- set_type(HType::Smi());
- set_representation(Representation::Smi());
- SetFlag(kUseGVN);
- SetGVNFlag(kDependsOnMaps);
- }
+ DECLARE_INSTRUCTION_FACTORY_P1(HMapEnumLength, HValue*);
virtual Representation RequiredInputRepresentation(int index) {
return Representation::Tagged();
@@ -2511,6 +2673,13 @@ class HMapEnumLength: public HUnaryOperation {
virtual bool DataEquals(HValue* other) { return true; }
private:
+ explicit HMapEnumLength(HValue* value)
+ : HUnaryOperation(value, HType::Smi()) {
+ set_representation(Representation::Smi());
+ SetFlag(kUseGVN);
+ SetGVNFlag(kDependsOnMaps);
+ }
+
virtual bool IsDeletable() const { return true; }
};
@@ -2539,12 +2708,7 @@ class HElementsKind: public HUnaryOperation {
class HBitNot: public HUnaryOperation {
public:
- explicit HBitNot(HValue* value) : HUnaryOperation(value) {
- set_representation(Representation::Integer32());
- SetFlag(kUseGVN);
- SetFlag(kTruncatingToInt32);
- SetFlag(kAllowUndefinedAsNaN);
- }
+ DECLARE_INSTRUCTION_FACTORY_P1(HBitNot, HValue*);
virtual Representation RequiredInputRepresentation(int index) {
return Representation::Integer32();
@@ -2552,7 +2716,6 @@ class HBitNot: public HUnaryOperation {
virtual Representation observed_input_representation(int index) {
return Representation::Integer32();
}
- virtual HType CalculateInferredType();
virtual HValue* Canonicalize();
@@ -2562,6 +2725,14 @@ class HBitNot: public HUnaryOperation {
virtual bool DataEquals(HValue* other) { return true; }
private:
+ explicit HBitNot(HValue* value)
+ : HUnaryOperation(value, HType::TaggedNumber()) {
+ set_representation(Representation::Integer32());
+ SetFlag(kUseGVN);
+ SetFlag(kTruncatingToInt32);
+ SetFlag(kAllowUndefinedAsNaN);
+ }
+
virtual bool IsDeletable() const { return true; }
};
@@ -2578,8 +2749,6 @@ class HUnaryMathOperation: public HTemplateInstruction<2> {
virtual void PrintDataTo(StringStream* stream);
- virtual HType CalculateInferredType();
-
virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
virtual Representation RequiredInputRepresentation(int index) {
@@ -2624,7 +2793,7 @@ class HUnaryMathOperation: public HTemplateInstruction<2> {
private:
HUnaryMathOperation(HValue* context, HValue* value, BuiltinFunctionId op)
- : op_(op) {
+ : HTemplateInstruction<2>(HType::TaggedNumber()), op_(op) {
SetOperandAt(0, context);
SetOperandAt(1, value);
switch (op) {
@@ -2668,35 +2837,43 @@ class HUnaryMathOperation: public HTemplateInstruction<2> {
class HLoadExternalArrayPointer: public HUnaryOperation {
public:
- 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 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);
- }
+ DECLARE_INSTRUCTION_FACTORY_P1(HLoadExternalArrayPointer, HValue*);
virtual Representation RequiredInputRepresentation(int index) {
return Representation::Tagged();
}
+ virtual HType CalculateInferredType() {
+ return HType::None();
+ }
+
DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer)
protected:
virtual bool DataEquals(HValue* other) { return true; }
private:
+ 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 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);
+ }
+
virtual bool IsDeletable() const { return true; }
};
class HCheckMaps: public HTemplateInstruction<2> {
public:
- static HCheckMaps* New(HValue* value, Handle<Map> map, Zone* zone,
- CompilationInfo* info, HValue *typecheck = NULL);
- static HCheckMaps* New(HValue* value, SmallMapList* maps, Zone* zone,
+ static HCheckMaps* New(Zone* zone, HValue* context, HValue* value,
+ Handle<Map> map, CompilationInfo* info,
+ HValue *typecheck = NULL);
+ static HCheckMaps* New(Zone* zone, HValue* context,
+ HValue* value, SmallMapList* maps,
HValue *typecheck = NULL) {
HCheckMaps* check_map = new(zone) HCheckMaps(value, zone, typecheck);
for (int i = 0; i < maps->length(); i++) {
@@ -2706,9 +2883,6 @@ class HCheckMaps: public HTemplateInstruction<2> {
return check_map;
}
- static HCheckMaps* NewWithTransitions(HValue* value, Handle<Map> map,
- Zone* zone, CompilationInfo* info);
-
bool CanOmitMapChecks() { return omit_; }
virtual bool HasEscapingOperandAt(int index) { return false; }
@@ -2718,7 +2892,6 @@ class HCheckMaps: public HTemplateInstruction<2> {
virtual void HandleSideEffectDominator(GVNFlag side_effect,
HValue* dominator);
virtual void PrintDataTo(StringStream* stream);
- virtual HType CalculateInferredType();
HValue* value() { return OperandAt(0); }
SmallMapList* map_set() { return &map_set_; }
@@ -2746,7 +2919,8 @@ class HCheckMaps: public HTemplateInstruction<2> {
private:
// Clients should use one of the static New* methods above.
HCheckMaps(HValue* value, Zone *zone, HValue* typecheck)
- : omit_(false), map_unique_ids_(0, zone) {
+ : HTemplateInstruction<2>(value->type()),
+ omit_(false), map_unique_ids_(0, zone) {
SetOperandAt(0, value);
// Use the object value for the dependency if NULL is passed.
// TODO(titzer): do GVN flags already express this dependency?
@@ -2775,18 +2949,12 @@ class HCheckMaps: public HTemplateInstruction<2> {
class HCheckFunction: public HUnaryOperation {
public:
- HCheckFunction(HValue* value, Handle<JSFunction> function)
- : HUnaryOperation(value), target_(function), target_unique_id_() {
- set_representation(Representation::Tagged());
- SetFlag(kUseGVN);
- target_in_new_space_ = Isolate::Current()->heap()->InNewSpace(*function);
- }
+ DECLARE_INSTRUCTION_FACTORY_P2(HCheckFunction, HValue*, Handle<JSFunction>);
virtual Representation RequiredInputRepresentation(int index) {
return Representation::Tagged();
}
virtual void PrintDataTo(StringStream* stream);
- virtual HType CalculateInferredType();
virtual HValue* Canonicalize();
@@ -2810,6 +2978,14 @@ class HCheckFunction: public HUnaryOperation {
}
private:
+ HCheckFunction(HValue* value, Handle<JSFunction> function)
+ : HUnaryOperation(value, value->type()),
+ target_(function), target_unique_id_() {
+ set_representation(Representation::Tagged());
+ SetFlag(kUseGVN);
+ target_in_new_space_ = Isolate::Current()->heap()->InNewSpace(*function);
+ }
+
Handle<JSFunction> target_;
UniqueValueId target_unique_id_;
bool target_in_new_space_;
@@ -2878,17 +3054,12 @@ class HCheckInstanceType: public HUnaryOperation {
class HCheckSmi: public HUnaryOperation {
public:
- explicit HCheckSmi(HValue* value) : HUnaryOperation(value) {
- set_representation(Representation::Smi());
- SetFlag(kUseGVN);
- }
+ DECLARE_INSTRUCTION_FACTORY_P1(HCheckSmi, HValue*);
virtual Representation RequiredInputRepresentation(int index) {
return Representation::Tagged();
}
- virtual HType CalculateInferredType();
-
virtual HValue* Canonicalize() {
HType value_type = value()->type();
if (value_type.IsSmi()) {
@@ -2901,6 +3072,12 @@ class HCheckSmi: public HUnaryOperation {
protected:
virtual bool DataEquals(HValue* other) { return true; }
+
+ private:
+ explicit HCheckSmi(HValue* value) : HUnaryOperation(value, HType::Smi()) {
+ set_representation(Representation::Smi());
+ SetFlag(kUseGVN);
+ }
};
@@ -2921,67 +3098,42 @@ class HIsNumberAndBranch: public HUnaryControlInstruction {
class HCheckHeapObject: public HUnaryOperation {
public:
- explicit HCheckHeapObject(HValue* value) : HUnaryOperation(value) {
- set_representation(Representation::Tagged());
- SetFlag(kUseGVN);
- }
+ DECLARE_INSTRUCTION_FACTORY_P1(HCheckHeapObject, HValue*);
virtual Representation RequiredInputRepresentation(int index) {
return Representation::Tagged();
}
- virtual HType CalculateInferredType();
-
#ifdef DEBUG
virtual void Verify();
#endif
virtual HValue* Canonicalize() {
- HType value_type = value()->type();
- if (!value_type.IsUninitialized() && value_type.IsHeapObject()) {
- return NULL;
- }
- return this;
+ return value()->type().IsHeapObject() ? NULL : this;
}
DECLARE_CONCRETE_INSTRUCTION(CheckHeapObject)
protected:
virtual bool DataEquals(HValue* other) { return true; }
+
+ private:
+ explicit HCheckHeapObject(HValue* value)
+ : HUnaryOperation(value, HType::NonPrimitive()) {
+ set_representation(Representation::Tagged());
+ SetFlag(kUseGVN);
+ }
};
class HCheckPrototypeMaps: public HTemplateInstruction<0> {
public:
- HCheckPrototypeMaps(Handle<JSObject> prototype,
- Handle<JSObject> holder,
- Zone* zone,
- CompilationInfo* info)
- : prototypes_(2, zone),
- maps_(2, zone),
- first_prototype_unique_id_(),
- last_prototype_unique_id_(),
- can_omit_prototype_maps_(true) {
- SetFlag(kUseGVN);
- SetGVNFlag(kDependsOnMaps);
- // Keep a list of all objects on the prototype chain up to the holder
- // and the expected maps.
- while (true) {
- prototypes_.Add(prototype, zone);
- Handle<Map> map(prototype->map());
- maps_.Add(map, zone);
- can_omit_prototype_maps_ &= map->CanOmitPrototypeChecks();
- if (prototype.is_identical_to(holder)) break;
- prototype = Handle<JSObject>(JSObject::cast(prototype->GetPrototype()));
- }
- if (can_omit_prototype_maps_) {
- // Mark in-flight compilation as dependent on those maps.
- for (int i = 0; i < maps()->length(); i++) {
- Handle<Map> map = maps()->at(i);
- map->AddDependentCompilationInfo(DependentCode::kPrototypeCheckGroup,
- info);
- }
- }
+ static HCheckPrototypeMaps* New(Zone* zone,
+ HValue* context,
+ Handle<JSObject> prototype,
+ Handle<JSObject> holder,
+ CompilationInfo* info) {
+ return new(zone) HCheckPrototypeMaps(prototype, holder, zone, info);
}
ZoneList<Handle<JSObject> >* prototypes() { return &prototypes_; }
@@ -3016,6 +3168,37 @@ class HCheckPrototypeMaps: public HTemplateInstruction<0> {
}
private:
+ HCheckPrototypeMaps(Handle<JSObject> prototype,
+ Handle<JSObject> holder,
+ Zone* zone,
+ CompilationInfo* info)
+ : prototypes_(2, zone),
+ maps_(2, zone),
+ first_prototype_unique_id_(),
+ last_prototype_unique_id_(),
+ can_omit_prototype_maps_(true) {
+ SetFlag(kUseGVN);
+ SetGVNFlag(kDependsOnMaps);
+ // Keep a list of all objects on the prototype chain up to the holder
+ // and the expected maps.
+ while (true) {
+ prototypes_.Add(prototype, zone);
+ Handle<Map> map(prototype->map());
+ maps_.Add(map, zone);
+ can_omit_prototype_maps_ &= map->CanOmitPrototypeChecks();
+ if (prototype.is_identical_to(holder)) break;
+ prototype = Handle<JSObject>(JSObject::cast(prototype->GetPrototype()));
+ }
+ if (can_omit_prototype_maps_) {
+ // Mark in-flight compilation as dependent on those maps.
+ for (int i = 0; i < maps()->length(); i++) {
+ Handle<Map> map = maps()->at(i);
+ map->AddDependentCompilationInfo(DependentCode::kPrototypeCheckGroup,
+ info);
+ }
+ }
+ }
+
ZoneList<Handle<JSObject> > prototypes_;
ZoneList<Handle<Map> > maps_;
UniqueValueId first_prototype_unique_id_;
@@ -3343,9 +3526,6 @@ class HPhi: public HValue {
void SimplifyConstantInputs();
- // TODO(titzer): we can't eliminate the receiver for generating backtraces
- virtual bool IsDeletable() const { return !IsReceiver(); }
-
protected:
virtual void DeleteFromGraph();
virtual void InternalSetOperandAt(int index, HValue* value) {
@@ -3365,6 +3545,9 @@ class HPhi: public HValue {
int indirect_uses_[Representation::kNumRepresentations];
int phi_id_;
InductionVariableData* induction_variable_data_;
+
+ // TODO(titzer): we can't eliminate the receiver for generating backtraces
+ virtual bool IsDeletable() const { return !IsReceiver(); }
};
@@ -3417,9 +3600,10 @@ class HInductionVariableAnnotation : public HUnaryOperation {
class HArgumentsObject: public HTemplateInstruction<0> {
public:
- HArgumentsObject(int count, Zone* zone) : values_(count, zone) {
- set_representation(Representation::Tagged());
- SetFlag(kIsArguments);
+ static HArgumentsObject* New(Zone* zone,
+ HValue* context,
+ int count) {
+ return new(zone) HArgumentsObject(count, zone);
}
const ZoneList<HValue*>* arguments_values() const { return &values_; }
@@ -3446,6 +3630,11 @@ class HArgumentsObject: public HTemplateInstruction<0> {
}
private:
+ HArgumentsObject(int count, Zone* zone) : values_(count, zone) {
+ set_representation(Representation::Tagged());
+ SetFlag(kIsArguments);
+ }
+
virtual bool IsDeletable() const { return true; }
ZoneList<HValue*> values_;
@@ -3454,23 +3643,11 @@ class HArgumentsObject: public HTemplateInstruction<0> {
class HConstant: public HTemplateInstruction<0> {
public:
- HConstant(Handle<Object> handle, Representation r = Representation::None());
- HConstant(int32_t value,
- Representation r = Representation::None(),
- bool is_not_in_new_space = true,
- Handle<Object> optional_handle = Handle<Object>::null());
- HConstant(double value,
- Representation r = Representation::None(),
- bool is_not_in_new_space = true,
- Handle<Object> optional_handle = Handle<Object>::null());
- HConstant(Handle<Object> handle,
- UniqueValueId unique_id,
- Representation r,
- HType type,
- bool is_internalized_string,
- bool is_not_in_new_space,
- bool is_cell,
- bool boolean_value);
+ DECLARE_INSTRUCTION_FACTORY_P1(HConstant, int32_t);
+ DECLARE_INSTRUCTION_FACTORY_P2(HConstant, int32_t, Representation);
+ DECLARE_INSTRUCTION_FACTORY_P1(HConstant, double);
+ DECLARE_INSTRUCTION_FACTORY_P1(HConstant, Handle<Object>);
+ DECLARE_INSTRUCTION_FACTORY_P1(HConstant, ExternalReference);
Handle<Object> handle() {
if (handle_.is_null()) {
@@ -3535,12 +3712,12 @@ class HConstant: public HTemplateInstruction<0> {
if (HasSmiValue() && kSmiValueSize == 31) return Representation::Smi();
if (HasInteger32Value()) return Representation::Integer32();
if (HasNumberValue()) return Representation::Double();
+ if (HasExternalReferenceValue()) return Representation::External();
return Representation::Tagged();
}
virtual bool EmitAtUses();
virtual void PrintDataTo(StringStream* stream);
- virtual HType CalculateInferredType();
bool IsInteger() { return handle()->IsSmi(); }
HConstant* CopyToRepresentation(Representation r, Zone* zone) const;
Maybe<HConstant*> CopyToTruncatedInt32(Zone* zone);
@@ -3577,7 +3754,7 @@ class HConstant: public HTemplateInstruction<0> {
bool HasStringValue() const {
if (has_double_value_ || has_int32_value_) return false;
ASSERT(!handle_.is_null());
- return type_from_value_.IsString();
+ return type_.IsString();
}
Handle<String> StringValue() const {
ASSERT(HasStringValue());
@@ -3587,6 +3764,13 @@ class HConstant: public HTemplateInstruction<0> {
return HasStringValue() && is_internalized_string_;
}
+ bool HasExternalReferenceValue() const {
+ return has_external_reference_value_;
+ }
+ ExternalReference ExternalReferenceValue() const {
+ return external_reference_value_;
+ }
+
bool BooleanValue() const { return boolean_value_; }
virtual intptr_t Hashcode() {
@@ -3594,6 +3778,8 @@ class HConstant: public HTemplateInstruction<0> {
return static_cast<intptr_t>(int32_value_);
} else if (has_double_value_) {
return static_cast<intptr_t>(BitCast<int64_t>(double_value_));
+ } else if (has_external_reference_value_) {
+ return reinterpret_cast<intptr_t>(external_reference_value_.address());
} else {
ASSERT(!handle_.is_null());
return unique_id_.Hashcode();
@@ -3601,14 +3787,15 @@ class HConstant: public HTemplateInstruction<0> {
}
virtual void FinalizeUniqueValueId() {
- if (!has_double_value_) {
+ if (!has_double_value_ && !has_external_reference_value_) {
ASSERT(!handle_.is_null());
unique_id_ = UniqueValueId(handle_);
}
}
bool UniqueValueIdsMatch(UniqueValueId other) {
- return !has_double_value_ && unique_id_ == other;
+ return !has_double_value_ && !has_external_reference_value_ &&
+ unique_id_ == other;
}
#ifdef DEBUG
@@ -3629,6 +3816,10 @@ class HConstant: public HTemplateInstruction<0> {
return other_constant->has_double_value_ &&
BitCast<int64_t>(double_value_) ==
BitCast<int64_t>(other_constant->double_value_);
+ } else if (has_external_reference_value_) {
+ return other_constant->has_external_reference_value_ &&
+ external_reference_value_ ==
+ other_constant->external_reference_value_;
} else {
ASSERT(!handle_.is_null());
return !other_constant->handle_.is_null() &&
@@ -3637,6 +3828,26 @@ class HConstant: public HTemplateInstruction<0> {
}
private:
+ friend class HGraph;
+ HConstant(Handle<Object> handle, Representation r = Representation::None());
+ HConstant(int32_t value,
+ Representation r = Representation::None(),
+ bool is_not_in_new_space = true,
+ Handle<Object> optional_handle = Handle<Object>::null());
+ HConstant(double value,
+ Representation r = Representation::None(),
+ bool is_not_in_new_space = true,
+ Handle<Object> optional_handle = Handle<Object>::null());
+ HConstant(Handle<Object> handle,
+ UniqueValueId unique_id,
+ Representation r,
+ HType type,
+ bool is_internalized_string,
+ bool is_not_in_new_space,
+ bool is_cell,
+ bool boolean_value);
+ explicit HConstant(ExternalReference reference);
+
void Initialize(Representation r);
virtual bool IsDeletable() const { return true; }
@@ -3656,20 +3867,23 @@ class HConstant: public HTemplateInstruction<0> {
bool has_smi_value_ : 1;
bool has_int32_value_ : 1;
bool has_double_value_ : 1;
+ bool has_external_reference_value_ : 1;
bool is_internalized_string_ : 1; // TODO(yangguo): make this part of HType.
bool is_not_in_new_space_ : 1;
bool is_cell_ : 1;
bool boolean_value_ : 1;
int32_t int32_value_;
double double_value_;
- HType type_from_value_;
+ ExternalReference external_reference_value_;
};
class HBinaryOperation: public HTemplateInstruction<3> {
public:
- HBinaryOperation(HValue* context, HValue* left, HValue* right)
- : observed_output_representation_(Representation::None()) {
+ HBinaryOperation(HValue* context, HValue* left, HValue* right,
+ HType type = HType::Tagged())
+ : HTemplateInstruction<3>(type),
+ observed_output_representation_(Representation::None()) {
ASSERT(left != NULL && right != NULL);
SetOperandAt(0, context);
SetOperandAt(1, left);
@@ -3678,9 +3892,9 @@ class HBinaryOperation: public HTemplateInstruction<3> {
observed_input_representation_[1] = Representation::None();
}
- HValue* context() { return OperandAt(0); }
- HValue* left() { return OperandAt(1); }
- HValue* right() { return OperandAt(2); }
+ HValue* context() const { return OperandAt(0); }
+ HValue* left() const { return OperandAt(1); }
+ HValue* right() const { return OperandAt(2); }
// True if switching left and right operands likely generates better code.
bool AreOperandsBetterSwitched() {
@@ -3753,11 +3967,7 @@ class HBinaryOperation: public HTemplateInstruction<3> {
class HWrapReceiver: public HTemplateInstruction<2> {
public:
- HWrapReceiver(HValue* receiver, HValue* function) {
- set_representation(Representation::Tagged());
- SetOperandAt(0, receiver);
- SetOperandAt(1, function);
- }
+ DECLARE_INSTRUCTION_FACTORY_P2(HWrapReceiver, HValue*, HValue*);
virtual Representation RequiredInputRepresentation(int index) {
return Representation::Tagged();
@@ -3771,6 +3981,13 @@ class HWrapReceiver: public HTemplateInstruction<2> {
virtual void PrintDataTo(StringStream* stream);
DECLARE_CONCRETE_INSTRUCTION(WrapReceiver)
+
+ private:
+ HWrapReceiver(HValue* receiver, HValue* function) {
+ set_representation(Representation::Tagged());
+ SetOperandAt(0, receiver);
+ SetOperandAt(1, function);
+ }
};
@@ -3806,12 +4023,7 @@ class HApplyArguments: public HTemplateInstruction<4> {
class HArgumentsElements: public HTemplateInstruction<0> {
public:
- explicit HArgumentsElements(bool from_inlined) : from_inlined_(from_inlined) {
- // The value produced by this instruction is a pointer into the stack
- // that looks as if it was a smi because of alignment.
- set_representation(Representation::Tagged());
- SetFlag(kUseGVN);
- }
+ DECLARE_INSTRUCTION_FACTORY_P1(HArgumentsElements, bool);
DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements)
@@ -3825,6 +4037,13 @@ class HArgumentsElements: public HTemplateInstruction<0> {
virtual bool DataEquals(HValue* other) { return true; }
private:
+ explicit HArgumentsElements(bool from_inlined) : from_inlined_(from_inlined) {
+ // The value produced by this instruction is a pointer into the stack
+ // that looks as if it was a smi because of alignment.
+ set_representation(Representation::Tagged());
+ SetFlag(kUseGVN);
+ }
+
virtual bool IsDeletable() const { return true; }
bool from_inlined_;
@@ -3833,10 +4052,7 @@ class HArgumentsElements: public HTemplateInstruction<0> {
class HArgumentsLength: public HUnaryOperation {
public:
- explicit HArgumentsLength(HValue* value) : HUnaryOperation(value) {
- set_representation(Representation::Integer32());
- SetFlag(kUseGVN);
- }
+ DECLARE_INSTRUCTION_FACTORY_P1(HArgumentsLength, HValue*);
virtual Representation RequiredInputRepresentation(int index) {
return Representation::Tagged();
@@ -3848,6 +4064,11 @@ class HArgumentsLength: public HUnaryOperation {
virtual bool DataEquals(HValue* other) { return true; }
private:
+ explicit HArgumentsLength(HValue* value) : HUnaryOperation(value) {
+ set_representation(Representation::Integer32());
+ SetFlag(kUseGVN);
+ }
+
virtual bool IsDeletable() const { return true; }
};
@@ -3886,23 +4107,11 @@ class HBoundsCheckBaseIndexInformation;
class HBoundsCheck: public HTemplateInstruction<2> {
public:
- // Normally HBoundsCheck should be created using the
- // HGraphBuilder::AddBoundsCheck() helper.
- // However when building stubs, where we know that the arguments are Int32,
- // it makes sense to invoke this constructor directly.
- HBoundsCheck(HValue* index, HValue* length)
- : skip_check_(false),
- base_(NULL), offset_(0), scale_(0),
- responsibility_direction_(DIRECTION_NONE),
- allow_equality_(false) {
- SetOperandAt(0, index);
- SetOperandAt(1, length);
- SetFlag(kFlexibleRepresentation);
- SetFlag(kUseGVN);
- }
+ DECLARE_INSTRUCTION_FACTORY_P2(HBoundsCheck, HValue*, HValue*);
bool skip_check() const { return skip_check_; }
void set_skip_check() { skip_check_ = true; }
+
HValue* base() { return base_; }
int offset() { return offset_; }
int scale() { return scale_; }
@@ -3934,9 +4143,6 @@ class HBoundsCheck: public HTemplateInstruction<2> {
virtual Representation RequiredInputRepresentation(int arg_index) {
return representation();
}
- virtual bool IsDeletable() const {
- return skip_check() && !FLAG_debug_code;
- }
virtual bool IsRelationTrueInternal(NumericRelation relation,
HValue* related_value,
@@ -3973,6 +4179,26 @@ class HBoundsCheck: public HTemplateInstruction<2> {
int scale_;
RangeGuaranteeDirection responsibility_direction_;
bool allow_equality_;
+
+ private:
+ // Normally HBoundsCheck should be created using the
+ // HGraphBuilder::AddBoundsCheck() helper.
+ // However when building stubs, where we know that the arguments are Int32,
+ // it makes sense to invoke this constructor directly.
+ HBoundsCheck(HValue* index, HValue* length)
+ : skip_check_(false),
+ base_(NULL), offset_(0), scale_(0),
+ responsibility_direction_(DIRECTION_NONE),
+ allow_equality_(false) {
+ SetOperandAt(0, index);
+ SetOperandAt(1, length);
+ SetFlag(kFlexibleRepresentation);
+ SetFlag(kUseGVN);
+ }
+
+ virtual bool IsDeletable() const {
+ return skip_check() && !FLAG_debug_code;
+ }
};
@@ -4018,8 +4244,9 @@ class HBoundsCheckBaseIndexInformation: public HTemplateInstruction<2> {
class HBitwiseBinaryOperation: public HBinaryOperation {
public:
- HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right)
- : HBinaryOperation(context, left, right) {
+ HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right,
+ HType type = HType::Tagged())
+ : HBinaryOperation(context, left, right, type) {
SetFlag(kFlexibleRepresentation);
SetFlag(kTruncatingToInt32);
SetFlag(kAllowUndefinedAsNaN);
@@ -4056,8 +4283,6 @@ class HBitwiseBinaryOperation: public HBinaryOperation {
HBinaryOperation::initialize_output_representation(observed);
}
- virtual HType CalculateInferredType();
-
DECLARE_ABSTRACT_INSTRUCTION(BitwiseBinaryOperation)
private:
@@ -4067,15 +4292,11 @@ class HBitwiseBinaryOperation: public HBinaryOperation {
class HMathFloorOfDiv: public HBinaryOperation {
public:
- HMathFloorOfDiv(HValue* context, HValue* left, HValue* right)
- : HBinaryOperation(context, left, right) {
- set_representation(Representation::Integer32());
- SetFlag(kUseGVN);
- SetFlag(kCanOverflow);
- if (!right->IsConstant()) {
- SetFlag(kCanBeDivByZero);
- }
- SetFlag(kAllowUndefinedAsNaN);
+ static HMathFloorOfDiv* New(Zone* zone,
+ HValue* context,
+ HValue* left,
+ HValue* right) {
+ return new(zone) HMathFloorOfDiv(context, left, right);
}
virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
@@ -4090,6 +4311,17 @@ class HMathFloorOfDiv: public HBinaryOperation {
virtual bool DataEquals(HValue* other) { return true; }
private:
+ HMathFloorOfDiv(HValue* context, HValue* left, HValue* right)
+ : HBinaryOperation(context, left, right) {
+ set_representation(Representation::Integer32());
+ SetFlag(kUseGVN);
+ SetFlag(kCanOverflow);
+ if (!right->IsConstant()) {
+ SetFlag(kCanBeDivByZero);
+ }
+ SetFlag(kAllowUndefinedAsNaN);
+ }
+
virtual bool IsDeletable() const { return true; }
};
@@ -4097,7 +4329,7 @@ class HMathFloorOfDiv: public HBinaryOperation {
class HArithmeticBinaryOperation: public HBinaryOperation {
public:
HArithmeticBinaryOperation(HValue* context, HValue* left, HValue* right)
- : HBinaryOperation(context, left, right) {
+ : HBinaryOperation(context, left, right, HType::TaggedNumber()) {
SetAllSideEffects();
SetFlag(kFlexibleRepresentation);
SetFlag(kAllowUndefinedAsNaN);
@@ -4113,8 +4345,6 @@ class HArithmeticBinaryOperation: public HBinaryOperation {
}
}
- virtual HType CalculateInferredType();
-
DECLARE_ABSTRACT_INSTRUCTION(ArithmeticBinaryOperation)
private:
@@ -4128,7 +4358,8 @@ class HCompareGeneric: public HBinaryOperation {
HValue* left,
HValue* right,
Token::Value token)
- : HBinaryOperation(context, left, right), token_(token) {
+ : HBinaryOperation(context, left, right, HType::Boolean()),
+ token_(token) {
ASSERT(Token::IsCompareOp(token));
set_representation(Representation::Tagged());
SetAllSideEffects();
@@ -4143,8 +4374,6 @@ class HCompareGeneric: public HBinaryOperation {
Token::Value token() const { return token_; }
virtual void PrintDataTo(StringStream* stream);
- virtual HType CalculateInferredType();
-
DECLARE_CONCRETE_INSTRUCTION(CompareGeneric)
private:
@@ -4194,11 +4423,16 @@ class HCompareNumericAndBranch: public HTemplateControlInstruction<2, 2> {
class HCompareObjectEqAndBranch: public HTemplateControlInstruction<2, 2> {
public:
- HCompareObjectEqAndBranch(HValue* left, HValue* right) {
+ // TODO(danno): make this private when the IfBuilder properly constructs
+ // control flow instructions.
+ HCompareObjectEqAndBranch(HValue* left,
+ HValue* right) {
SetOperandAt(0, left);
SetOperandAt(1, right);
}
+ DECLARE_INSTRUCTION_FACTORY_P2(HCompareObjectEqAndBranch, HValue*, HValue*);
+
HValue* left() { return OperandAt(0); }
HValue* right() { return OperandAt(1); }
@@ -4420,7 +4654,7 @@ class HTypeofIsAndBranch: public HUnaryControlInstruction {
class HInstanceOf: public HBinaryOperation {
public:
HInstanceOf(HValue* context, HValue* left, HValue* right)
- : HBinaryOperation(context, left, right) {
+ : HBinaryOperation(context, left, right, HType::Boolean()) {
set_representation(Representation::Tagged());
SetAllSideEffects();
}
@@ -4429,8 +4663,6 @@ class HInstanceOf: public HBinaryOperation {
return Representation::Tagged();
}
- virtual HType CalculateInferredType();
-
virtual void PrintDataTo(StringStream* stream);
DECLARE_CONCRETE_INSTRUCTION(InstanceOf)
@@ -4442,7 +4674,7 @@ class HInstanceOfKnownGlobal: public HTemplateInstruction<2> {
HInstanceOfKnownGlobal(HValue* context,
HValue* left,
Handle<JSFunction> right)
- : function_(right) {
+ : HTemplateInstruction<2>(HType::Boolean()), function_(right) {
SetOperandAt(0, context);
SetOperandAt(1, left);
set_representation(Representation::Tagged());
@@ -4457,8 +4689,6 @@ class HInstanceOfKnownGlobal: public HTemplateInstruction<2> {
return Representation::Tagged();
}
- virtual HType CalculateInferredType();
-
DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal)
private:
@@ -4488,7 +4718,10 @@ class HInstanceSize: public HTemplateInstruction<1> {
class HPower: public HTemplateInstruction<2> {
public:
- static HInstruction* New(Zone* zone, HValue* left, HValue* right);
+ static HInstruction* New(Zone* zone,
+ HValue* context,
+ HValue* left,
+ HValue* right);
HValue* left() { return OperandAt(0); }
HValue* right() const { return OperandAt(1); }
@@ -4557,8 +4790,6 @@ class HAdd: public HArithmeticBinaryOperation {
virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
- virtual HType CalculateInferredType();
-
virtual HValue* Canonicalize();
virtual bool TryDecompose(DecompositionResult* decomposition) {
@@ -4825,8 +5056,8 @@ class HMathMinMax: public HArithmeticBinaryOperation {
class HBitwise: public HBitwiseBinaryOperation {
public:
static HInstruction* New(Zone* zone,
- Token::Value op,
HValue* context,
+ Token::Value op,
HValue* left,
HValue* right);
@@ -4848,8 +5079,12 @@ class HBitwise: public HBitwiseBinaryOperation {
virtual Range* InferRange(Zone* zone);
private:
- HBitwise(Token::Value op, HValue* context, HValue* left, HValue* right)
- : HBitwiseBinaryOperation(context, left, right), op_(op) {
+ HBitwise(HValue* context,
+ Token::Value op,
+ HValue* left,
+ HValue* right)
+ : HBitwiseBinaryOperation(context, left, right, HType::TaggedNumber()),
+ op_(op) {
ASSERT(op == Token::BIT_AND || op == Token::BIT_OR || op == Token::BIT_XOR);
// BIT_AND with a smi-range positive value will always unset the
// entire sign-extension of the smi-sign.
@@ -5010,10 +5245,7 @@ class HRor: public HBitwiseBinaryOperation {
class HOsrEntry: public HTemplateInstruction<0> {
public:
- explicit HOsrEntry(BailoutId ast_id) : ast_id_(ast_id) {
- SetGVNFlag(kChangesOsrEntries);
- SetGVNFlag(kChangesNewSpacePromotion);
- }
+ DECLARE_INSTRUCTION_FACTORY_P1(HOsrEntry, BailoutId);
BailoutId ast_id() const { return ast_id_; }
@@ -5024,6 +5256,11 @@ class HOsrEntry: public HTemplateInstruction<0> {
DECLARE_CONCRETE_INSTRUCTION(OsrEntry)
private:
+ explicit HOsrEntry(BailoutId ast_id) : ast_id_(ast_id) {
+ SetGVNFlag(kChangesOsrEntries);
+ SetGVNFlag(kChangesNewSpacePromotion);
+ }
+
BailoutId ast_id_;
};
@@ -5035,6 +5272,23 @@ class HParameter: public HTemplateInstruction<0> {
REGISTER_PARAMETER
};
+ DECLARE_INSTRUCTION_FACTORY_P1(HParameter, unsigned);
+ DECLARE_INSTRUCTION_FACTORY_P2(HParameter, unsigned, ParameterKind);
+ DECLARE_INSTRUCTION_FACTORY_P3(HParameter, unsigned, ParameterKind,
+ Representation);
+
+ unsigned index() const { return index_; }
+ ParameterKind kind() const { return kind_; }
+
+ virtual void PrintDataTo(StringStream* stream);
+
+ virtual Representation RequiredInputRepresentation(int index) {
+ return Representation::None();
+ }
+
+ DECLARE_CONCRETE_INSTRUCTION(Parameter)
+
+ private:
explicit HParameter(unsigned index,
ParameterKind kind = STACK_PARAMETER)
: index_(index),
@@ -5050,18 +5304,6 @@ class HParameter: public HTemplateInstruction<0> {
set_representation(r);
}
- unsigned index() const { return index_; }
- ParameterKind kind() const { return kind_; }
-
- virtual void PrintDataTo(StringStream* stream);
-
- virtual Representation RequiredInputRepresentation(int index) {
- return Representation::None();
- }
-
- DECLARE_CONCRETE_INSTRUCTION(Parameter)
-
- private:
unsigned index_;
ParameterKind kind_;
};
@@ -5102,10 +5344,7 @@ class HCallStub: public HUnaryCall {
class HUnknownOSRValue: public HTemplateInstruction<0> {
public:
- HUnknownOSRValue()
- : incoming_value_(NULL) {
- set_representation(Representation::Tagged());
- }
+ DECLARE_INSTRUCTION_FACTORY_P0(HUnknownOSRValue)
virtual Representation RequiredInputRepresentation(int index) {
return Representation::None();
@@ -5127,6 +5366,11 @@ class HUnknownOSRValue: public HTemplateInstruction<0> {
DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue)
private:
+ HUnknownOSRValue()
+ : incoming_value_(NULL) {
+ set_representation(Representation::Tagged());
+ }
+
HPhi* incoming_value_;
};
@@ -5209,41 +5453,19 @@ class HLoadGlobalGeneric: public HTemplateInstruction<2> {
class HAllocate: public HTemplateInstruction<2> {
public:
- enum Flags {
- CAN_ALLOCATE_IN_NEW_SPACE = 1 << 0,
- CAN_ALLOCATE_IN_OLD_DATA_SPACE = 1 << 1,
- CAN_ALLOCATE_IN_OLD_POINTER_SPACE = 1 << 2,
- ALLOCATE_DOUBLE_ALIGNED = 1 << 3,
- PREFILL_WITH_FILLER = 1 << 4
- };
-
- HAllocate(HValue* context, HValue* size, HType type, Flags flags)
- : flags_(flags) {
- SetOperandAt(0, context);
- SetOperandAt(1, size);
- set_type(type);
- set_representation(Representation::Tagged());
- SetFlag(kTrackSideEffectDominators);
- SetGVNFlag(kChangesNewSpacePromotion);
- SetGVNFlag(kDependsOnNewSpacePromotion);
+ static HAllocate* New(Zone* zone,
+ HValue* context,
+ HValue* size,
+ HType type,
+ PretenureFlag pretenure_flag,
+ InstanceType instance_type) {
+ return new(zone) HAllocate(context, size, type, pretenure_flag,
+ instance_type);
}
// Maximum instance size for which allocations will be inlined.
static const int kMaxInlineSize = 64 * kPointerSize;
- static Flags DefaultFlags() {
- return CAN_ALLOCATE_IN_NEW_SPACE;
- }
-
- static Flags DefaultFlags(ElementsKind kind) {
- Flags flags = CAN_ALLOCATE_IN_NEW_SPACE;
- if (IsFastDoubleElementsKind(kind)) {
- flags = static_cast<HAllocate::Flags>(
- flags | HAllocate::ALLOCATE_DOUBLE_ALIGNED);
- }
- return flags;
- }
-
HValue* context() { return OperandAt(0); }
HValue* size() { return OperandAt(1); }
@@ -5263,25 +5485,16 @@ class HAllocate: public HTemplateInstruction<2> {
known_initial_map_ = known_initial_map;
}
- bool CanAllocateInNewSpace() const {
- return (flags_ & CAN_ALLOCATE_IN_NEW_SPACE) != 0;
- }
-
- bool CanAllocateInOldDataSpace() const {
- return (flags_ & CAN_ALLOCATE_IN_OLD_DATA_SPACE) != 0;
+ bool IsNewSpaceAllocation() const {
+ return (flags_ & ALLOCATE_IN_NEW_SPACE) != 0;
}
- bool CanAllocateInOldPointerSpace() const {
- return (flags_ & CAN_ALLOCATE_IN_OLD_POINTER_SPACE) != 0;
+ bool IsOldDataSpaceAllocation() const {
+ return (flags_ & ALLOCATE_IN_OLD_DATA_SPACE) != 0;
}
- bool CanAllocateInOldSpace() const {
- return CanAllocateInOldDataSpace() ||
- CanAllocateInOldPointerSpace();
- }
-
- bool GuaranteedInNewSpace() const {
- return CanAllocateInNewSpace() && !CanAllocateInOldSpace();
+ bool IsOldPointerSpaceAllocation() const {
+ return (flags_ & ALLOCATE_IN_OLD_POINTER_SPACE) != 0;
}
bool MustAllocateDoubleAligned() const {
@@ -5292,8 +5505,12 @@ class HAllocate: public HTemplateInstruction<2> {
return (flags_ & PREFILL_WITH_FILLER) != 0;
}
- void SetFlags(Flags flags) {
- flags_ = static_cast<HAllocate::Flags>(flags_ | flags);
+ void MakePrefillWithFiller() {
+ flags_ = static_cast<HAllocate::Flags>(flags_ | PREFILL_WITH_FILLER);
+ }
+
+ void MakeDoubleAligned() {
+ flags_ = static_cast<HAllocate::Flags>(flags_ | ALLOCATE_DOUBLE_ALIGNED);
}
void UpdateSize(HValue* size) {
@@ -5308,6 +5525,36 @@ class HAllocate: public HTemplateInstruction<2> {
DECLARE_CONCRETE_INSTRUCTION(Allocate)
private:
+ enum Flags {
+ ALLOCATE_IN_NEW_SPACE = 1 << 0,
+ ALLOCATE_IN_OLD_DATA_SPACE = 1 << 1,
+ ALLOCATE_IN_OLD_POINTER_SPACE = 1 << 2,
+ ALLOCATE_DOUBLE_ALIGNED = 1 << 3,
+ PREFILL_WITH_FILLER = 1 << 4
+ };
+
+ HAllocate(HValue* context,
+ HValue* size,
+ HType type,
+ PretenureFlag pretenure_flag,
+ InstanceType instance_type)
+ : HTemplateInstruction<2>(type) {
+ SetOperandAt(0, context);
+ SetOperandAt(1, size);
+ set_representation(Representation::Tagged());
+ SetFlag(kTrackSideEffectDominators);
+ SetGVNFlag(kChangesNewSpacePromotion);
+ SetGVNFlag(kDependsOnNewSpacePromotion);
+ flags_ = pretenure_flag == TENURED
+ ? (Heap::TargetSpaceId(instance_type) == OLD_POINTER_SPACE
+ ? ALLOCATE_IN_OLD_POINTER_SPACE : ALLOCATE_IN_OLD_DATA_SPACE)
+ : ALLOCATE_IN_NEW_SPACE;
+ if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
+ flags_ = static_cast<HAllocate::Flags>(flags_ |
+ ALLOCATE_DOUBLE_ALIGNED);
+ }
+ }
+
Flags flags_;
Handle<Map> known_initial_map_;
};
@@ -5315,12 +5562,12 @@ class HAllocate: public HTemplateInstruction<2> {
class HInnerAllocatedObject: public HTemplateInstruction<1> {
public:
- HInnerAllocatedObject(HValue* value, int offset, HType type = HType::Tagged())
- : offset_(offset) {
- ASSERT(value->IsAllocate());
- SetOperandAt(0, value);
- set_type(type);
- set_representation(Representation::Tagged());
+ static HInnerAllocatedObject* New(Zone* zone,
+ HValue* context,
+ HValue* value,
+ int offset,
+ HType type = HType::Tagged()) {
+ return new(zone) HInnerAllocatedObject(value, offset, type);
}
HValue* base_object() { return OperandAt(0); }
@@ -5335,6 +5582,14 @@ class HInnerAllocatedObject: public HTemplateInstruction<1> {
DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject)
private:
+ HInnerAllocatedObject(HValue* value, int offset, HType type = HType::Tagged())
+ : HTemplateInstruction<1>(type), offset_(offset) {
+ ASSERT(value->IsAllocate());
+ SetOperandAt(0, value);
+ set_type(type);
+ set_representation(Representation::Tagged());
+ }
+
int offset_;
};
@@ -5356,9 +5611,14 @@ inline bool ReceiverObjectNeedsWriteBarrier(HValue* object,
if (object->IsConstant() && HConstant::cast(object)->IsCell()) {
return false;
}
+ if (object->IsConstant() &&
+ HConstant::cast(object)->HasExternalReferenceValue()) {
+ // Stores to external references require no write barriers
+ return false;
+ }
if (object != new_space_dominator) return true;
if (object->IsAllocate()) {
- return !HAllocate::cast(object)->GuaranteedInNewSpace();
+ return !HAllocate::cast(object)->IsNewSpaceAllocation();
}
return true;
}
@@ -5366,14 +5626,8 @@ inline bool ReceiverObjectNeedsWriteBarrier(HValue* object,
class HStoreGlobalCell: public HUnaryOperation {
public:
- HStoreGlobalCell(HValue* value,
- Handle<PropertyCell> cell,
- PropertyDetails details)
- : HUnaryOperation(value),
- cell_(cell),
- details_(details) {
- SetGVNFlag(kChangesGlobalVars);
- }
+ DECLARE_INSTRUCTION_FACTORY_P3(HStoreGlobalCell, HValue*,
+ Handle<PropertyCell>, PropertyDetails);
Handle<PropertyCell> cell() const { return cell_; }
bool RequiresHoleCheck() {
@@ -5391,6 +5645,15 @@ class HStoreGlobalCell: public HUnaryOperation {
DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell)
private:
+ HStoreGlobalCell(HValue* value,
+ Handle<PropertyCell> cell,
+ PropertyDetails details)
+ : HUnaryOperation(value),
+ cell_(cell),
+ details_(details) {
+ SetGVNFlag(kChangesGlobalVars);
+ }
+
Handle<PropertyCell> cell_;
PropertyDetails details_;
};
@@ -5398,18 +5661,14 @@ class HStoreGlobalCell: public HUnaryOperation {
class HStoreGlobalGeneric: public HTemplateInstruction<3> {
public:
- HStoreGlobalGeneric(HValue* context,
- HValue* global_object,
- Handle<Object> name,
- HValue* value,
- StrictModeFlag strict_mode_flag)
- : name_(name),
- strict_mode_flag_(strict_mode_flag) {
- SetOperandAt(0, context);
- SetOperandAt(1, global_object);
- SetOperandAt(2, value);
- set_representation(Representation::Tagged());
- SetAllSideEffects();
+ inline static HStoreGlobalGeneric* New(Zone* zone,
+ HValue* context,
+ HValue* global_object,
+ Handle<Object> name,
+ HValue* value,
+ StrictModeFlag strict_mode_flag) {
+ return new(zone) HStoreGlobalGeneric(context, global_object,
+ name, value, strict_mode_flag);
}
HValue* context() { return OperandAt(0); }
@@ -5427,6 +5686,20 @@ class HStoreGlobalGeneric: public HTemplateInstruction<3> {
DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric)
private:
+ HStoreGlobalGeneric(HValue* context,
+ HValue* global_object,
+ Handle<Object> name,
+ HValue* value,
+ StrictModeFlag strict_mode_flag)
+ : name_(name),
+ strict_mode_flag_(strict_mode_flag) {
+ SetOperandAt(0, context);
+ SetOperandAt(1, global_object);
+ SetOperandAt(2, value);
+ set_representation(Representation::Tagged());
+ SetAllSideEffects();
+ }
+
Handle<Object> name_;
StrictModeFlag strict_mode_flag_;
};
@@ -5514,12 +5787,8 @@ class HStoreContextSlot: public HTemplateInstruction<2> {
kCheckIgnoreAssignment
};
- HStoreContextSlot(HValue* context, int slot_index, Mode mode, HValue* value)
- : slot_index_(slot_index), mode_(mode) {
- SetOperandAt(0, context);
- SetOperandAt(1, value);
- SetGVNFlag(kChangesContextSlots);
- }
+ DECLARE_INSTRUCTION_FACTORY_P4(HStoreContextSlot, HValue*, int,
+ Mode, HValue*);
HValue* context() { return OperandAt(0); }
HValue* value() { return OperandAt(1); }
@@ -5547,6 +5816,13 @@ class HStoreContextSlot: public HTemplateInstruction<2> {
DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot)
private:
+ HStoreContextSlot(HValue* context, int slot_index, Mode mode, HValue* value)
+ : slot_index_(slot_index), mode_(mode) {
+ SetOperandAt(0, context);
+ SetOperandAt(1, value);
+ SetGVNFlag(kChangesContextSlots);
+ }
+
int slot_index_;
Mode mode_;
};
@@ -5557,7 +5833,15 @@ class HStoreContextSlot: public HTemplateInstruction<2> {
class HObjectAccess {
public:
inline bool IsInobject() const {
- return portion() != kBackingStore;
+ return portion() != kBackingStore && portion() != kExternalMemory;
+ }
+
+ inline bool IsExternalMemory() const {
+ return portion() == kExternalMemory;
+ }
+
+ inline bool IsStringLength() const {
+ return portion() == kStringLengths;
}
inline int offset() const {
@@ -5587,9 +5871,11 @@ class HObjectAccess {
static HObjectAccess ForArrayLength(ElementsKind elements_kind) {
return HObjectAccess(
- kArrayLengths, JSArray::kLengthOffset,
- IsFastElementsKind(elements_kind) && FLAG_track_fields ?
- Representation::Smi() : Representation::Tagged());
+ kArrayLengths,
+ JSArray::kLengthOffset,
+ IsFastElementsKind(elements_kind) &&
+ FLAG_track_fields
+ ? Representation::Smi() : Representation::Tagged());
}
static HObjectAccess ForAllocationSiteTransitionInfo() {
@@ -5600,11 +5886,23 @@ class HObjectAccess {
return HObjectAccess(kInobject, AllocationSite::kWeakNextOffset);
}
+ static HObjectAccess ForAllocationSiteList() {
+ return HObjectAccess(kExternalMemory, 0, Representation::Tagged());
+ }
+
static HObjectAccess ForFixedArrayLength() {
return HObjectAccess(
- kArrayLengths, FixedArray::kLengthOffset,
- FLAG_track_fields ?
- Representation::Smi() : Representation::Tagged());
+ kArrayLengths,
+ FixedArray::kLengthOffset,
+ FLAG_track_fields ? Representation::Smi() : Representation::Tagged());
+ }
+
+ static HObjectAccess ForStringLength() {
+ STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
+ return HObjectAccess(
+ kStringLengths,
+ String::kLengthOffset,
+ FLAG_track_fields ? Representation::Smi() : Representation::Tagged());
}
static HObjectAccess ForPropertiesPointer() {
@@ -5631,6 +5929,10 @@ class HObjectAccess {
return HObjectAccess(kInobject, AllocationMemento::kAllocationSiteOffset);
}
+ static HObjectAccess ForCounter() {
+ return HObjectAccess(kExternalMemory, 0, Representation::Integer32());
+ }
+
// Create an access to an offset in a fixed array header.
static HObjectAccess ForFixedArrayHeader(int offset);
@@ -5666,10 +5968,12 @@ class HObjectAccess {
enum Portion {
kMaps, // map of an object
kArrayLengths, // the length of an array
+ kStringLengths, // the length of a string
kElementsPointer, // elements pointer
kBackingStore, // some field in the backing store
kDouble, // some double field
- kInobject // some other in-object field
+ kInobject, // some other in-object field
+ kExternalMemory // some field in external memory
};
HObjectAccess(Portion portion, int offset,
@@ -5701,40 +6005,44 @@ class HObjectAccess {
};
-class HLinkObjectInList: public HUnaryOperation {
+class HLoadNamedField: public HTemplateInstruction<2> {
public:
- // There needs to be a mapping from every KnownList to an external reference
- enum KnownList {
- ALLOCATION_SITE_LIST
- };
+ DECLARE_INSTRUCTION_FACTORY_P2(HLoadNamedField, HValue*, HObjectAccess);
+ DECLARE_INSTRUCTION_FACTORY_P3(HLoadNamedField, HValue*, HObjectAccess,
+ HValue*);
- HLinkObjectInList(HValue* object, HObjectAccess store_field,
- KnownList known_list)
- : HUnaryOperation(object),
- store_field_(store_field),
- known_list_(known_list) {
- set_representation(Representation::Tagged());
+ HValue* object() { return OperandAt(0); }
+ HValue* typecheck() {
+ ASSERT(HasTypeCheck());
+ return OperandAt(1);
}
- HObjectAccess store_field() const { return store_field_; }
- KnownList known_list() const { return known_list_; }
+ bool HasTypeCheck() const { return OperandAt(0) != OperandAt(1); }
+ HObjectAccess access() const { return access_; }
+ Representation field_representation() const {
+ return access_.representation();
+ }
+ virtual bool HasEscapingOperandAt(int index) { return false; }
virtual Representation RequiredInputRepresentation(int index) {
+ if (index == 0 && access().IsExternalMemory()) {
+ // object must be external in case of external memory access
+ return Representation::External();
+ }
return Representation::Tagged();
}
-
+ virtual Range* InferRange(Zone* zone);
virtual void PrintDataTo(StringStream* stream);
- DECLARE_CONCRETE_INSTRUCTION(LinkObjectInList)
-
- private:
- HObjectAccess store_field_;
- KnownList known_list_;
-};
+ DECLARE_CONCRETE_INSTRUCTION(LoadNamedField)
+ protected:
+ virtual bool DataEquals(HValue* other) {
+ HLoadNamedField* b = HLoadNamedField::cast(other);
+ return access_.Equals(b->access_);
+ }
-class HLoadNamedField: public HTemplateInstruction<2> {
- public:
+ private:
HLoadNamedField(HValue* object,
HObjectAccess access,
HValue* typecheck = NULL)
@@ -5747,7 +6055,9 @@ class HLoadNamedField: public HTemplateInstruction<2> {
if (representation.IsSmi()) {
set_type(HType::Smi());
set_representation(representation);
- } else if (representation.IsDouble()) {
+ } else if (representation.IsDouble() ||
+ representation.IsExternal() ||
+ representation.IsInteger32()) {
set_representation(representation);
} else if (FLAG_track_heap_object_fields &&
representation.IsHeapObject()) {
@@ -5759,33 +6069,6 @@ class HLoadNamedField: public HTemplateInstruction<2> {
access.SetGVNFlags(this, false);
}
- HValue* object() { return OperandAt(0); }
- HValue* typecheck() {
- ASSERT(HasTypeCheck());
- return OperandAt(1);
- }
-
- bool HasTypeCheck() const { return OperandAt(0) != OperandAt(1); }
- HObjectAccess access() const { return access_; }
- Representation field_representation() const {
- return access_.representation();
- }
-
- virtual bool HasEscapingOperandAt(int index) { return false; }
- virtual Representation RequiredInputRepresentation(int index) {
- return Representation::Tagged();
- }
- virtual void PrintDataTo(StringStream* stream);
-
- DECLARE_CONCRETE_INSTRUCTION(LoadNamedField)
-
- protected:
- virtual bool DataEquals(HValue* other) {
- HLoadNamedField* b = HLoadNamedField::cast(other);
- return access_.Equals(b->access_);
- }
-
- private:
virtual bool IsDeletable() const { return true; }
HObjectAccess access_;
@@ -5904,55 +6187,10 @@ enum LoadKeyedHoleMode {
class HLoadKeyed
: public HTemplateInstruction<3>, public ArrayInstructionInterface {
public:
- HLoadKeyed(HValue* obj,
- HValue* key,
- HValue* dependency,
- ElementsKind elements_kind,
- LoadKeyedHoleMode mode = NEVER_RETURN_HOLE)
- : bit_field_(0) {
- bit_field_ = ElementsKindField::encode(elements_kind) |
- HoleModeField::encode(mode);
-
- SetOperandAt(0, obj);
- SetOperandAt(1, key);
- SetOperandAt(2, dependency != NULL ? dependency : obj);
-
- if (!is_external()) {
- // I can detect the case between storing double (holey and fast) and
- // smi/object by looking at elements_kind_.
- ASSERT(IsFastSmiOrObjectElementsKind(elements_kind) ||
- IsFastDoubleElementsKind(elements_kind));
-
- if (IsFastSmiOrObjectElementsKind(elements_kind)) {
- if (IsFastSmiElementsKind(elements_kind) &&
- (!IsHoleyElementsKind(elements_kind) ||
- mode == NEVER_RETURN_HOLE)) {
- set_type(HType::Smi());
- set_representation(Representation::Smi());
- } else {
- set_representation(Representation::Tagged());
- }
-
- SetGVNFlag(kDependsOnArrayElements);
- } else {
- set_representation(Representation::Double());
- SetGVNFlag(kDependsOnDoubleArrayElements);
- }
- } else {
- if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
- elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
- set_representation(Representation::Double());
- } else {
- set_representation(Representation::Integer32());
- }
-
- SetGVNFlag(kDependsOnSpecializedArrayElements);
- // Native code could change the specialized array.
- SetGVNFlag(kDependsOnCalls);
- }
-
- SetFlag(kUseGVN);
- }
+ DECLARE_INSTRUCTION_FACTORY_P4(HLoadKeyed, HValue*, HValue*, HValue*,
+ ElementsKind);
+ DECLARE_INSTRUCTION_FACTORY_P5(HLoadKeyed, HValue*, HValue*, HValue*,
+ ElementsKind, LoadKeyedHoleMode);
bool is_external() const {
return IsExternalArrayElementsKind(elements_kind());
@@ -6021,6 +6259,56 @@ class HLoadKeyed
}
private:
+ HLoadKeyed(HValue* obj,
+ HValue* key,
+ HValue* dependency,
+ ElementsKind elements_kind,
+ LoadKeyedHoleMode mode = NEVER_RETURN_HOLE)
+ : bit_field_(0) {
+ bit_field_ = ElementsKindField::encode(elements_kind) |
+ HoleModeField::encode(mode);
+
+ SetOperandAt(0, obj);
+ SetOperandAt(1, key);
+ SetOperandAt(2, dependency != NULL ? dependency : obj);
+
+ if (!is_external()) {
+ // I can detect the case between storing double (holey and fast) and
+ // smi/object by looking at elements_kind_.
+ ASSERT(IsFastSmiOrObjectElementsKind(elements_kind) ||
+ IsFastDoubleElementsKind(elements_kind));
+
+ if (IsFastSmiOrObjectElementsKind(elements_kind)) {
+ if (IsFastSmiElementsKind(elements_kind) &&
+ (!IsHoleyElementsKind(elements_kind) ||
+ mode == NEVER_RETURN_HOLE)) {
+ set_type(HType::Smi());
+ set_representation(Representation::Smi());
+ } else {
+ set_representation(Representation::Tagged());
+ }
+
+ SetGVNFlag(kDependsOnArrayElements);
+ } else {
+ set_representation(Representation::Double());
+ SetGVNFlag(kDependsOnDoubleArrayElements);
+ }
+ } else {
+ if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
+ elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
+ set_representation(Representation::Double());
+ } else {
+ set_representation(Representation::Integer32());
+ }
+
+ SetGVNFlag(kDependsOnExternalMemory);
+ // Native code could change the specialized array.
+ SetGVNFlag(kDependsOnCalls);
+ }
+
+ SetFlag(kUseGVN);
+ }
+
virtual bool IsDeletable() const {
return !RequiresHoleCheck();
}
@@ -6086,26 +6374,20 @@ class HLoadKeyedGeneric: public HTemplateInstruction<3> {
class HStoreNamedField: public HTemplateInstruction<2> {
public:
- HStoreNamedField(HValue* obj,
- HObjectAccess access,
- HValue* val)
- : access_(access),
- transition_(),
- transition_unique_id_(),
- new_space_dominator_(NULL),
- write_barrier_mode_(UPDATE_WRITE_BARRIER) {
- SetOperandAt(0, obj);
- SetOperandAt(1, val);
- access.SetGVNFlags(this, true);
- }
+ DECLARE_INSTRUCTION_FACTORY_P3(HStoreNamedField, HValue*,
+ HObjectAccess, HValue*);
DECLARE_CONCRETE_INSTRUCTION(StoreNamedField)
virtual bool HasEscapingOperandAt(int index) { return index == 1; }
virtual Representation RequiredInputRepresentation(int index) {
- if (index == 1 && field_representation().IsDouble()) {
- return field_representation();
- } else if (index == 1 && field_representation().IsSmi()) {
+ if (index == 0 && access().IsExternalMemory()) {
+ // object must be external in case of external memory access
+ return Representation::External();
+ } else if (index == 1 &&
+ (field_representation().IsDouble() ||
+ field_representation().IsSmi() ||
+ field_representation().IsInteger32())) {
return field_representation();
}
return Representation::Tagged();
@@ -6143,6 +6425,8 @@ class HStoreNamedField: public HTemplateInstruction<2> {
if (IsSkipWriteBarrier()) return false;
if (field_representation().IsDouble()) return false;
if (field_representation().IsSmi()) return false;
+ if (field_representation().IsInteger32()) return false;
+ if (field_representation().IsExternal()) return false;
return StoringValueNeedsWriteBarrier(value()) &&
ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator());
}
@@ -6161,6 +6445,19 @@ class HStoreNamedField: public HTemplateInstruction<2> {
}
private:
+ HStoreNamedField(HValue* obj,
+ HObjectAccess access,
+ HValue* val)
+ : access_(access),
+ transition_(),
+ transition_unique_id_(),
+ new_space_dominator_(NULL),
+ write_barrier_mode_(UPDATE_WRITE_BARRIER) {
+ SetOperandAt(0, obj);
+ SetOperandAt(1, val);
+ access.SetGVNFlags(this, true);
+ }
+
HObjectAccess access_;
Handle<Map> transition_;
UniqueValueId transition_unique_id_;
@@ -6207,38 +6504,8 @@ class HStoreNamedGeneric: public HTemplateInstruction<3> {
class HStoreKeyed
: public HTemplateInstruction<3>, public ArrayInstructionInterface {
public:
- HStoreKeyed(HValue* obj, HValue* key, HValue* val,
- ElementsKind elements_kind)
- : elements_kind_(elements_kind),
- index_offset_(0),
- is_dehoisted_(false),
- is_uninitialized_(false),
- new_space_dominator_(NULL) {
- SetOperandAt(0, obj);
- SetOperandAt(1, key);
- SetOperandAt(2, val);
-
- if (IsFastObjectElementsKind(elements_kind)) {
- SetFlag(kTrackSideEffectDominators);
- SetGVNFlag(kDependsOnNewSpacePromotion);
- }
- if (is_external()) {
- SetGVNFlag(kChangesSpecializedArrayElements);
- SetFlag(kAllowUndefinedAsNaN);
- } else if (IsFastDoubleElementsKind(elements_kind)) {
- SetGVNFlag(kChangesDoubleArrayElements);
- } else if (IsFastSmiElementsKind(elements_kind)) {
- SetGVNFlag(kChangesArrayElements);
- } else {
- SetGVNFlag(kChangesArrayElements);
- }
-
- // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating.
- if (elements_kind >= EXTERNAL_BYTE_ELEMENTS &&
- elements_kind <= EXTERNAL_UNSIGNED_INT_ELEMENTS) {
- SetFlag(kTruncatingToInt32);
- }
- }
+ DECLARE_INSTRUCTION_FACTORY_P4(HStoreKeyed, HValue*, HValue*, HValue*,
+ ElementsKind);
virtual bool HasEscapingOperandAt(int index) { return index != 0; }
virtual Representation RequiredInputRepresentation(int index) {
@@ -6335,6 +6602,39 @@ class HStoreKeyed
DECLARE_CONCRETE_INSTRUCTION(StoreKeyed)
private:
+ HStoreKeyed(HValue* obj, HValue* key, HValue* val,
+ ElementsKind elements_kind)
+ : elements_kind_(elements_kind),
+ index_offset_(0),
+ is_dehoisted_(false),
+ is_uninitialized_(false),
+ new_space_dominator_(NULL) {
+ SetOperandAt(0, obj);
+ SetOperandAt(1, key);
+ SetOperandAt(2, val);
+
+ if (IsFastObjectElementsKind(elements_kind)) {
+ SetFlag(kTrackSideEffectDominators);
+ SetGVNFlag(kDependsOnNewSpacePromotion);
+ }
+ if (is_external()) {
+ SetGVNFlag(kChangesExternalMemory);
+ SetFlag(kAllowUndefinedAsNaN);
+ } else if (IsFastDoubleElementsKind(elements_kind)) {
+ SetGVNFlag(kChangesDoubleArrayElements);
+ } else if (IsFastSmiElementsKind(elements_kind)) {
+ SetGVNFlag(kChangesArrayElements);
+ } else {
+ SetGVNFlag(kChangesArrayElements);
+ }
+
+ // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating.
+ if (elements_kind >= EXTERNAL_BYTE_ELEMENTS &&
+ elements_kind <= EXTERNAL_UNSIGNED_INT_ELEMENTS) {
+ SetFlag(kTruncatingToInt32);
+ }
+ }
+
ElementsKind elements_kind_;
uint32_t index_offset_;
bool is_dehoisted_ : 1;
@@ -6380,29 +6680,13 @@ class HStoreKeyedGeneric: public HTemplateInstruction<4> {
class HTransitionElementsKind: public HTemplateInstruction<2> {
public:
- HTransitionElementsKind(HValue* context,
- HValue* object,
- Handle<Map> original_map,
- Handle<Map> transitioned_map)
- : original_map_(original_map),
- transitioned_map_(transitioned_map),
- original_map_unique_id_(),
- transitioned_map_unique_id_(),
- from_kind_(original_map->elements_kind()),
- to_kind_(transitioned_map->elements_kind()) {
- SetOperandAt(0, object);
- SetOperandAt(1, context);
- SetFlag(kUseGVN);
- SetGVNFlag(kChangesElementsKind);
- if (original_map->has_fast_double_elements()) {
- SetGVNFlag(kChangesElementsPointer);
- SetGVNFlag(kChangesNewSpacePromotion);
- }
- if (transitioned_map->has_fast_double_elements()) {
- SetGVNFlag(kChangesElementsPointer);
- SetGVNFlag(kChangesNewSpacePromotion);
- }
- set_representation(Representation::Tagged());
+ inline static HTransitionElementsKind* New(Zone* zone,
+ HValue* context,
+ HValue* object,
+ Handle<Map> original_map,
+ Handle<Map> transitioned_map) {
+ return new(zone) HTransitionElementsKind(context, object,
+ original_map, transitioned_map);
}
virtual Representation RequiredInputRepresentation(int index) {
@@ -6433,6 +6717,31 @@ class HTransitionElementsKind: public HTemplateInstruction<2> {
}
private:
+ HTransitionElementsKind(HValue* context,
+ HValue* object,
+ Handle<Map> original_map,
+ Handle<Map> transitioned_map)
+ : original_map_(original_map),
+ transitioned_map_(transitioned_map),
+ original_map_unique_id_(),
+ transitioned_map_unique_id_(),
+ from_kind_(original_map->elements_kind()),
+ to_kind_(transitioned_map->elements_kind()) {
+ SetOperandAt(0, object);
+ SetOperandAt(1, context);
+ SetFlag(kUseGVN);
+ SetGVNFlag(kChangesElementsKind);
+ if (original_map->has_fast_double_elements()) {
+ SetGVNFlag(kChangesElementsPointer);
+ SetGVNFlag(kChangesNewSpacePromotion);
+ }
+ if (transitioned_map->has_fast_double_elements()) {
+ SetGVNFlag(kChangesElementsPointer);
+ SetGVNFlag(kChangesNewSpacePromotion);
+ }
+ set_representation(Representation::Tagged());
+ }
+
Handle<Map> original_map_;
Handle<Map> transitioned_map_;
UniqueValueId original_map_unique_id_;
@@ -6456,10 +6765,6 @@ class HStringAdd: public HBinaryOperation {
return Representation::Tagged();
}
- virtual HType CalculateInferredType() {
- return HType::String();
- }
-
DECLARE_CONCRETE_INSTRUCTION(StringAdd)
protected:
@@ -6467,15 +6772,16 @@ class HStringAdd: public HBinaryOperation {
private:
HStringAdd(HValue* context, HValue* left, HValue* right, StringAddFlags flags)
- : HBinaryOperation(context, left, right), flags_(flags) {
+ : HBinaryOperation(context, left, right, HType::String()), flags_(flags) {
set_representation(Representation::Tagged());
SetFlag(kUseGVN);
SetGVNFlag(kDependsOnMaps);
SetGVNFlag(kChangesNewSpacePromotion);
}
- // TODO(svenpanne) Might be safe, but leave it out until we know for sure.
- // virtual bool IsDeletable() const { return true; }
+ // No side-effects except possible allocation.
+ // NOTE: this instruction _does not_ call ToString() on its inputs.
+ virtual bool IsDeletable() const { return true; }
const StringAddFlags flags_;
};
@@ -6483,14 +6789,11 @@ class HStringAdd: public HBinaryOperation {
class HStringCharCodeAt: public HTemplateInstruction<3> {
public:
- HStringCharCodeAt(HValue* context, HValue* string, HValue* index) {
- SetOperandAt(0, context);
- SetOperandAt(1, string);
- SetOperandAt(2, index);
- set_representation(Representation::Integer32());
- SetFlag(kUseGVN);
- SetGVNFlag(kDependsOnMaps);
- SetGVNFlag(kChangesNewSpacePromotion);
+ static HStringCharCodeAt* New(Zone* zone,
+ HValue* context,
+ HValue* string,
+ HValue* index) {
+ return new(zone) HStringCharCodeAt(context, string, index);
}
virtual Representation RequiredInputRepresentation(int index) {
@@ -6500,9 +6803,9 @@ class HStringCharCodeAt: public HTemplateInstruction<3> {
: Representation::Tagged();
}
- HValue* context() { return OperandAt(0); }
- HValue* string() { return OperandAt(1); }
- HValue* index() { return OperandAt(2); }
+ HValue* context() const { return OperandAt(0); }
+ HValue* string() const { return OperandAt(1); }
+ HValue* index() const { return OperandAt(2); }
DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt)
@@ -6513,9 +6816,19 @@ class HStringCharCodeAt: public HTemplateInstruction<3> {
return new(zone) Range(0, String::kMaxUtf16CodeUnit);
}
- // TODO(svenpanne) Might be safe, but leave it out until we know for sure.
- // private:
- // virtual bool IsDeletable() const { return true; }
+ private:
+ HStringCharCodeAt(HValue* context, HValue* string, HValue* index) {
+ SetOperandAt(0, context);
+ SetOperandAt(1, string);
+ SetOperandAt(2, index);
+ set_representation(Representation::Integer32());
+ SetFlag(kUseGVN);
+ SetGVNFlag(kDependsOnMaps);
+ SetGVNFlag(kChangesNewSpacePromotion);
+ }
+
+ // No side effects: runtime function assumes string + number inputs.
+ virtual bool IsDeletable() const { return true; }
};
@@ -6530,17 +6843,17 @@ class HStringCharFromCode: public HTemplateInstruction<2> {
? Representation::Tagged()
: Representation::Integer32();
}
- virtual HType CalculateInferredType();
- HValue* context() { return OperandAt(0); }
- HValue* value() { return OperandAt(1); }
+ HValue* context() const { return OperandAt(0); }
+ HValue* value() const { return OperandAt(1); }
virtual bool DataEquals(HValue* other) { return true; }
DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode)
private:
- HStringCharFromCode(HValue* context, HValue* char_code) {
+ HStringCharFromCode(HValue* context, HValue* char_code)
+ : HTemplateInstruction<2>(HType::String()) {
SetOperandAt(0, context);
SetOperandAt(1, char_code);
set_representation(Representation::Tagged());
@@ -6548,41 +6861,9 @@ class HStringCharFromCode: public HTemplateInstruction<2> {
SetGVNFlag(kChangesNewSpacePromotion);
}
- // TODO(svenpanne) Might be safe, but leave it out until we know for sure.
- // virtual bool IsDeletable() const { return true; }
-};
-
-
-class HStringLength: public HUnaryOperation {
- public:
- static HInstruction* New(Zone* zone, HValue* string);
-
- virtual Representation RequiredInputRepresentation(int index) {
- return Representation::Tagged();
- }
-
- virtual HType CalculateInferredType() {
- STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
- return HType::Smi();
- }
-
- DECLARE_CONCRETE_INSTRUCTION(StringLength)
-
- protected:
- virtual bool DataEquals(HValue* other) { return true; }
-
- virtual Range* InferRange(Zone* zone) {
- return new(zone) Range(0, String::kMaxLength);
- }
-
- private:
- explicit HStringLength(HValue* string) : HUnaryOperation(string) {
- set_representation(Representation::Tagged());
- SetFlag(kUseGVN);
- SetGVNFlag(kDependsOnMaps);
+ virtual bool IsDeletable() const {
+ return !value()->ToNumberCanBeObserved();
}
-
- virtual bool IsDeletable() const { return true; }
};
@@ -6628,6 +6909,7 @@ class HRegExpLiteral: public HMaterializedLiteral<1> {
flags_(flags) {
SetOperandAt(0, context);
SetAllSideEffects();
+ set_type(HType::JSObject());
}
HValue* context() { return OperandAt(0); }
@@ -6638,7 +6920,6 @@ class HRegExpLiteral: public HMaterializedLiteral<1> {
virtual Representation RequiredInputRepresentation(int index) {
return Representation::Tagged();
}
- virtual HType CalculateInferredType();
DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral)
@@ -6654,7 +6935,8 @@ class HFunctionLiteral: public HTemplateInstruction<1> {
HFunctionLiteral(HValue* context,
Handle<SharedFunctionInfo> shared,
bool pretenure)
- : shared_info_(shared),
+ : HTemplateInstruction<1>(HType::JSObject()),
+ shared_info_(shared),
pretenure_(pretenure),
has_no_literals_(shared->num_literals() == 0),
is_generator_(shared->is_generator()),
@@ -6669,7 +6951,6 @@ class HFunctionLiteral: public HTemplateInstruction<1> {
virtual Representation RequiredInputRepresentation(int index) {
return Representation::Tagged();
}
- virtual HType CalculateInferredType();
DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral)
@@ -6716,9 +6997,7 @@ class HTypeof: public HTemplateInstruction<2> {
class HTrapAllocationMemento : public HTemplateInstruction<1> {
public:
- explicit HTrapAllocationMemento(HValue* obj) {
- SetOperandAt(0, obj);
- }
+ DECLARE_INSTRUCTION_FACTORY_P1(HTrapAllocationMemento, HValue*);
virtual Representation RequiredInputRepresentation(int index) {
return Representation::Tagged();
@@ -6727,11 +7006,25 @@ class HTrapAllocationMemento : public HTemplateInstruction<1> {
HValue* object() { return OperandAt(0); }
DECLARE_CONCRETE_INSTRUCTION(TrapAllocationMemento)
+
+ private:
+ explicit HTrapAllocationMemento(HValue* obj) {
+ SetOperandAt(0, obj);
+ }
};
class HToFastProperties: public HUnaryOperation {
public:
+ DECLARE_INSTRUCTION_FACTORY_P1(HToFastProperties, HValue*);
+
+ virtual Representation RequiredInputRepresentation(int index) {
+ return Representation::Tagged();
+ }
+
+ DECLARE_CONCRETE_INSTRUCTION(ToFastProperties)
+
+ private:
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
@@ -6745,13 +7038,6 @@ class HToFastProperties: public HUnaryOperation {
set_representation(Representation::Tagged());
}
- virtual Representation RequiredInputRepresentation(int index) {
- return Representation::Tagged();
- }
-
- DECLARE_CONCRETE_INSTRUCTION(ToFastProperties)
-
- private:
virtual bool IsDeletable() const { return true; }
};
@@ -6824,15 +7110,7 @@ class HSeqStringSetChar: public HTemplateInstruction<3> {
class HCheckMapValue: public HTemplateInstruction<2> {
public:
- HCheckMapValue(HValue* value,
- HValue* map) {
- SetOperandAt(0, value);
- SetOperandAt(1, map);
- set_representation(Representation::Tagged());
- SetFlag(kUseGVN);
- SetGVNFlag(kDependsOnMaps);
- SetGVNFlag(kDependsOnElementsKind);
- }
+ DECLARE_INSTRUCTION_FACTORY_P2(HCheckMapValue, HValue*, HValue*);
virtual Representation RequiredInputRepresentation(int index) {
return Representation::Tagged();
@@ -6853,17 +7131,26 @@ class HCheckMapValue: public HTemplateInstruction<2> {
virtual bool DataEquals(HValue* other) {
return true;
}
+
+ private:
+ HCheckMapValue(HValue* value,
+ HValue* map) {
+ SetOperandAt(0, value);
+ SetOperandAt(1, map);
+ set_representation(Representation::Tagged());
+ SetFlag(kUseGVN);
+ SetGVNFlag(kDependsOnMaps);
+ SetGVNFlag(kDependsOnElementsKind);
+ }
};
class HForInPrepareMap : public HTemplateInstruction<2> {
public:
- HForInPrepareMap(HValue* context,
- HValue* object) {
- SetOperandAt(0, context);
- SetOperandAt(1, object);
- set_representation(Representation::Tagged());
- SetAllSideEffects();
+ static HForInPrepareMap* New(Zone* zone,
+ HValue* context,
+ HValue* object) {
+ return new(zone) HForInPrepareMap(context, object);
}
virtual Representation RequiredInputRepresentation(int index) {
@@ -6880,18 +7167,21 @@ class HForInPrepareMap : public HTemplateInstruction<2> {
}
DECLARE_CONCRETE_INSTRUCTION(ForInPrepareMap);
+
+ private:
+ HForInPrepareMap(HValue* context,
+ HValue* object) {
+ SetOperandAt(0, context);
+ SetOperandAt(1, object);
+ set_representation(Representation::Tagged());
+ SetAllSideEffects();
+ }
};
class HForInCacheArray : public HTemplateInstruction<2> {
public:
- HForInCacheArray(HValue* enumerable,
- HValue* keys,
- int idx) : idx_(idx) {
- SetOperandAt(0, enumerable);
- SetOperandAt(1, keys);
- set_representation(Representation::Tagged());
- }
+ DECLARE_INSTRUCTION_FACTORY_P3(HForInCacheArray, HValue*, HValue*, int);
virtual Representation RequiredInputRepresentation(int index) {
return Representation::Tagged();
@@ -6918,6 +7208,14 @@ class HForInCacheArray : public HTemplateInstruction<2> {
DECLARE_CONCRETE_INSTRUCTION(ForInCacheArray);
private:
+ HForInCacheArray(HValue* enumerable,
+ HValue* keys,
+ int idx) : idx_(idx) {
+ SetOperandAt(0, enumerable);
+ SetOperandAt(1, keys);
+ set_representation(Representation::Tagged());
+ }
+
int idx_;
HForInCacheArray* index_cache_;
};
« no previous file with comments | « src/hydrogen-bch.cc ('k') | src/hydrogen-instructions.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698