| Index: src/hydrogen-instructions.h
|
| diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
|
| index 53f1b65755beaa3cbaa3ada0086830d60529bc27..3e53eca7092293b0d2c5a41766db8d8c50ec60fc 100644
|
| --- a/src/hydrogen-instructions.h
|
| +++ b/src/hydrogen-instructions.h
|
| @@ -92,6 +92,7 @@ class LChunkBuilder;
|
| V(CheckNonSmi) \
|
| V(CheckPrototypeMaps) \
|
| V(CheckSmi) \
|
| + V(CheckSmiOrInt32) \
|
| V(ClampToUint8) \
|
| V(ClassOfTestAndBranch) \
|
| V(CompareIDAndBranch) \
|
| @@ -2612,6 +2613,34 @@ class HCheckSmi: public HUnaryOperation {
|
| };
|
|
|
|
|
| +class HCheckSmiOrInt32: public HUnaryOperation {
|
| + public:
|
| + explicit HCheckSmiOrInt32(HValue* value) : HUnaryOperation(value) {
|
| + SetFlag(kFlexibleRepresentation);
|
| + SetFlag(kUseGVN);
|
| + }
|
| +
|
| + virtual int RedefinedOperandIndex() { return 0; }
|
| + virtual Representation RequiredInputRepresentation(int index) {
|
| + return representation();
|
| + }
|
| + virtual void InferRepresentation(HInferRepresentation* h_infer);
|
| +
|
| + virtual HValue* Canonicalize() {
|
| + if (representation().IsTagged() && !type().IsSmi()) {
|
| + return this;
|
| + } else {
|
| + return value();
|
| + }
|
| + }
|
| +
|
| + DECLARE_CONCRETE_INSTRUCTION(CheckSmiOrInt32)
|
| +
|
| + protected:
|
| + virtual bool DataEquals(HValue* other) { return true; }
|
| +};
|
| +
|
| +
|
| class HPhi: public HValue {
|
| public:
|
| HPhi(int merged_index, Zone* zone)
|
| @@ -2807,6 +2836,9 @@ class HConstant: public HTemplateInstruction<0> {
|
| ASSERT(HasInteger32Value());
|
| return int32_value_;
|
| }
|
| + bool HasSmiValue() const {
|
| + return HasInteger32Value() && Smi::IsValid(Integer32Value());
|
| + }
|
| bool HasDoubleValue() const { return has_double_value_; }
|
| double DoubleValue() const {
|
| ASSERT(HasDoubleValue());
|
| @@ -3088,15 +3120,21 @@ enum BoundsCheckKeyMode {
|
|
|
| class HBoundsCheck: public HTemplateInstruction<2> {
|
| public:
|
| - HBoundsCheck(HValue* index, HValue* length,
|
| + // Normally HBoundsCheck should be created using the
|
| + // HGraphBuilder::AddBoundsCheck() helper, which also guards the index with
|
| + // a HCheckSmiOrInt32 check.
|
| + // 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,
|
| BoundsCheckKeyMode key_mode = DONT_ALLOW_SMI_KEY,
|
| Representation r = Representation::None())
|
| - : key_mode_(key_mode) {
|
| + : key_mode_(key_mode), skip_check_(false) {
|
| SetOperandAt(0, index);
|
| SetOperandAt(1, length);
|
| if (r.IsNone()) {
|
| // In the normal compilation pipeline the representation is flexible
|
| - // (see comment to RequiredInputRepresentation).
|
| + // (see InferRepresentation).
|
| SetFlag(kFlexibleRepresentation);
|
| } else {
|
| // When compiling stubs we want to set the representation explicitly
|
| @@ -3106,6 +3144,9 @@ class HBoundsCheck: public HTemplateInstruction<2> {
|
| SetFlag(kUseGVN);
|
| }
|
|
|
| + bool skip_check() { return skip_check_; }
|
| + void set_skip_check(bool skip_check) { skip_check_ = skip_check; }
|
| +
|
| virtual Representation RequiredInputRepresentation(int arg_index) {
|
| return representation();
|
| }
|
| @@ -3126,6 +3167,7 @@ class HBoundsCheck: public HTemplateInstruction<2> {
|
| protected:
|
| virtual bool DataEquals(HValue* other) { return true; }
|
| BoundsCheckKeyMode key_mode_;
|
| + bool skip_check_;
|
| };
|
|
|
|
|
|
|