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) {
void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) {
Register elements = ToRegister(instr->elements());
Register key = ToRegister(instr->key());
Register result = ToRegister(instr->result());
ASSERT(result.is(elements));
// Load the result.
__ mov(result, FieldOperand(elements,
key,
times_pointer_size,
FixedArray::kHeaderSize));
__ mov(result,
BuildFastArrayOperand(instr->elements(), instr->key(),
JSObject::FAST_ELEMENTS,
FixedArray::kHeaderSize - kHeapObjectTag));
// Check for the hole value.
if (instr->hydrogen()->RequiresHoleCheck()) {
......@@ -2301,22 +2298,22 @@ void LCodeGen::DoLoadKeyedFastDoubleElement(
Operand LCodeGen::BuildFastArrayOperand(
LOperand* external_pointer,
LOperand* elements_pointer,
LOperand* key,
JSObject::ElementsKind elements_kind,
uint32_t offset) {
Register external_pointer_reg = ToRegister(external_pointer);
Register elements_pointer_reg = ToRegister(elements_pointer);
int shift_size = ElementsKindToShiftSize(elements_kind);
if (key->IsConstantOperand()) {
int constant_value = ToInteger32(LConstantOperand::cast(key));
if (constant_value & 0xF0000000) {
Abort("array index constant value too big");
}
return Operand(external_pointer_reg,
return Operand(elements_pointer_reg,
constant_value * (1 << shift_size) + offset);
} else {
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) {
void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
__ cmp(ToRegister(instr->index()), ToOperand(instr->length()));
DeoptimizeIf(above_equal, instr->environment());
if (instr->index()->IsConstantOperand()) {
__ 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 {
Register ToRegister(int index) const;
XMMRegister ToDoubleRegister(int index) const;
int ToInteger32(LConstantOperand* op) const;
Operand BuildFastArrayOperand(LOperand* external_pointer,
Operand BuildFastArrayOperand(LOperand* elements_pointer,
LOperand* key,
JSObject::ElementsKind elements_kind,
uint32_t offset);
......
......@@ -1559,8 +1559,9 @@ LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) {
LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) {
return AssignEnvironment(new LBoundsCheck(UseRegisterAtStart(instr->index()),
UseAtStart(instr->length())));
return AssignEnvironment(new LBoundsCheck(
UseRegisterOrConstantAtStart(instr->index()),
UseAtStart(instr->length())));
}
......@@ -1881,9 +1882,9 @@ LInstruction* LChunkBuilder::DoLoadKeyedFastElement(
ASSERT(instr->representation().IsTagged());
ASSERT(instr->key()->representation().IsInteger32());
LOperand* obj = UseRegisterAtStart(instr->object());
LOperand* key = UseRegisterAtStart(instr->key());
LOperand* key = UseRegisterOrConstantAtStart(instr->key());
LLoadKeyedFastElement* result = new LLoadKeyedFastElement(obj, key);
return AssignEnvironment(DefineSameAsFirst(result));
return AssignEnvironment(DefineAsRegister(result));
}
......
......@@ -2237,14 +2237,18 @@ class LChunkBuilder BASE_EMBEDDED {
template<int I, int T>
LInstruction* DefineFixedDouble(LTemplateInstruction<1, I, T>* instr,
XMMRegister reg);
// Assigns an environment to an instruction. An instruction which can
// deoptimize must have an environment.
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);
enum CanDeoptimize { CAN_DEOPTIMIZE_EAGERLY, CANNOT_DEOPTIMIZE_EAGERLY };
// By default we assume that instruction sequences generated for calls
// cannot deoptimize eagerly and we do not attach environment to this
// instruction.
// Marks a call for the register allocator. Assigns a pointer map to
// support GC and lazy deoptimization. Assigns an environment to support
// eager deoptimization if CAN_DEOPTIMIZE_EAGERLY.
LInstruction* MarkAsCall(
LInstruction* instr,
HInstruction* hinstr,
......
......@@ -2262,16 +2262,13 @@ void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) {
Register elements = ToRegister(instr->elements());
Register key = ToRegister(instr->key());
Register result = ToRegister(instr->result());
ASSERT(result.is(elements));
// Load the result.
__ movq(result, FieldOperand(elements,
key,
times_pointer_size,
FixedArray::kHeaderSize));
__ movq(result,
BuildFastArrayOperand(instr->elements(), instr->key(),
JSObject::FAST_ELEMENTS,
FixedArray::kHeaderSize - kHeapObjectTag));
// Check for the hole value.
if (instr->hydrogen()->RequiresHoleCheck()) {
......@@ -2305,22 +2302,22 @@ void LCodeGen::DoLoadKeyedFastDoubleElement(
Operand LCodeGen::BuildFastArrayOperand(
LOperand* external_pointer,
LOperand* elements_pointer,
LOperand* key,
JSObject::ElementsKind elements_kind,
uint32_t offset) {
Register external_pointer_reg = ToRegister(external_pointer);
Register elements_pointer_reg = ToRegister(elements_pointer);
int shift_size = ElementsKindToShiftSize(elements_kind);
if (key->IsConstantOperand()) {
int constant_value = ToInteger32(LConstantOperand::cast(key));
if (constant_value & 0xF0000000) {
Abort("array index constant value too big");
}
return Operand(external_pointer_reg,
return Operand(elements_pointer_reg,
constant_value * (1 << shift_size) + offset);
} else {
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);
}
}
......@@ -3103,12 +3100,22 @@ void LCodeGen::DoStoreKeyedSpecializedArrayElement(
void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
if (instr->length()->IsRegister()) {
__ cmpq(ToRegister(instr->index()), ToRegister(instr->length()));
if (instr->index()->IsConstantOperand()) {
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 {
__ 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 {
Register ToRegister(int index) const;
XMMRegister ToDoubleRegister(int index) const;
Operand BuildFastArrayOperand(
LOperand* external_pointer,
LOperand* elements_pointer,
LOperand* key,
JSObject::ElementsKind elements_kind,
uint32_t offset);
......
......@@ -1519,8 +1519,9 @@ LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) {
LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) {
return AssignEnvironment(new LBoundsCheck(UseRegisterAtStart(instr->index()),
Use(instr->length())));
return AssignEnvironment(new LBoundsCheck(
UseRegisterOrConstantAtStart(instr->index()),
Use(instr->length())));
}
......@@ -1819,9 +1820,9 @@ LInstruction* LChunkBuilder::DoLoadKeyedFastElement(
ASSERT(instr->representation().IsTagged());
ASSERT(instr->key()->representation().IsInteger32());
LOperand* obj = UseRegisterAtStart(instr->object());
LOperand* key = UseRegisterAtStart(instr->key());
LOperand* key = UseRegisterOrConstantAtStart(instr->key());
LLoadKeyedFastElement* result = new LLoadKeyedFastElement(obj, key);
return AssignEnvironment(DefineSameAsFirst(result));
return AssignEnvironment(DefineAsRegister(result));
}
......
......@@ -2124,14 +2124,18 @@ class LChunkBuilder BASE_EMBEDDED {
template<int I, int T>
LInstruction* DefineFixedDouble(LTemplateInstruction<1, I, T>* instr,
XMMRegister reg);
// Assigns an environment to an instruction. An instruction which can
// deoptimize must have an environment.
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);
enum CanDeoptimize { CAN_DEOPTIMIZE_EAGERLY, CANNOT_DEOPTIMIZE_EAGERLY };
// By default we assume that instruction sequences generated for calls
// cannot deoptimize eagerly and we do not attach environment to this
// instruction.
// Marks a call for the register allocator. Assigns a pointer map to
// support GC and lazy deoptimization. Assigns an environment to support
// eager deoptimization if CAN_DEOPTIMIZE_EAGERLY.
LInstruction* MarkAsCall(
LInstruction* instr,
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