Fix handling of -0 in the unary-op IC and avoid repeated patching/transitions.

When the stub return a heap number we do a state transition to
a version HEAP_NUMBER that can handle -0.

There is room for further improvement in the typefeedback for the
case of -0. This change however does not address this and only fixes
the acute issue.
Review URL: http://codereview.chromium.org/7037025

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@7944 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 85edb5f9
......@@ -1847,12 +1847,14 @@ void TypeRecordingUnaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) {
void TypeRecordingUnaryOpStub::GenerateHeapNumberStubSub(MacroAssembler* masm) {
Label non_smi, slow;
GenerateSmiCodeSub(masm, &non_smi, &slow);
Label non_smi, slow, call_builtin;
GenerateSmiCodeSub(masm, &non_smi, &call_builtin);
__ bind(&non_smi);
GenerateHeapNumberCodeSub(masm, &slow);
__ bind(&slow);
GenerateTypeTransition(masm);
__ bind(&call_builtin);
GenerateGenericCodeFallback(masm);
}
......
......@@ -622,9 +622,12 @@ void TypeRecordingUnaryOpStub::GenerateSmiStubBitNot(MacroAssembler* masm) {
}
void TypeRecordingUnaryOpStub::GenerateSmiCodeSub(
MacroAssembler* masm, Label* non_smi, Label* undo, Label* slow,
Label::Distance non_smi_near, Label::Distance undo_near,
void TypeRecordingUnaryOpStub::GenerateSmiCodeSub(MacroAssembler* masm,
Label* non_smi,
Label* undo,
Label* slow,
Label::Distance non_smi_near,
Label::Distance undo_near,
Label::Distance slow_near) {
// Check whether the value is a smi.
__ test(eax, Immediate(kSmiTagMask));
......@@ -679,14 +682,16 @@ void TypeRecordingUnaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) {
void TypeRecordingUnaryOpStub::GenerateHeapNumberStubSub(MacroAssembler* masm) {
Label non_smi, undo, slow;
GenerateSmiCodeSub(masm, &non_smi, &undo, &slow, Label::kNear);
Label non_smi, undo, slow, call_builtin;
GenerateSmiCodeSub(masm, &non_smi, &undo, &call_builtin, Label::kNear);
__ bind(&non_smi);
GenerateHeapNumberCodeSub(masm, &slow);
__ bind(&undo);
GenerateSmiCodeUndo(masm);
__ bind(&slow);
GenerateTypeTransition(masm);
__ bind(&call_builtin);
GenerateGenericCodeFallback(masm);
}
......
......@@ -2200,9 +2200,23 @@ TRUnaryOpIC::TypeInfo TRUnaryOpIC::GetTypeInfo(Handle<Object> operand) {
}
TRUnaryOpIC::TypeInfo TRUnaryOpIC::JoinTypes(TRUnaryOpIC::TypeInfo x,
TRUnaryOpIC::TypeInfo y) {
return x >= y ? x : y;
TRUnaryOpIC::TypeInfo TRUnaryOpIC::ComputeNewType(
TRUnaryOpIC::TypeInfo type,
TRUnaryOpIC::TypeInfo previous) {
switch (previous) {
case TRUnaryOpIC::UNINITIALIZED:
return type;
case TRUnaryOpIC::SMI:
return (type == TRUnaryOpIC::GENERIC)
? TRUnaryOpIC::GENERIC
: TRUnaryOpIC::HEAP_NUMBER;
case TRUnaryOpIC::HEAP_NUMBER:
return TRUnaryOpIC::GENERIC;
case TRUnaryOpIC::GENERIC:
// We should never do patching if we are in GENERIC state.
UNREACHABLE();
return TRUnaryOpIC::GENERIC;
}
}
......@@ -2314,7 +2328,7 @@ RUNTIME_FUNCTION(MaybeObject*, TypeRecordingUnaryOp_Patch) {
static_cast<TRUnaryOpIC::TypeInfo>(Smi::cast(args[3])->value());
TRUnaryOpIC::TypeInfo type = TRUnaryOpIC::GetTypeInfo(operand);
type = TRUnaryOpIC::JoinTypes(type, previous_type);
type = TRUnaryOpIC::ComputeNewType(type, previous_type);
Handle<Code> code = GetTypeRecordingUnaryOpStub(key, type);
if (!code.is_null()) {
......
......@@ -643,7 +643,7 @@ class TRUnaryOpIC: public IC {
static TypeInfo GetTypeInfo(Handle<Object> operand);
static TypeInfo JoinTypes(TypeInfo x, TypeInfo y);
static TypeInfo ComputeNewType(TypeInfo type, TypeInfo previous);
};
......
......@@ -524,12 +524,14 @@ void TypeRecordingUnaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) {
void TypeRecordingUnaryOpStub::GenerateHeapNumberStubSub(MacroAssembler* masm) {
Label non_smi, slow;
GenerateSmiCodeSub(masm, &non_smi, &slow, Label::kNear);
Label non_smi, slow, call_builtin;
GenerateSmiCodeSub(masm, &non_smi, &call_builtin, Label::kNear);
__ bind(&non_smi);
GenerateHeapNumberCodeSub(masm, &slow);
__ bind(&slow);
GenerateTypeTransition(masm);
__ bind(&call_builtin);
GenerateGenericCodeFallback(masm);
}
......
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