Fixed deopt reasons in TaggedToI.
Every DeoptimizeIf should be preceded by a RecordComment explaining the reason. In the long run, the reason should be an argument of DeoptimizeIf, but we're not there yet. On x87, things are a bit ugly due to some pushing/popping, so if somebody feels inclined to improve this: Feel free. Probably the right approach would be reloading instead of the push/pop horror. Another thing is our inconsistent handling of the "done" continuation of deferred code on the various platforms, I made tiny changes on the way, but this should better be unified somehow, with all those micro-optimizations removed. R=jkummerow@chromium.org Review URL: https://codereview.chromium.org/578583002 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@23996 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
fdcf5f99b2
commit
ac1b9b11dc
@ -4975,16 +4975,17 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
|
||||
__ bind(&check_false);
|
||||
__ LoadRoot(ip, Heap::kFalseValueRootIndex);
|
||||
__ cmp(scratch2, Operand(ip));
|
||||
__ RecordComment("Deferred TaggedToI: cannot truncate");
|
||||
DeoptimizeIf(ne, instr->environment());
|
||||
__ mov(input_reg, Operand::Zero());
|
||||
__ b(&done);
|
||||
} else {
|
||||
// Deoptimize if we don't have a heap number.
|
||||
__ RecordComment("Deferred TaggedToI: not a heap number");
|
||||
DeoptimizeIf(ne, instr->environment());
|
||||
|
||||
__ sub(ip, scratch2, Operand(kHeapObjectTag));
|
||||
__ vldr(double_scratch2, ip, HeapNumber::kValueOffset);
|
||||
__ TryDoubleToInt32Exact(input_reg, double_scratch2, double_scratch);
|
||||
__ RecordComment("Deferred TaggedToI: lost precision or NaN");
|
||||
DeoptimizeIf(ne, instr->environment());
|
||||
|
||||
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
|
||||
@ -4992,6 +4993,7 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
|
||||
__ b(ne, &done);
|
||||
__ VmovHigh(scratch1, double_scratch2);
|
||||
__ tst(scratch1, Operand(HeapNumber::kSignMask));
|
||||
__ RecordComment("Deferred TaggedToI: minus zero");
|
||||
DeoptimizeIf(ne, instr->environment());
|
||||
}
|
||||
}
|
||||
|
@ -5645,10 +5645,9 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr,
|
||||
instr->environment());
|
||||
} else {
|
||||
Register output = ToRegister32(instr->result());
|
||||
|
||||
DoubleRegister dbl_scratch2 = ToDoubleRegister(temp2);
|
||||
|
||||
// Deoptimized if it's not a heap number.
|
||||
__ RecordComment("Deferred TaggedToI: not a heap number");
|
||||
DeoptimizeIfNotRoot(scratch1, Heap::kHeapNumberMapRootIndex,
|
||||
instr->environment());
|
||||
|
||||
@ -5656,12 +5655,14 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr,
|
||||
// function. If the result is out of range, branch to deoptimize.
|
||||
__ Ldr(dbl_scratch1, FieldMemOperand(input, HeapNumber::kValueOffset));
|
||||
__ TryRepresentDoubleAsInt32(output, dbl_scratch1, dbl_scratch2);
|
||||
__ RecordComment("Deferred TaggedToI: lost precision or NaN");
|
||||
DeoptimizeIf(ne, instr->environment());
|
||||
|
||||
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
|
||||
__ Cmp(output, 0);
|
||||
__ B(ne, &done);
|
||||
__ Fmov(scratch1, dbl_scratch1);
|
||||
__ RecordComment("Deferred TaggedToI: minus zero");
|
||||
DeoptimizeIfNegative(scratch1, instr->environment());
|
||||
}
|
||||
}
|
||||
|
@ -4764,15 +4764,28 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr, Label* done) {
|
||||
DeoptimizeIf(not_equal, instr->environment());
|
||||
__ Move(input_reg, Immediate(0));
|
||||
} else {
|
||||
Label bailout;
|
||||
XMMRegister scratch = (instr->temp() != NULL)
|
||||
? ToDoubleRegister(instr->temp())
|
||||
: no_xmm_reg;
|
||||
__ TaggedToI(input_reg, input_reg, scratch,
|
||||
instr->hydrogen()->GetMinusZeroMode(), &bailout);
|
||||
__ jmp(done);
|
||||
__ bind(&bailout);
|
||||
DeoptimizeIf(no_condition, instr->environment());
|
||||
XMMRegister scratch = ToDoubleRegister(instr->temp());
|
||||
DCHECK(!scratch.is(xmm0));
|
||||
__ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
|
||||
isolate()->factory()->heap_number_map());
|
||||
__ RecordComment("Deferred TaggedToI: not a heap number");
|
||||
DeoptimizeIf(not_equal, instr->environment());
|
||||
__ movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
|
||||
__ cvttsd2si(input_reg, Operand(xmm0));
|
||||
__ Cvtsi2sd(scratch, Operand(input_reg));
|
||||
__ ucomisd(xmm0, scratch);
|
||||
__ RecordComment("Deferred TaggedToI: lost precision");
|
||||
DeoptimizeIf(not_equal, instr->environment());
|
||||
__ RecordComment("Deferred TaggedToI: NaN");
|
||||
DeoptimizeIf(parity_even, instr->environment());
|
||||
if (instr->hydrogen()->GetMinusZeroMode() == FAIL_ON_MINUS_ZERO) {
|
||||
__ test(input_reg, Operand(input_reg));
|
||||
__ j(not_zero, done);
|
||||
__ movmskpd(input_reg, xmm0);
|
||||
__ and_(input_reg, 1);
|
||||
__ RecordComment("Deferred TaggedToI: minus zero");
|
||||
DeoptimizeIf(not_zero, instr->environment());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -346,40 +346,6 @@ void MacroAssembler::TruncateHeapNumberToI(Register result_reg,
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::TaggedToI(Register result_reg,
|
||||
Register input_reg,
|
||||
XMMRegister temp,
|
||||
MinusZeroMode minus_zero_mode,
|
||||
Label* lost_precision) {
|
||||
Label done;
|
||||
DCHECK(!temp.is(xmm0));
|
||||
|
||||
cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
|
||||
isolate()->factory()->heap_number_map());
|
||||
j(not_equal, lost_precision, Label::kNear);
|
||||
|
||||
DCHECK(!temp.is(no_xmm_reg));
|
||||
|
||||
movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
|
||||
cvttsd2si(result_reg, Operand(xmm0));
|
||||
Cvtsi2sd(temp, Operand(result_reg));
|
||||
ucomisd(xmm0, temp);
|
||||
RecordComment("Deferred TaggedToI: lost precision");
|
||||
j(not_equal, lost_precision, Label::kNear);
|
||||
RecordComment("Deferred TaggedToI: NaN");
|
||||
j(parity_even, lost_precision, Label::kNear);
|
||||
if (minus_zero_mode == FAIL_ON_MINUS_ZERO) {
|
||||
test(result_reg, Operand(result_reg));
|
||||
j(not_zero, &done, Label::kNear);
|
||||
movmskpd(result_reg, xmm0);
|
||||
and_(result_reg, 1);
|
||||
RecordComment("Deferred TaggedToI: minus zero");
|
||||
j(not_zero, lost_precision, Label::kNear);
|
||||
}
|
||||
bind(&done);
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::LoadUint32(XMMRegister dst,
|
||||
Register src) {
|
||||
Label done;
|
||||
|
@ -466,9 +466,6 @@ class MacroAssembler: public Assembler {
|
||||
XMMRegister scratch, MinusZeroMode minus_zero_mode,
|
||||
Label* conversion_failed, Label::Distance dst = Label::kFar);
|
||||
|
||||
void TaggedToI(Register result_reg, Register input_reg, XMMRegister temp,
|
||||
MinusZeroMode minus_zero_mode, Label* lost_precision);
|
||||
|
||||
// Smi tagging support.
|
||||
void SmiTag(Register reg) {
|
||||
STATIC_ASSERT(kSmiTag == 0);
|
||||
|
@ -4934,11 +4934,12 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
|
||||
|
||||
__ bind(&check_false);
|
||||
__ LoadRoot(at, Heap::kFalseValueRootIndex);
|
||||
__ RecordComment("Deferred TaggedToI: cannot truncate");
|
||||
DeoptimizeIf(ne, instr->environment(), scratch2, Operand(at));
|
||||
__ Branch(USE_DELAY_SLOT, &done);
|
||||
__ mov(input_reg, zero_reg); // In delay slot.
|
||||
} else {
|
||||
// Deoptimize if we don't have a heap number.
|
||||
__ RecordComment("Deferred TaggedToI: not a heap number");
|
||||
DeoptimizeIf(ne, instr->environment(), scratch1, Operand(at));
|
||||
|
||||
// Load the double value.
|
||||
@ -4954,7 +4955,7 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
|
||||
except_flag,
|
||||
kCheckForInexactConversion);
|
||||
|
||||
// Deopt if the operation did not succeed.
|
||||
__ RecordComment("Deferred TaggedToI: lost precision or NaN");
|
||||
DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg));
|
||||
|
||||
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
|
||||
@ -4962,6 +4963,7 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
|
||||
|
||||
__ Mfhc1(scratch1, double_scratch);
|
||||
__ And(scratch1, scratch1, Operand(HeapNumber::kSignMask));
|
||||
__ RecordComment("Deferred TaggedToI: minus zero");
|
||||
DeoptimizeIf(ne, instr->environment(), scratch1, Operand(zero_reg));
|
||||
}
|
||||
}
|
||||
|
@ -4973,11 +4973,12 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
|
||||
|
||||
__ bind(&check_false);
|
||||
__ LoadRoot(at, Heap::kFalseValueRootIndex);
|
||||
__ RecordComment("Deferred TaggedToI: cannot truncate");
|
||||
DeoptimizeIf(ne, instr->environment(), scratch2, Operand(at));
|
||||
__ Branch(USE_DELAY_SLOT, &done);
|
||||
__ mov(input_reg, zero_reg); // In delay slot.
|
||||
} else {
|
||||
// Deoptimize if we don't have a heap number.
|
||||
__ RecordComment("Deferred TaggedToI: not a heap number");
|
||||
DeoptimizeIf(ne, instr->environment(), scratch1, Operand(at));
|
||||
|
||||
// Load the double value.
|
||||
@ -4993,7 +4994,7 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
|
||||
except_flag,
|
||||
kCheckForInexactConversion);
|
||||
|
||||
// Deopt if the operation did not succeed.
|
||||
__ RecordComment("Deferred TaggedToI: lost precision or NaN");
|
||||
DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg));
|
||||
|
||||
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
|
||||
@ -5001,6 +5002,7 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
|
||||
|
||||
__ mfhc1(scratch1, double_scratch); // Get exponent/sign bits.
|
||||
__ And(scratch1, scratch1, Operand(HeapNumber::kSignMask));
|
||||
__ RecordComment("Deferred TaggedToI: minus zero");
|
||||
DeoptimizeIf(ne, instr->environment(), scratch1, Operand(zero_reg));
|
||||
}
|
||||
}
|
||||
|
@ -4963,16 +4963,29 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr, Label* done) {
|
||||
__ RecordComment("Deferred TaggedToI: cannot truncate");
|
||||
DeoptimizeIf(not_equal, instr->environment());
|
||||
__ Set(input_reg, 0);
|
||||
__ jmp(done);
|
||||
} else {
|
||||
Label bailout;
|
||||
XMMRegister xmm_temp = ToDoubleRegister(instr->temp());
|
||||
__ TaggedToI(input_reg, input_reg, xmm_temp,
|
||||
instr->hydrogen()->GetMinusZeroMode(), &bailout, Label::kNear);
|
||||
|
||||
__ jmp(done);
|
||||
__ bind(&bailout);
|
||||
DeoptimizeIf(no_condition, instr->environment());
|
||||
XMMRegister scratch = ToDoubleRegister(instr->temp());
|
||||
DCHECK(!scratch.is(xmm0));
|
||||
__ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset),
|
||||
Heap::kHeapNumberMapRootIndex);
|
||||
__ RecordComment("Deferred TaggedToI: not a heap number");
|
||||
DeoptimizeIf(not_equal, instr->environment());
|
||||
__ movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
|
||||
__ cvttsd2si(input_reg, xmm0);
|
||||
__ Cvtlsi2sd(scratch, input_reg);
|
||||
__ ucomisd(xmm0, scratch);
|
||||
__ RecordComment("Deferred TaggedToI: lost precision");
|
||||
DeoptimizeIf(not_equal, instr->environment());
|
||||
__ RecordComment("Deferred TaggedToI: NaN");
|
||||
DeoptimizeIf(parity_even, instr->environment());
|
||||
if (instr->hydrogen()->GetMinusZeroMode() == FAIL_ON_MINUS_ZERO) {
|
||||
__ testl(input_reg, input_reg);
|
||||
__ j(not_zero, done);
|
||||
__ movmskpd(input_reg, xmm0);
|
||||
__ andl(input_reg, Immediate(1));
|
||||
__ RecordComment("Deferred TaggedToI: minus zero");
|
||||
DeoptimizeIf(not_zero, instr->environment());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3545,39 +3545,6 @@ void MacroAssembler::DoubleToI(Register result_reg,
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::TaggedToI(Register result_reg,
|
||||
Register input_reg,
|
||||
XMMRegister temp,
|
||||
MinusZeroMode minus_zero_mode,
|
||||
Label* lost_precision,
|
||||
Label::Distance dst) {
|
||||
Label done;
|
||||
DCHECK(!temp.is(xmm0));
|
||||
|
||||
// Heap number map check.
|
||||
CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset),
|
||||
Heap::kHeapNumberMapRootIndex);
|
||||
j(not_equal, lost_precision, dst);
|
||||
|
||||
movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
|
||||
cvttsd2si(result_reg, xmm0);
|
||||
Cvtlsi2sd(temp, result_reg);
|
||||
ucomisd(xmm0, temp);
|
||||
RecordComment("Deferred TaggedToI: lost precision");
|
||||
j(not_equal, lost_precision, dst);
|
||||
RecordComment("Deferred TaggedToI: NaN");
|
||||
j(parity_even, lost_precision, dst); // NaN.
|
||||
if (minus_zero_mode == FAIL_ON_MINUS_ZERO) {
|
||||
testl(result_reg, result_reg);
|
||||
j(not_zero, &done, Label::kNear);
|
||||
movmskpd(result_reg, xmm0);
|
||||
andl(result_reg, Immediate(1));
|
||||
j(not_zero, lost_precision, dst);
|
||||
}
|
||||
bind(&done);
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::LoadInstanceDescriptors(Register map,
|
||||
Register descriptors) {
|
||||
movp(descriptors, FieldOperand(map, Map::kDescriptorsOffset));
|
||||
|
@ -1033,10 +1033,6 @@ class MacroAssembler: public Assembler {
|
||||
XMMRegister scratch, MinusZeroMode minus_zero_mode,
|
||||
Label* conversion_failed, Label::Distance dst = Label::kFar);
|
||||
|
||||
void TaggedToI(Register result_reg, Register input_reg, XMMRegister temp,
|
||||
MinusZeroMode minus_zero_mode, Label* lost_precision,
|
||||
Label::Distance dst = Label::kFar);
|
||||
|
||||
void LoadUint32(XMMRegister dst, Register src);
|
||||
|
||||
void LoadInstanceDescriptors(Register map, Register descriptors);
|
||||
|
@ -4730,12 +4730,61 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr, Label* done) {
|
||||
DeoptimizeIf(not_equal, instr->environment());
|
||||
__ Move(input_reg, Immediate(0));
|
||||
} else {
|
||||
Label bailout;
|
||||
__ TaggedToI(input_reg, input_reg,
|
||||
instr->hydrogen()->GetMinusZeroMode(), &bailout);
|
||||
__ jmp(done);
|
||||
__ bind(&bailout);
|
||||
DeoptimizeIf(no_condition, instr->environment());
|
||||
// TODO(olivf) Converting a number on the fpu is actually quite slow. We
|
||||
// should first try a fast conversion and then bailout to this slow case.
|
||||
__ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
|
||||
isolate()->factory()->heap_number_map());
|
||||
__ RecordComment("Deferred TaggedToI: not a heap number");
|
||||
DeoptimizeIf(not_equal, instr->environment());
|
||||
|
||||
__ sub(esp, Immediate(kPointerSize));
|
||||
__ fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset));
|
||||
|
||||
if (instr->hydrogen()->GetMinusZeroMode() == FAIL_ON_MINUS_ZERO) {
|
||||
Label no_precision_lost, not_nan, zero_check;
|
||||
__ fld(0);
|
||||
|
||||
__ fist_s(MemOperand(esp, 0));
|
||||
__ fild_s(MemOperand(esp, 0));
|
||||
__ FCmp();
|
||||
__ pop(input_reg);
|
||||
|
||||
__ j(equal, &no_precision_lost, Label::kNear);
|
||||
__ fstp(0);
|
||||
__ RecordComment("Deferred TaggedToI: lost precision");
|
||||
DeoptimizeIf(no_condition, instr->environment());
|
||||
__ bind(&no_precision_lost);
|
||||
|
||||
__ j(parity_odd, ¬_nan);
|
||||
__ fstp(0);
|
||||
__ RecordComment("Deferred TaggedToI: NaN");
|
||||
DeoptimizeIf(no_condition, instr->environment());
|
||||
__ bind(¬_nan);
|
||||
|
||||
__ test(input_reg, Operand(input_reg));
|
||||
__ j(zero, &zero_check, Label::kNear);
|
||||
__ fstp(0);
|
||||
__ jmp(done);
|
||||
|
||||
__ bind(&zero_check);
|
||||
// To check for minus zero, we load the value again as float, and check
|
||||
// if that is still 0.
|
||||
__ sub(esp, Immediate(kPointerSize));
|
||||
__ fstp_s(Operand(esp, 0));
|
||||
__ pop(input_reg);
|
||||
__ test(input_reg, Operand(input_reg));
|
||||
__ RecordComment("Deferred TaggedToI: minus zero");
|
||||
DeoptimizeIf(not_zero, instr->environment());
|
||||
} else {
|
||||
__ fist_s(MemOperand(esp, 0));
|
||||
__ fild_s(MemOperand(esp, 0));
|
||||
__ FCmp();
|
||||
__ pop(input_reg);
|
||||
__ RecordComment("Deferred TaggedToI: lost precision");
|
||||
DeoptimizeIf(not_equal, instr->environment());
|
||||
__ RecordComment("Deferred TaggedToI: NaN");
|
||||
DeoptimizeIf(parity_even, instr->environment());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -254,53 +254,6 @@ void MacroAssembler::TruncateHeapNumberToI(Register result_reg,
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::TaggedToI(Register result_reg,
|
||||
Register input_reg,
|
||||
MinusZeroMode minus_zero_mode,
|
||||
Label* lost_precision) {
|
||||
Label done;
|
||||
|
||||
cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
|
||||
isolate()->factory()->heap_number_map());
|
||||
j(not_equal, lost_precision, Label::kNear);
|
||||
|
||||
// TODO(olivf) Converting a number on the fpu is actually quite slow. We
|
||||
// should first try a fast conversion and then bailout to this slow case.
|
||||
Label lost_precision_pop, zero_check;
|
||||
Label* lost_precision_int = (minus_zero_mode == FAIL_ON_MINUS_ZERO)
|
||||
? &lost_precision_pop : lost_precision;
|
||||
sub(esp, Immediate(kPointerSize));
|
||||
fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset));
|
||||
if (minus_zero_mode == FAIL_ON_MINUS_ZERO) fld(0);
|
||||
fist_s(MemOperand(esp, 0));
|
||||
fild_s(MemOperand(esp, 0));
|
||||
FCmp();
|
||||
pop(result_reg);
|
||||
j(not_equal, lost_precision_int, Label::kNear);
|
||||
j(parity_even, lost_precision_int, Label::kNear); // NaN.
|
||||
if (minus_zero_mode == FAIL_ON_MINUS_ZERO) {
|
||||
test(result_reg, Operand(result_reg));
|
||||
j(zero, &zero_check, Label::kNear);
|
||||
fstp(0);
|
||||
jmp(&done, Label::kNear);
|
||||
bind(&zero_check);
|
||||
// To check for minus zero, we load the value again as float, and check
|
||||
// if that is still 0.
|
||||
sub(esp, Immediate(kPointerSize));
|
||||
fstp_s(Operand(esp, 0));
|
||||
pop(result_reg);
|
||||
test(result_reg, Operand(result_reg));
|
||||
j(zero, &done, Label::kNear);
|
||||
jmp(lost_precision, Label::kNear);
|
||||
|
||||
bind(&lost_precision_pop);
|
||||
fstp(0);
|
||||
jmp(lost_precision, Label::kNear);
|
||||
}
|
||||
bind(&done);
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::LoadUint32NoSSE2(Register src) {
|
||||
Label done;
|
||||
push(src);
|
||||
|
@ -447,9 +447,6 @@ class MacroAssembler: public Assembler {
|
||||
void X87TOSToI(Register result_reg, MinusZeroMode minus_zero_mode,
|
||||
Label* conversion_failed, Label::Distance dst = Label::kFar);
|
||||
|
||||
void TaggedToI(Register result_reg, Register input_reg,
|
||||
MinusZeroMode minus_zero_mode, Label* lost_precision);
|
||||
|
||||
// Smi tagging support.
|
||||
void SmiTag(Register reg) {
|
||||
STATIC_ASSERT(kSmiTag == 0);
|
||||
|
Loading…
Reference in New Issue
Block a user