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) { ...@@ -1847,12 +1847,14 @@ void TypeRecordingUnaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) {
void TypeRecordingUnaryOpStub::GenerateHeapNumberStubSub(MacroAssembler* masm) { void TypeRecordingUnaryOpStub::GenerateHeapNumberStubSub(MacroAssembler* masm) {
Label non_smi, slow; Label non_smi, slow, call_builtin;
GenerateSmiCodeSub(masm, &non_smi, &slow); GenerateSmiCodeSub(masm, &non_smi, &call_builtin);
__ bind(&non_smi); __ bind(&non_smi);
GenerateHeapNumberCodeSub(masm, &slow); GenerateHeapNumberCodeSub(masm, &slow);
__ bind(&slow); __ bind(&slow);
GenerateTypeTransition(masm); GenerateTypeTransition(masm);
__ bind(&call_builtin);
GenerateGenericCodeFallback(masm);
} }
......
...@@ -622,10 +622,13 @@ void TypeRecordingUnaryOpStub::GenerateSmiStubBitNot(MacroAssembler* masm) { ...@@ -622,10 +622,13 @@ void TypeRecordingUnaryOpStub::GenerateSmiStubBitNot(MacroAssembler* masm) {
} }
void TypeRecordingUnaryOpStub::GenerateSmiCodeSub( void TypeRecordingUnaryOpStub::GenerateSmiCodeSub(MacroAssembler* masm,
MacroAssembler* masm, Label* non_smi, Label* undo, Label* slow, Label* non_smi,
Label::Distance non_smi_near, Label::Distance undo_near, Label* undo,
Label::Distance slow_near) { Label* slow,
Label::Distance non_smi_near,
Label::Distance undo_near,
Label::Distance slow_near) {
// Check whether the value is a smi. // Check whether the value is a smi.
__ test(eax, Immediate(kSmiTagMask)); __ test(eax, Immediate(kSmiTagMask));
__ j(not_zero, non_smi, non_smi_near); __ j(not_zero, non_smi, non_smi_near);
...@@ -679,14 +682,16 @@ void TypeRecordingUnaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) { ...@@ -679,14 +682,16 @@ void TypeRecordingUnaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) {
void TypeRecordingUnaryOpStub::GenerateHeapNumberStubSub(MacroAssembler* masm) { void TypeRecordingUnaryOpStub::GenerateHeapNumberStubSub(MacroAssembler* masm) {
Label non_smi, undo, slow; Label non_smi, undo, slow, call_builtin;
GenerateSmiCodeSub(masm, &non_smi, &undo, &slow, Label::kNear); GenerateSmiCodeSub(masm, &non_smi, &undo, &call_builtin, Label::kNear);
__ bind(&non_smi); __ bind(&non_smi);
GenerateHeapNumberCodeSub(masm, &slow); GenerateHeapNumberCodeSub(masm, &slow);
__ bind(&undo); __ bind(&undo);
GenerateSmiCodeUndo(masm); GenerateSmiCodeUndo(masm);
__ bind(&slow); __ bind(&slow);
GenerateTypeTransition(masm); GenerateTypeTransition(masm);
__ bind(&call_builtin);
GenerateGenericCodeFallback(masm);
} }
......
...@@ -2200,9 +2200,23 @@ TRUnaryOpIC::TypeInfo TRUnaryOpIC::GetTypeInfo(Handle<Object> operand) { ...@@ -2200,9 +2200,23 @@ TRUnaryOpIC::TypeInfo TRUnaryOpIC::GetTypeInfo(Handle<Object> operand) {
} }
TRUnaryOpIC::TypeInfo TRUnaryOpIC::JoinTypes(TRUnaryOpIC::TypeInfo x, TRUnaryOpIC::TypeInfo TRUnaryOpIC::ComputeNewType(
TRUnaryOpIC::TypeInfo y) { TRUnaryOpIC::TypeInfo type,
return x >= y ? x : y; 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) { ...@@ -2314,7 +2328,7 @@ RUNTIME_FUNCTION(MaybeObject*, TypeRecordingUnaryOp_Patch) {
static_cast<TRUnaryOpIC::TypeInfo>(Smi::cast(args[3])->value()); static_cast<TRUnaryOpIC::TypeInfo>(Smi::cast(args[3])->value());
TRUnaryOpIC::TypeInfo type = TRUnaryOpIC::GetTypeInfo(operand); TRUnaryOpIC::TypeInfo type = TRUnaryOpIC::GetTypeInfo(operand);
type = TRUnaryOpIC::JoinTypes(type, previous_type); type = TRUnaryOpIC::ComputeNewType(type, previous_type);
Handle<Code> code = GetTypeRecordingUnaryOpStub(key, type); Handle<Code> code = GetTypeRecordingUnaryOpStub(key, type);
if (!code.is_null()) { if (!code.is_null()) {
......
...@@ -643,7 +643,7 @@ class TRUnaryOpIC: public IC { ...@@ -643,7 +643,7 @@ class TRUnaryOpIC: public IC {
static TypeInfo GetTypeInfo(Handle<Object> operand); 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) { ...@@ -524,12 +524,14 @@ void TypeRecordingUnaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) {
void TypeRecordingUnaryOpStub::GenerateHeapNumberStubSub(MacroAssembler* masm) { void TypeRecordingUnaryOpStub::GenerateHeapNumberStubSub(MacroAssembler* masm) {
Label non_smi, slow; Label non_smi, slow, call_builtin;
GenerateSmiCodeSub(masm, &non_smi, &slow, Label::kNear); GenerateSmiCodeSub(masm, &non_smi, &call_builtin, Label::kNear);
__ bind(&non_smi); __ bind(&non_smi);
GenerateHeapNumberCodeSub(masm, &slow); GenerateHeapNumberCodeSub(masm, &slow);
__ bind(&slow); __ bind(&slow);
GenerateTypeTransition(masm); 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