Use immediates when possible for HBoundsCheck and HLoadKeyedFastElement

Review URL: http://codereview.chromium.org/7608020

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@8943 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 7d17c8d5
...@@ -2259,16 +2259,13 @@ void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { ...@@ -2259,16 +2259,13 @@ void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) { void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) {
Register elements = ToRegister(instr->elements());
Register key = ToRegister(instr->key());
Register result = ToRegister(instr->result()); Register result = ToRegister(instr->result());
ASSERT(result.is(elements));
// Load the result. // Load the result.
__ mov(result, FieldOperand(elements, __ mov(result,
key, BuildFastArrayOperand(instr->elements(), instr->key(),
times_pointer_size, JSObject::FAST_ELEMENTS,
FixedArray::kHeaderSize)); FixedArray::kHeaderSize - kHeapObjectTag));
// Check for the hole value. // Check for the hole value.
if (instr->hydrogen()->RequiresHoleCheck()) { if (instr->hydrogen()->RequiresHoleCheck()) {
...@@ -2301,22 +2298,22 @@ void LCodeGen::DoLoadKeyedFastDoubleElement( ...@@ -2301,22 +2298,22 @@ void LCodeGen::DoLoadKeyedFastDoubleElement(
Operand LCodeGen::BuildFastArrayOperand( Operand LCodeGen::BuildFastArrayOperand(
LOperand* external_pointer, LOperand* elements_pointer,
LOperand* key, LOperand* key,
JSObject::ElementsKind elements_kind, JSObject::ElementsKind elements_kind,
uint32_t offset) { uint32_t offset) {
Register external_pointer_reg = ToRegister(external_pointer); Register elements_pointer_reg = ToRegister(elements_pointer);
int shift_size = ElementsKindToShiftSize(elements_kind); int shift_size = ElementsKindToShiftSize(elements_kind);
if (key->IsConstantOperand()) { if (key->IsConstantOperand()) {
int constant_value = ToInteger32(LConstantOperand::cast(key)); int constant_value = ToInteger32(LConstantOperand::cast(key));
if (constant_value & 0xF0000000) { if (constant_value & 0xF0000000) {
Abort("array index constant value too big"); Abort("array index constant value too big");
} }
return Operand(external_pointer_reg, return Operand(elements_pointer_reg,
constant_value * (1 << shift_size) + offset); constant_value * (1 << shift_size) + offset);
} else { } else {
ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size); ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size);
return Operand(external_pointer_reg, ToRegister(key), scale_factor, offset); return Operand(elements_pointer_reg, ToRegister(key), scale_factor, offset);
} }
} }
...@@ -3093,8 +3090,14 @@ void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { ...@@ -3093,8 +3090,14 @@ void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {
void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
__ cmp(ToRegister(instr->index()), ToOperand(instr->length())); if (instr->index()->IsConstantOperand()) {
DeoptimizeIf(above_equal, instr->environment()); __ cmp(ToOperand(instr->length()),
ToImmediate(LConstantOperand::cast(instr->index())));
DeoptimizeIf(below_equal, instr->environment());
} else {
__ cmp(ToRegister(instr->index()), ToOperand(instr->length()));
DeoptimizeIf(above_equal, instr->environment());
}
} }
......
...@@ -222,7 +222,7 @@ class LCodeGen BASE_EMBEDDED { ...@@ -222,7 +222,7 @@ class LCodeGen BASE_EMBEDDED {
Register ToRegister(int index) const; Register ToRegister(int index) const;
XMMRegister ToDoubleRegister(int index) const; XMMRegister ToDoubleRegister(int index) const;
int ToInteger32(LConstantOperand* op) const; int ToInteger32(LConstantOperand* op) const;
Operand BuildFastArrayOperand(LOperand* external_pointer, Operand BuildFastArrayOperand(LOperand* elements_pointer,
LOperand* key, LOperand* key,
JSObject::ElementsKind elements_kind, JSObject::ElementsKind elements_kind,
uint32_t offset); uint32_t offset);
......
...@@ -1559,8 +1559,9 @@ LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) { ...@@ -1559,8 +1559,9 @@ LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) {
LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) { LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) {
return AssignEnvironment(new LBoundsCheck(UseRegisterAtStart(instr->index()), return AssignEnvironment(new LBoundsCheck(
UseAtStart(instr->length()))); UseRegisterOrConstantAtStart(instr->index()),
UseAtStart(instr->length())));
} }
...@@ -1881,9 +1882,9 @@ LInstruction* LChunkBuilder::DoLoadKeyedFastElement( ...@@ -1881,9 +1882,9 @@ LInstruction* LChunkBuilder::DoLoadKeyedFastElement(
ASSERT(instr->representation().IsTagged()); ASSERT(instr->representation().IsTagged());
ASSERT(instr->key()->representation().IsInteger32()); ASSERT(instr->key()->representation().IsInteger32());
LOperand* obj = UseRegisterAtStart(instr->object()); LOperand* obj = UseRegisterAtStart(instr->object());
LOperand* key = UseRegisterAtStart(instr->key()); LOperand* key = UseRegisterOrConstantAtStart(instr->key());
LLoadKeyedFastElement* result = new LLoadKeyedFastElement(obj, key); LLoadKeyedFastElement* result = new LLoadKeyedFastElement(obj, key);
return AssignEnvironment(DefineSameAsFirst(result)); return AssignEnvironment(DefineAsRegister(result));
} }
......
...@@ -2237,14 +2237,18 @@ class LChunkBuilder BASE_EMBEDDED { ...@@ -2237,14 +2237,18 @@ class LChunkBuilder BASE_EMBEDDED {
template<int I, int T> template<int I, int T>
LInstruction* DefineFixedDouble(LTemplateInstruction<1, I, T>* instr, LInstruction* DefineFixedDouble(LTemplateInstruction<1, I, T>* instr,
XMMRegister reg); XMMRegister reg);
// Assigns an environment to an instruction. An instruction which can
// deoptimize must have an environment.
LInstruction* AssignEnvironment(LInstruction* instr); LInstruction* AssignEnvironment(LInstruction* instr);
// Assigns a pointer map to an instruction. An instruction which can
// trigger a GC or a lazy deoptimization must have a pointer map.
LInstruction* AssignPointerMap(LInstruction* instr); LInstruction* AssignPointerMap(LInstruction* instr);
enum CanDeoptimize { CAN_DEOPTIMIZE_EAGERLY, CANNOT_DEOPTIMIZE_EAGERLY }; enum CanDeoptimize { CAN_DEOPTIMIZE_EAGERLY, CANNOT_DEOPTIMIZE_EAGERLY };
// By default we assume that instruction sequences generated for calls // Marks a call for the register allocator. Assigns a pointer map to
// cannot deoptimize eagerly and we do not attach environment to this // support GC and lazy deoptimization. Assigns an environment to support
// instruction. // eager deoptimization if CAN_DEOPTIMIZE_EAGERLY.
LInstruction* MarkAsCall( LInstruction* MarkAsCall(
LInstruction* instr, LInstruction* instr,
HInstruction* hinstr, HInstruction* hinstr,
......
...@@ -2262,16 +2262,13 @@ void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { ...@@ -2262,16 +2262,13 @@ void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) { void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) {
Register elements = ToRegister(instr->elements());
Register key = ToRegister(instr->key());
Register result = ToRegister(instr->result()); Register result = ToRegister(instr->result());
ASSERT(result.is(elements));
// Load the result. // Load the result.
__ movq(result, FieldOperand(elements, __ movq(result,
key, BuildFastArrayOperand(instr->elements(), instr->key(),
times_pointer_size, JSObject::FAST_ELEMENTS,
FixedArray::kHeaderSize)); FixedArray::kHeaderSize - kHeapObjectTag));
// Check for the hole value. // Check for the hole value.
if (instr->hydrogen()->RequiresHoleCheck()) { if (instr->hydrogen()->RequiresHoleCheck()) {
...@@ -2305,22 +2302,22 @@ void LCodeGen::DoLoadKeyedFastDoubleElement( ...@@ -2305,22 +2302,22 @@ void LCodeGen::DoLoadKeyedFastDoubleElement(
Operand LCodeGen::BuildFastArrayOperand( Operand LCodeGen::BuildFastArrayOperand(
LOperand* external_pointer, LOperand* elements_pointer,
LOperand* key, LOperand* key,
JSObject::ElementsKind elements_kind, JSObject::ElementsKind elements_kind,
uint32_t offset) { uint32_t offset) {
Register external_pointer_reg = ToRegister(external_pointer); Register elements_pointer_reg = ToRegister(elements_pointer);
int shift_size = ElementsKindToShiftSize(elements_kind); int shift_size = ElementsKindToShiftSize(elements_kind);
if (key->IsConstantOperand()) { if (key->IsConstantOperand()) {
int constant_value = ToInteger32(LConstantOperand::cast(key)); int constant_value = ToInteger32(LConstantOperand::cast(key));
if (constant_value & 0xF0000000) { if (constant_value & 0xF0000000) {
Abort("array index constant value too big"); Abort("array index constant value too big");
} }
return Operand(external_pointer_reg, return Operand(elements_pointer_reg,
constant_value * (1 << shift_size) + offset); constant_value * (1 << shift_size) + offset);
} else { } else {
ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size); ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size);
return Operand(external_pointer_reg, ToRegister(key), return Operand(elements_pointer_reg, ToRegister(key),
scale_factor, offset); scale_factor, offset);
} }
} }
...@@ -3103,12 +3100,22 @@ void LCodeGen::DoStoreKeyedSpecializedArrayElement( ...@@ -3103,12 +3100,22 @@ void LCodeGen::DoStoreKeyedSpecializedArrayElement(
void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
if (instr->length()->IsRegister()) { if (instr->index()->IsConstantOperand()) {
__ cmpq(ToRegister(instr->index()), ToRegister(instr->length())); if (instr->length()->IsRegister()) {
__ cmpq(ToRegister(instr->length()),
Immediate(ToInteger32(LConstantOperand::cast(instr->index()))));
} else {
__ cmpq(ToOperand(instr->length()),
Immediate(ToInteger32(LConstantOperand::cast(instr->index()))));
}
} else { } else {
__ cmpq(ToRegister(instr->index()), ToOperand(instr->length())); if (instr->length()->IsRegister()) {
__ cmpq(ToRegister(instr->length()), ToRegister(instr->index()));
} else {
__ cmpq(ToOperand(instr->length()), ToRegister(instr->index()));
}
} }
DeoptimizeIf(above_equal, instr->environment()); DeoptimizeIf(below_equal, instr->environment());
} }
......
...@@ -216,7 +216,7 @@ class LCodeGen BASE_EMBEDDED { ...@@ -216,7 +216,7 @@ class LCodeGen BASE_EMBEDDED {
Register ToRegister(int index) const; Register ToRegister(int index) const;
XMMRegister ToDoubleRegister(int index) const; XMMRegister ToDoubleRegister(int index) const;
Operand BuildFastArrayOperand( Operand BuildFastArrayOperand(
LOperand* external_pointer, LOperand* elements_pointer,
LOperand* key, LOperand* key,
JSObject::ElementsKind elements_kind, JSObject::ElementsKind elements_kind,
uint32_t offset); uint32_t offset);
......
...@@ -1519,8 +1519,9 @@ LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) { ...@@ -1519,8 +1519,9 @@ LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) {
LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) { LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) {
return AssignEnvironment(new LBoundsCheck(UseRegisterAtStart(instr->index()), return AssignEnvironment(new LBoundsCheck(
Use(instr->length()))); UseRegisterOrConstantAtStart(instr->index()),
Use(instr->length())));
} }
...@@ -1819,9 +1820,9 @@ LInstruction* LChunkBuilder::DoLoadKeyedFastElement( ...@@ -1819,9 +1820,9 @@ LInstruction* LChunkBuilder::DoLoadKeyedFastElement(
ASSERT(instr->representation().IsTagged()); ASSERT(instr->representation().IsTagged());
ASSERT(instr->key()->representation().IsInteger32()); ASSERT(instr->key()->representation().IsInteger32());
LOperand* obj = UseRegisterAtStart(instr->object()); LOperand* obj = UseRegisterAtStart(instr->object());
LOperand* key = UseRegisterAtStart(instr->key()); LOperand* key = UseRegisterOrConstantAtStart(instr->key());
LLoadKeyedFastElement* result = new LLoadKeyedFastElement(obj, key); LLoadKeyedFastElement* result = new LLoadKeyedFastElement(obj, key);
return AssignEnvironment(DefineSameAsFirst(result)); return AssignEnvironment(DefineAsRegister(result));
} }
......
...@@ -2124,14 +2124,18 @@ class LChunkBuilder BASE_EMBEDDED { ...@@ -2124,14 +2124,18 @@ class LChunkBuilder BASE_EMBEDDED {
template<int I, int T> template<int I, int T>
LInstruction* DefineFixedDouble(LTemplateInstruction<1, I, T>* instr, LInstruction* DefineFixedDouble(LTemplateInstruction<1, I, T>* instr,
XMMRegister reg); XMMRegister reg);
// Assigns an environment to an instruction. An instruction which can
// deoptimize must have an environment.
LInstruction* AssignEnvironment(LInstruction* instr); LInstruction* AssignEnvironment(LInstruction* instr);
// Assigns a pointer map to an instruction. An instruction which can
// trigger a GC or a lazy deoptimization must have a pointer map.
LInstruction* AssignPointerMap(LInstruction* instr); LInstruction* AssignPointerMap(LInstruction* instr);
enum CanDeoptimize { CAN_DEOPTIMIZE_EAGERLY, CANNOT_DEOPTIMIZE_EAGERLY }; enum CanDeoptimize { CAN_DEOPTIMIZE_EAGERLY, CANNOT_DEOPTIMIZE_EAGERLY };
// By default we assume that instruction sequences generated for calls // Marks a call for the register allocator. Assigns a pointer map to
// cannot deoptimize eagerly and we do not attach environment to this // support GC and lazy deoptimization. Assigns an environment to support
// instruction. // eager deoptimization if CAN_DEOPTIMIZE_EAGERLY.
LInstruction* MarkAsCall( LInstruction* MarkAsCall(
LInstruction* instr, LInstruction* instr,
HInstruction* hinstr, HInstruction* hinstr,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment