From 632f591884913a257e3db667f010009f7c436103 Mon Sep 17 00:00:00 2001 From: "verwaest@chromium.org" Date: Thu, 23 May 2013 14:38:39 +0000 Subject: [PATCH] Tag length of FixedArrayBase and smi-array[x] as smi representation R=jkummerow@chromium.org Review URL: https://chromiumcodereview.appspot.com/15858006 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14778 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/arm/lithium-arm.cc | 10 ++++++++-- src/arm/lithium-arm.h | 15 ++++++++++++++- src/arm/lithium-codegen-arm.cc | 7 +++++++ src/hydrogen-instructions.h | 6 ++++-- src/ia32/lithium-codegen-ia32.cc | 7 +++++++ src/ia32/lithium-ia32.cc | 17 ++++++++++++----- src/ia32/lithium-ia32.h | 15 ++++++++++++++- src/x64/lithium-codegen-x64.cc | 7 +++++++ src/x64/lithium-x64.cc | 14 ++++++++++---- src/x64/lithium-x64.h | 15 ++++++++++++++- 10 files changed, 97 insertions(+), 16 deletions(-) diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc index 57d7525..9ed5329 100644 --- a/src/arm/lithium-arm.cc +++ b/src/arm/lithium-arm.cc @@ -1890,6 +1890,12 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) { if (from.IsSmi()) { if (to.IsTagged()) { LOperand* value = UseRegister(instr->value()); + // For now, always deopt on hole. + if (instr->value()->IsLoadKeyed() && + HLoadKeyed::cast(instr->value())->UsesMustHandleHole()) { + return AssignEnvironment( + DefineSameAsFirst(new(zone()) LCheckSmiAndReturn(value))); + } return DefineSameAsFirst(new(zone()) LDummyUse(value)); } from = Representation::Tagged(); @@ -1902,9 +1908,9 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) { return AssignEnvironment(DefineAsRegister(res)); } else if (to.IsSmi()) { HValue* val = instr->value(); - LOperand* value = UseRegisterAtStart(val); + LOperand* value = UseRegister(val); return AssignEnvironment( - DefineSameAsFirst(new(zone()) LCheckSmi(value))); + DefineSameAsFirst(new(zone()) LCheckSmiAndReturn(value))); } else { ASSERT(to.IsInteger32()); LOperand* value = NULL; diff --git a/src/arm/lithium-arm.h b/src/arm/lithium-arm.h index 68e8748..0d01bfd 100644 --- a/src/arm/lithium-arm.h +++ b/src/arm/lithium-arm.h @@ -76,6 +76,7 @@ class LCodeGen; V(CheckMaps) \ V(CheckPrototypeMaps) \ V(CheckSmi) \ + V(CheckSmiAndReturn) \ V(ClampDToUint8) \ V(ClampIToUint8) \ V(ClampTToUint8) \ @@ -2387,7 +2388,7 @@ class LCheckPrototypeMaps: public LTemplateInstruction<0, 0, 2> { }; -class LCheckSmi: public LTemplateInstruction<1, 1, 0> { +class LCheckSmi: public LTemplateInstruction<0, 1, 0> { public: explicit LCheckSmi(LOperand* value) { inputs_[0] = value; @@ -2399,6 +2400,18 @@ class LCheckSmi: public LTemplateInstruction<1, 1, 0> { }; +class LCheckSmiAndReturn: public LTemplateInstruction<1, 1, 0> { + public: + explicit LCheckSmiAndReturn(LOperand* value) { + inputs_[0] = value; + } + + LOperand* value() { return inputs_[0]; } + + DECLARE_CONCRETE_INSTRUCTION(CheckSmiAndReturn, "check-smi-and-return") +}; + + class LCheckNonSmi: public LTemplateInstruction<0, 1, 0> { public: explicit LCheckNonSmi(LOperand* value) { diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc index c57baea..04661d3 100644 --- a/src/arm/lithium-codegen-arm.cc +++ b/src/arm/lithium-codegen-arm.cc @@ -5224,6 +5224,13 @@ void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) { } +void LCodeGen::DoCheckSmiAndReturn(LCheckSmiAndReturn* instr) { + LOperand* input = instr->value(); + __ SmiTst(ToRegister(input)); + DeoptimizeIf(ne, instr->environment()); +} + + void LCodeGen::DoCheckSmi(LCheckSmi* instr) { LOperand* input = instr->value(); __ SmiTst(ToRegister(input)); diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h index 5a103e4..bf05619 100644 --- a/src/hydrogen-instructions.h +++ b/src/hydrogen-instructions.h @@ -2422,7 +2422,7 @@ class HFixedArrayBaseLength: public HUnaryOperation { public: explicit HFixedArrayBaseLength(HValue* value) : HUnaryOperation(value) { set_type(HType::Smi()); - set_representation(Representation::Tagged()); + set_representation(Representation::Smi()); SetFlag(kUseGVN); SetGVNFlag(kDependsOnArrayLengths); } @@ -5419,9 +5419,11 @@ class HLoadKeyed if (IsFastSmiOrObjectElementsKind(elements_kind)) { if (IsFastSmiElementsKind(elements_kind)) { set_type(HType::Smi()); + set_representation(Representation::Smi()); + } else { + set_representation(Representation::Tagged()); } - set_representation(Representation::Tagged()); SetGVNFlag(kDependsOnArrayElements); } else { set_representation(Representation::Double()); diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc index cade3e6..26e7103 100644 --- a/src/ia32/lithium-codegen-ia32.cc +++ b/src/ia32/lithium-codegen-ia32.cc @@ -5698,6 +5698,13 @@ void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) { } +void LCodeGen::DoCheckSmiAndReturn(LCheckSmiAndReturn* instr) { + LOperand* input = instr->value(); + __ test(ToOperand(input), Immediate(kSmiTagMask)); + DeoptimizeIf(not_zero, instr->environment()); +} + + void LCodeGen::DoCheckSmi(LCheckSmi* instr) { LOperand* input = instr->value(); __ test(ToOperand(input), Immediate(kSmiTagMask)); diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc index 3e6931c..a56a2d4 100644 --- a/src/ia32/lithium-ia32.cc +++ b/src/ia32/lithium-ia32.cc @@ -1910,7 +1910,14 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) { if (from.IsSmi()) { if (to.IsTagged()) { LOperand* value = UseRegister(instr->value()); - return DefineSameAsFirst(new(zone()) LDummyUse(value)); + // For now, always deopt on hole. + if (instr->value()->IsLoadKeyed() && + HLoadKeyed::cast(instr->value())->UsesMustHandleHole()) { + return AssignEnvironment( + DefineSameAsFirst(new(zone()) LCheckSmiAndReturn(value))); + } else { + return DefineSameAsFirst(new(zone()) LDummyUse(value)); + } } from = Representation::Tagged(); } @@ -1933,9 +1940,9 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) { } } else if (to.IsSmi()) { HValue* val = instr->value(); - LOperand* value = UseRegisterAtStart(val); + LOperand* value = UseRegister(val); return AssignEnvironment( - DefineSameAsFirst(new(zone()) LCheckSmi(value))); + DefineSameAsFirst(new(zone()) LCheckSmiAndReturn(value))); } else { ASSERT(to.IsInteger32()); if (instr->value()->type().IsSmi()) { @@ -2058,13 +2065,13 @@ LInstruction* LChunkBuilder::DoCheckPrototypeMaps(HCheckPrototypeMaps* instr) { LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) { LOperand* value = UseAtStart(instr->value()); - return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value))); + return AssignEnvironment(new(zone()) LCheckSmi(value)); } LInstruction* LChunkBuilder::DoCheckSmiOrInt32(HCheckSmiOrInt32* instr) { LOperand* value = UseAtStart(instr->value()); - return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value))); + return AssignEnvironment(new(zone()) LCheckSmi(value)); } diff --git a/src/ia32/lithium-ia32.h b/src/ia32/lithium-ia32.h index e10bee5..47d8601 100644 --- a/src/ia32/lithium-ia32.h +++ b/src/ia32/lithium-ia32.h @@ -70,6 +70,7 @@ class LCodeGen; V(CheckNonSmi) \ V(CheckPrototypeMaps) \ V(CheckSmi) \ + V(CheckSmiAndReturn) \ V(ClampDToUint8) \ V(ClampIToUint8) \ V(ClampTToUint8) \ @@ -2461,7 +2462,7 @@ class LCheckPrototypeMaps: public LTemplateInstruction<0, 0, 1> { }; -class LCheckSmi: public LTemplateInstruction<1, 1, 0> { +class LCheckSmi: public LTemplateInstruction<0, 1, 0> { public: explicit LCheckSmi(LOperand* value) { inputs_[0] = value; @@ -2473,6 +2474,18 @@ class LCheckSmi: public LTemplateInstruction<1, 1, 0> { }; +class LCheckSmiAndReturn: public LTemplateInstruction<1, 1, 0> { + public: + explicit LCheckSmiAndReturn(LOperand* value) { + inputs_[0] = value; + } + + LOperand* value() { return inputs_[0]; } + + DECLARE_CONCRETE_INSTRUCTION(CheckSmiAndReturn, "check-smi-and-return") +}; + + class LClampDToUint8: public LTemplateInstruction<1, 1, 0> { public: explicit LClampDToUint8(LOperand* value) { diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc index 7ea3f9c..109c25a 100644 --- a/src/x64/lithium-codegen-x64.cc +++ b/src/x64/lithium-codegen-x64.cc @@ -4913,6 +4913,13 @@ void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) { } +void LCodeGen::DoCheckSmiAndReturn(LCheckSmiAndReturn* instr) { + LOperand* input = instr->value(); + Condition cc = masm()->CheckSmi(ToRegister(input)); + DeoptimizeIf(NegateCondition(cc), instr->environment()); +} + + void LCodeGen::DoCheckSmi(LCheckSmi* instr) { LOperand* input = instr->value(); Condition cc = masm()->CheckSmi(ToRegister(input)); diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc index 135c4cf..5184572 100644 --- a/src/x64/lithium-x64.cc +++ b/src/x64/lithium-x64.cc @@ -1815,6 +1815,12 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) { if (from.IsSmi()) { if (to.IsTagged()) { LOperand* value = UseRegister(instr->value()); + // For now, always deopt on hole. + if (instr->value()->IsLoadKeyed() && + HLoadKeyed::cast(instr->value())->UsesMustHandleHole()) { + return AssignEnvironment( + DefineSameAsFirst(new(zone()) LCheckSmiAndReturn(value))); + } return DefineSameAsFirst(new(zone()) LDummyUse(value)); } from = Representation::Tagged(); @@ -1830,9 +1836,9 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) { return AssignEnvironment(DefineAsRegister(res)); } else if (to.IsSmi()) { HValue* val = instr->value(); - LOperand* value = UseRegisterAtStart(val); + LOperand* value = UseRegister(val); return AssignEnvironment( - DefineSameAsFirst(new(zone()) LCheckSmi(value))); + DefineSameAsFirst(new(zone()) LCheckSmiAndReturn(value))); } else { ASSERT(to.IsInteger32()); LOperand* value = UseRegister(instr->value()); @@ -1937,13 +1943,13 @@ LInstruction* LChunkBuilder::DoCheckPrototypeMaps(HCheckPrototypeMaps* instr) { LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) { LOperand* value = UseRegisterAtStart(instr->value()); - return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value))); + return AssignEnvironment(new(zone()) LCheckSmi(value)); } LInstruction* LChunkBuilder::DoCheckSmiOrInt32(HCheckSmiOrInt32* instr) { LOperand* value = UseRegisterAtStart(instr->value()); - return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value))); + return AssignEnvironment(new(zone()) LCheckSmi(value)); } diff --git a/src/x64/lithium-x64.h b/src/x64/lithium-x64.h index 18f64f8..920ea0c 100644 --- a/src/x64/lithium-x64.h +++ b/src/x64/lithium-x64.h @@ -76,6 +76,7 @@ class LCodeGen; V(CheckNonSmi) \ V(CheckPrototypeMaps) \ V(CheckSmi) \ + V(CheckSmiAndReturn) \ V(ClampDToUint8) \ V(ClampIToUint8) \ V(ClampTToUint8) \ @@ -2294,7 +2295,7 @@ class LCheckPrototypeMaps: public LTemplateInstruction<0, 0, 1> { }; -class LCheckSmi: public LTemplateInstruction<1, 1, 0> { +class LCheckSmi: public LTemplateInstruction<0, 1, 0> { public: explicit LCheckSmi(LOperand* value) { inputs_[0] = value; @@ -2306,6 +2307,18 @@ class LCheckSmi: public LTemplateInstruction<1, 1, 0> { }; +class LCheckSmiAndReturn: public LTemplateInstruction<1, 1, 0> { + public: + explicit LCheckSmiAndReturn(LOperand* value) { + inputs_[0] = value; + } + + LOperand* value() { return inputs_[0]; } + + DECLARE_CONCRETE_INSTRUCTION(CheckSmiAndReturn, "check-smi-and-return") +}; + + class LClampDToUint8: public LTemplateInstruction<1, 1, 0> { public: explicit LClampDToUint8(LOperand* unclamped) { -- 2.7.4