Fix handling of -0 in the unary-op IC and avoid repeated patching/transitions.
authorfschneider@chromium.org <fschneider@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 18 May 2011 17:32:36 +0000 (17:32 +0000)
committerfschneider@chromium.org <fschneider@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 18 May 2011 17:32:36 +0000 (17:32 +0000)
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

src/arm/code-stubs-arm.cc
src/ia32/code-stubs-ia32.cc
src/ic.cc
src/ic.h
src/x64/code-stubs-x64.cc

index d510232409201125fcde2eebf70744eb54399e17..efec81fc0e046ac24da4413842cd54d4750dfcba 100644 (file)
@@ -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);
 }
 
 
index a382f7e7cc4f8532c177e5975551e0efb8f524db..ac0b64525ac1a7cac410ada0bb2415eeed05f8ca 100644 (file)
@@ -622,10 +622,13 @@ 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,
-    Label::Distance slow_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));
   __ j(not_zero, non_smi, non_smi_near);
@@ -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);
 }
 
 
index 458018dd1290fc73ba0b7ec84ecd76189d767ffb..8152acbf5c4272ba556ac694b4a7fa7fb62a7b5b 100644 (file)
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -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()) {
index bf03fd9423b7e40102daf7e3c917e7805d496e81..461f8b79a5b4555b233530ddf84d6a1c08f3389d 100644 (file)
--- a/src/ic.h
+++ b/src/ic.h
@@ -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);
 };
 
 
index 3dc86cca000137134c5a5c6c0a64f10d095f6c10..a53505d935213b5ad57082f1b0fdf63c4d259f6d 100644 (file)
@@ -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);
 }