Commit 26e692af authored by lrn@chromium.org's avatar lrn@chromium.org

X64: Change some smi operations to work on untagged integers instead.

Use direct reading and writing of integers from Smi fields.
Change RecordWrite with 0 offset to take untagged index instead of
smi tagged index.

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4893 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 93387f27
...@@ -1148,6 +1148,15 @@ void Assembler::incl(const Operand& dst) { ...@@ -1148,6 +1148,15 @@ void Assembler::incl(const Operand& dst) {
} }
void Assembler::incl(Register dst) {
EnsureSpace ensure_space(this);
last_pc_ = pc_;
emit_optional_rex_32(dst);
emit(0xFF);
emit_modrm(0, dst);
}
void Assembler::int3() { void Assembler::int3() {
EnsureSpace ensure_space(this); EnsureSpace ensure_space(this);
last_pc_ = pc_; last_pc_ = pc_;
......
...@@ -765,6 +765,7 @@ class Assembler : public Malloced { ...@@ -765,6 +765,7 @@ class Assembler : public Malloced {
void incq(Register dst); void incq(Register dst);
void incq(const Operand& dst); void incq(const Operand& dst);
void incl(Register dst);
void incl(const Operand& dst); void incl(const Operand& dst);
void lea(Register dst, const Operand& src); void lea(Register dst, const Operand& src);
......
This diff is collapsed.
...@@ -1013,6 +1013,7 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) { ...@@ -1013,6 +1013,7 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) {
__ movq(FieldOperand(rbx, index2.reg, index2.scale, FixedArray::kHeaderSize), __ movq(FieldOperand(rbx, index2.reg, index2.scale, FixedArray::kHeaderSize),
rax); rax);
__ movq(rdx, rax); __ movq(rdx, rax);
__ SmiToInteger32(rcx, rcx);
__ RecordWriteNonSmi(rbx, 0, rdx, rcx); __ RecordWriteNonSmi(rbx, 0, rdx, rcx);
__ ret(0); __ ret(0);
} }
......
...@@ -96,8 +96,8 @@ void MacroAssembler::RecordWriteHelper(Register object, ...@@ -96,8 +96,8 @@ void MacroAssembler::RecordWriteHelper(Register object,
// Compute number of region covering addr. See Page::GetRegionNumberForAddress // Compute number of region covering addr. See Page::GetRegionNumberForAddress
// method for more details. // method for more details.
and_(addr, Immediate(Page::kPageAlignmentMask));
shrl(addr, Immediate(Page::kRegionSizeLog2)); shrl(addr, Immediate(Page::kRegionSizeLog2));
andl(addr, Immediate(Page::kPageAlignmentMask >> Page::kRegionSizeLog2));
// Set dirty mark for region. // Set dirty mark for region.
bts(Operand(object, Page::kDirtyFlagOffset), addr); bts(Operand(object, Page::kDirtyFlagOffset), addr);
...@@ -106,25 +106,25 @@ void MacroAssembler::RecordWriteHelper(Register object, ...@@ -106,25 +106,25 @@ void MacroAssembler::RecordWriteHelper(Register object,
// For page containing |object| mark region covering [object+offset] dirty. // For page containing |object| mark region covering [object+offset] dirty.
// object is the object being stored into, value is the object being stored. // object is the object being stored into, value is the object being stored.
// If offset is zero, then the smi_index register contains the array index into // If offset is zero, then the index register contains the array index into
// the elements array represented as a smi. Otherwise it can be used as a // the elements array represented a zero extended int32. Otherwise it can be
// scratch register. // used as a scratch register.
// All registers are clobbered by the operation. // All registers are clobbered by the operation.
void MacroAssembler::RecordWrite(Register object, void MacroAssembler::RecordWrite(Register object,
int offset, int offset,
Register value, Register value,
Register smi_index) { Register index) {
// The compiled code assumes that record write doesn't change the // The compiled code assumes that record write doesn't change the
// context register, so we check that none of the clobbered // context register, so we check that none of the clobbered
// registers are rsi. // registers are rsi.
ASSERT(!object.is(rsi) && !value.is(rsi) && !smi_index.is(rsi)); ASSERT(!object.is(rsi) && !value.is(rsi) && !index.is(rsi));
// First, check if a write barrier is even needed. The tests below // First, check if a write barrier is even needed. The tests below
// catch stores of Smis and stores into young gen. // catch stores of Smis and stores into young gen.
Label done; Label done;
JumpIfSmi(value, &done); JumpIfSmi(value, &done);
RecordWriteNonSmi(object, offset, value, smi_index); RecordWriteNonSmi(object, offset, value, index);
bind(&done); bind(&done);
// Clobber all input registers when running with the debug-code flag // Clobber all input registers when running with the debug-code flag
...@@ -135,7 +135,7 @@ void MacroAssembler::RecordWrite(Register object, ...@@ -135,7 +135,7 @@ void MacroAssembler::RecordWrite(Register object,
if (FLAG_debug_code) { if (FLAG_debug_code) {
movq(object, BitCast<int64_t>(kZapValue), RelocInfo::NONE); movq(object, BitCast<int64_t>(kZapValue), RelocInfo::NONE);
movq(value, BitCast<int64_t>(kZapValue), RelocInfo::NONE); movq(value, BitCast<int64_t>(kZapValue), RelocInfo::NONE);
movq(smi_index, BitCast<int64_t>(kZapValue), RelocInfo::NONE); movq(index, BitCast<int64_t>(kZapValue), RelocInfo::NONE);
} }
} }
...@@ -143,7 +143,7 @@ void MacroAssembler::RecordWrite(Register object, ...@@ -143,7 +143,7 @@ void MacroAssembler::RecordWrite(Register object,
void MacroAssembler::RecordWriteNonSmi(Register object, void MacroAssembler::RecordWriteNonSmi(Register object,
int offset, int offset,
Register scratch, Register scratch,
Register smi_index) { Register index) {
Label done; Label done;
if (FLAG_debug_code) { if (FLAG_debug_code) {
...@@ -151,6 +151,16 @@ void MacroAssembler::RecordWriteNonSmi(Register object, ...@@ -151,6 +151,16 @@ void MacroAssembler::RecordWriteNonSmi(Register object,
JumpIfNotSmi(object, &okay); JumpIfNotSmi(object, &okay);
Abort("MacroAssembler::RecordWriteNonSmi cannot deal with smis"); Abort("MacroAssembler::RecordWriteNonSmi cannot deal with smis");
bind(&okay); bind(&okay);
if (offset == 0) {
// index must be int32.
Register tmp = index.is(rax) ? rbx : rax;
push(tmp);
movl(tmp, index);
cmpq(tmp, index);
Check(equal, "Index register for RecordWrite must be untagged int32.");
pop(tmp);
}
} }
// Test that the object address is not in the new space. We cannot // Test that the object address is not in the new space. We cannot
...@@ -163,16 +173,15 @@ void MacroAssembler::RecordWriteNonSmi(Register object, ...@@ -163,16 +173,15 @@ void MacroAssembler::RecordWriteNonSmi(Register object,
ASSERT(IsAligned(offset, kPointerSize) || ASSERT(IsAligned(offset, kPointerSize) ||
IsAligned(offset + kHeapObjectTag, kPointerSize)); IsAligned(offset + kHeapObjectTag, kPointerSize));
Register dst = smi_index; Register dst = index;
if (offset != 0) { if (offset != 0) {
lea(dst, Operand(object, offset)); lea(dst, Operand(object, offset));
} else { } else {
// array access: calculate the destination address in the same manner as // array access: calculate the destination address in the same manner as
// KeyedStoreIC::GenerateGeneric. // KeyedStoreIC::GenerateGeneric.
SmiIndex index = SmiToIndex(smi_index, smi_index, kPointerSizeLog2);
lea(dst, FieldOperand(object, lea(dst, FieldOperand(object,
index.reg, index,
index.scale, times_pointer_size,
FixedArray::kHeaderSize)); FixedArray::kHeaderSize));
} }
RecordWriteHelper(object, dst, scratch); RecordWriteHelper(object, dst, scratch);
...@@ -184,7 +193,7 @@ void MacroAssembler::RecordWriteNonSmi(Register object, ...@@ -184,7 +193,7 @@ void MacroAssembler::RecordWriteNonSmi(Register object,
if (FLAG_debug_code) { if (FLAG_debug_code) {
movq(object, BitCast<int64_t>(kZapValue), RelocInfo::NONE); movq(object, BitCast<int64_t>(kZapValue), RelocInfo::NONE);
movq(scratch, BitCast<int64_t>(kZapValue), RelocInfo::NONE); movq(scratch, BitCast<int64_t>(kZapValue), RelocInfo::NONE);
movq(smi_index, BitCast<int64_t>(kZapValue), RelocInfo::NONE); movq(index, BitCast<int64_t>(kZapValue), RelocInfo::NONE);
} }
} }
...@@ -485,6 +494,23 @@ void MacroAssembler::Integer32ToSmi(Register dst, ...@@ -485,6 +494,23 @@ void MacroAssembler::Integer32ToSmi(Register dst,
} }
void MacroAssembler::Integer32ToSmiField(const Operand& dst, Register src) {
if (FLAG_debug_code) {
testb(dst, Immediate(0x01));
Label ok;
j(zero, &ok);
if (allow_stub_calls()) {
Abort("Integer32ToSmiField writing to non-smi location");
} else {
int3();
}
bind(&ok);
}
ASSERT(kSmiShift % kBitsPerByte == 0);
movl(Operand(dst, kSmiShift / kBitsPerByte), src);
}
void MacroAssembler::Integer64PlusConstantToSmi(Register dst, void MacroAssembler::Integer64PlusConstantToSmi(Register dst,
Register src, Register src,
int constant) { int constant) {
...@@ -520,6 +546,11 @@ void MacroAssembler::SmiToInteger64(Register dst, Register src) { ...@@ -520,6 +546,11 @@ void MacroAssembler::SmiToInteger64(Register dst, Register src) {
} }
void MacroAssembler::SmiToInteger64(Register dst, const Operand& src) {
movsxlq(dst, Operand(src, kSmiShift / kBitsPerByte));
}
void MacroAssembler::SmiTest(Register src) { void MacroAssembler::SmiTest(Register src) {
testq(src, src); testq(src, src);
} }
...@@ -556,6 +587,11 @@ void MacroAssembler::SmiCompare(const Operand& dst, Smi* src) { ...@@ -556,6 +587,11 @@ void MacroAssembler::SmiCompare(const Operand& dst, Smi* src) {
} }
void MacroAssembler::SmiCompareInteger32(const Operand& dst, Register src) {
cmpl(Operand(dst, kSmiShift / kBitsPerByte), src);
}
void MacroAssembler::PositiveSmiTimesPowerOfTwoToInteger64(Register dst, void MacroAssembler::PositiveSmiTimesPowerOfTwoToInteger64(Register dst,
Register src, Register src,
int power) { int power) {
......
...@@ -203,6 +203,9 @@ class MacroAssembler: public Assembler { ...@@ -203,6 +203,9 @@ class MacroAssembler: public Assembler {
// NOTICE: Destroys the dst register even if unsuccessful! // NOTICE: Destroys the dst register even if unsuccessful!
void Integer32ToSmi(Register dst, Register src, Label* on_overflow); void Integer32ToSmi(Register dst, Register src, Label* on_overflow);
// Stores an integer32 value into a memory field that already holds a smi.
void Integer32ToSmiField(const Operand& dst, Register src);
// Adds constant to src and tags the result as a smi. // Adds constant to src and tags the result as a smi.
// Result must be a valid smi. // Result must be a valid smi.
void Integer64PlusConstantToSmi(Register dst, Register src, int constant); void Integer64PlusConstantToSmi(Register dst, Register src, int constant);
...@@ -214,6 +217,7 @@ class MacroAssembler: public Assembler { ...@@ -214,6 +217,7 @@ class MacroAssembler: public Assembler {
// Convert smi to 64-bit integer (sign extended if necessary). // Convert smi to 64-bit integer (sign extended if necessary).
void SmiToInteger64(Register dst, Register src); void SmiToInteger64(Register dst, Register src);
void SmiToInteger64(Register dst, const Operand& src);
// Multiply a positive smi's integer value by a power of two. // Multiply a positive smi's integer value by a power of two.
// Provides result as 64-bit integer value. // Provides result as 64-bit integer value.
...@@ -234,6 +238,8 @@ class MacroAssembler: public Assembler { ...@@ -234,6 +238,8 @@ class MacroAssembler: public Assembler {
void SmiCompare(Register dst, const Operand& src); void SmiCompare(Register dst, const Operand& src);
void SmiCompare(const Operand& dst, Register src); void SmiCompare(const Operand& dst, Register src);
void SmiCompare(const Operand& dst, Smi* src); void SmiCompare(const Operand& dst, Smi* src);
// Compare the int32 in src register to the value of the smi stored at dst.
void SmiCompareInteger32(const Operand& dst, Register src);
// Sets sign and zero flags depending on value of smi in register. // Sets sign and zero flags depending on value of smi in register.
void SmiTest(Register src); void SmiTest(Register src);
......
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