Revision: 9618
Author:   [email protected]
Date:     Fri Oct 14 00:45:18 2011
Log: Eliminate write barrier for global stores at compile time if value stored is a smi.

Omit smi check inside write barriers if the value is known to be a heap object.

Refine inferred types of some instructions.
Review URL: http://codereview.chromium.org/8256016
http://code.google.com/p/v8/source/detail?r=9618

Modified:
 /branches/bleeding_edge/src/arm/lithium-arm.h
 /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc
 /branches/bleeding_edge/src/arm/lithium-codegen-arm.h
 /branches/bleeding_edge/src/hydrogen-instructions.cc
 /branches/bleeding_edge/src/hydrogen-instructions.h
 /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc
 /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.h
 /branches/bleeding_edge/src/ia32/lithium-ia32.h
 /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc
 /branches/bleeding_edge/src/x64/lithium-codegen-x64.h
 /branches/bleeding_edge/src/x64/lithium-x64.h

=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.h       Tue Sep 20 00:14:30 2011
+++ /branches/bleeding_edge/src/arm/lithium-arm.h       Fri Oct 14 00:45:18 2011
@@ -1260,7 +1260,6 @@
   LOperand* context() { return InputAt(0); }
   LOperand* value() { return InputAt(1); }
   int slot_index() { return hydrogen()->slot_index(); }
-  int needs_write_barrier() { return hydrogen()->NeedsWriteBarrier(); }

   virtual void PrintDataTo(StringStream* stream);
 };
@@ -1561,7 +1560,6 @@
   Handle<Object> name() const { return hydrogen()->name(); }
   bool is_in_object() { return hydrogen()->is_in_object(); }
   int offset() { return hydrogen()->offset(); }
-  bool needs_write_barrier() { return hydrogen()->NeedsWriteBarrier(); }
   Handle<Map> transition() const { return hydrogen()->transition(); }
 };

=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Wed Oct 5 03:50:24 2011 +++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Fri Oct 14 00:45:18 2011
@@ -2251,13 +2251,19 @@
__ str(value, FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset));

   // Cells are always in the remembered set.
-  __ RecordWriteField(scratch,
-                      JSGlobalPropertyCell::kValueOffset,
-                      value,
-                      scratch2,
-                      kLRHasBeenSaved,
-                      kSaveFPRegs,
-                      OMIT_REMEMBERED_SET);
+  if (instr->hydrogen()->NeedsWriteBarrier()) {
+    HType type = instr->hydrogen()->value()->type();
+    SmiCheck check_needed =
+        type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
+    __ RecordWriteField(scratch,
+                        JSGlobalPropertyCell::kValueOffset,
+                        value,
+                        scratch2,
+                        kLRHasBeenSaved,
+                        kSaveFPRegs,
+                        OMIT_REMEMBERED_SET,
+                        check_needed);
+  }
 }


@@ -2285,13 +2291,18 @@
   Register value = ToRegister(instr->value());
   MemOperand target = ContextOperand(context, instr->slot_index());
   __ str(value, target);
-  if (instr->needs_write_barrier()) {
+  if (instr->hydrogen()->NeedsWriteBarrier()) {
+    HType type = instr->hydrogen()->value()->type();
+    SmiCheck check_needed =
+        type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
     __ RecordWriteContextSlot(context,
                               target.offset(),
                               value,
                               scratch0(),
                               kLRHasBeenSaved,
-                              kSaveFPRegs);
+                              kSaveFPRegs,
+                              EMIT_REMEMBERED_SET,
+                              check_needed);
   }
 }

@@ -3297,21 +3308,36 @@
   }

   // Do the store.
+  HType type = instr->hydrogen()->value()->type();
+  SmiCheck check_needed =
+      type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
   if (instr->is_in_object()) {
     __ str(value, FieldMemOperand(object, offset));
-    if (instr->needs_write_barrier()) {
+    if (instr->hydrogen()->NeedsWriteBarrier()) {
       // Update the write barrier for the object for in-object properties.
-      __ RecordWriteField(
-          object, offset, value, scratch, kLRHasBeenSaved, kSaveFPRegs);
+      __ RecordWriteField(object,
+                          offset,
+                          value,
+                          scratch,
+                          kLRHasBeenSaved,
+                          kSaveFPRegs,
+                          EMIT_REMEMBERED_SET,
+                          check_needed);
     }
   } else {
     __ ldr(scratch, FieldMemOperand(object, JSObject::kPropertiesOffset));
     __ str(value, FieldMemOperand(scratch, offset));
-    if (instr->needs_write_barrier()) {
+    if (instr->hydrogen()->NeedsWriteBarrier()) {
       // Update the write barrier for the properties array.
       // object is used as a scratch register.
-      __ RecordWriteField(
-          scratch, offset, value, object, kLRHasBeenSaved, kSaveFPRegs);
+      __ RecordWriteField(scratch,
+                          offset,
+                          value,
+                          object,
+                          kLRHasBeenSaved,
+                          kSaveFPRegs,
+                          EMIT_REMEMBERED_SET,
+                          check_needed);
     }
   }
 }
@@ -3362,9 +3388,18 @@
   }

   if (instr->hydrogen()->NeedsWriteBarrier()) {
+    HType type = instr->hydrogen()->value()->type();
+    SmiCheck check_needed =
+        type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
     // Compute address of modified element and store it into key register.
__ add(key, scratch, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
-    __ RecordWrite(elements, key, value, kLRHasBeenSaved, kSaveFPRegs);
+    __ RecordWrite(elements,
+                   key,
+                   value,
+                   kLRHasBeenSaved,
+                   kSaveFPRegs,
+                   EMIT_REMEMBERED_SET,
+                   check_needed);
   }
 }

@@ -4349,8 +4384,9 @@
                                                   false_label,
                                                   input,
                                                   instr->type_literal());
-
-  EmitBranch(true_block, false_block, final_branch_condition);
+  if (final_branch_condition != kNoCondition) {
+    EmitBranch(true_block, false_block, final_branch_condition);
+  }
 }


@@ -4420,9 +4456,7 @@
     final_branch_condition = eq;

   } else {
-    final_branch_condition = ne;
     __ b(false_label);
-    // A dead branch instruction will be generated after this point.
   }

   return final_branch_condition;
=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.h Mon Sep 26 02:32:10 2011 +++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.h Fri Oct 14 00:45:18 2011
@@ -272,8 +272,10 @@
   // Emits optimized code for typeof x == "y".  Modifies input register.
   // Returns the condition on which a final split to
   // true and false label should be made, to optimize fallthrough.
-  Condition EmitTypeofIs(Label* true_label, Label* false_label,
-                         Register input, Handle<String> type_name);
+  Condition EmitTypeofIs(Label* true_label,
+                         Label* false_label,
+                         Register input,
+                         Handle<String> type_name);

   // Emits optimized code for %_IsObject(x).  Preserves input register.
   // Returns the condition on which a final split to
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.cc Wed Sep 28 07:01:40 2011 +++ /branches/bleeding_edge/src/hydrogen-instructions.cc Fri Oct 14 00:45:18 2011
@@ -1744,6 +1744,12 @@
 HType HInstanceOfKnownGlobal::CalculateInferredType() {
   return HType::Boolean();
 }
+
+
+HType HChange::CalculateInferredType() {
+  if (from().IsDouble() && to().IsTagged()) return HType::HeapNumber();
+  return type();
+}


 HType HBitwiseBinaryOperation::CalculateInferredType() {
@@ -1799,6 +1805,31 @@
 HType HSar::CalculateInferredType() {
   return HType::TaggedNumber();
 }
+
+
+HType HStringCharFromCode::CalculateInferredType() {
+  return HType::String();
+}
+
+
+HType HArrayLiteral::CalculateInferredType() {
+  return HType::JSArray();
+}
+
+
+HType HObjectLiteral::CalculateInferredType() {
+  return HType::JSObject();
+}
+
+
+HType HRegExpLiteral::CalculateInferredType() {
+  return HType::JSObject();
+}
+
+
+HType HFunctionLiteral::CalculateInferredType() {
+  return HType::JSObject();
+}


 HValue* HUnaryMathOperation::EnsureAndPropagateNotMinusZero(
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.h Wed Sep 28 07:01:40 2011 +++ /branches/bleeding_edge/src/hydrogen-instructions.h Fri Oct 14 00:45:18 2011
@@ -396,6 +396,11 @@
   bool IsUninitialized() {
     return type_ == kUninitialized;
   }
+
+  bool IsHeapObject() {
+    ASSERT(type_ != kUninitialized);
+    return IsHeapNumber() || IsString() || IsNonPrimitive();
+  }

   static HType TypeFromValue(Handle<Object> value);

@@ -1101,12 +1106,14 @@
     ASSERT(!value->representation().IsNone() && !to.IsNone());
     ASSERT(!value->representation().Equals(to));
     set_representation(to);
+    set_type(HType::TaggedNumber());
     SetFlag(kUseGVN);
     if (deoptimize_on_undefined) SetFlag(kDeoptimizeOnUndefined);
     if (is_truncating) SetFlag(kTruncatingToInt32);
   }

   virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
+  virtual HType CalculateInferredType();

   Representation from() { return value()->representation(); }
   Representation to() { return representation(); }
@@ -3260,6 +3267,13 @@
 };


+static inline bool StoringValueNeedsWriteBarrier(HValue* value) {
+  return !value->type().IsBoolean()
+      && !value->type().IsSmi()
+ && !(value->IsConstant() && HConstant::cast(value)->ImmortalImmovable());
+}
+
+
 class HStoreGlobalCell: public HUnaryOperation {
  public:
   HStoreGlobalCell(HValue* value,
@@ -3275,6 +3289,9 @@
   bool RequiresHoleCheck() {
     return !details_.IsDontDelete() || details_.IsReadOnly();
   }
+  bool NeedsWriteBarrier() {
+    return StoringValueNeedsWriteBarrier(value());
+  }

   virtual Representation RequiredInputRepresentation(int index) {
     return Representation::Tagged();
@@ -3355,13 +3372,6 @@
 };


-static inline bool StoringValueNeedsWriteBarrier(HValue* value) {
-  return !value->type().IsBoolean()
-      && !value->type().IsSmi()
- && !(value->IsConstant() && HConstant::cast(value)->ImmortalImmovable());
-}
-
-
 class HStoreContextSlot: public HTemplateInstruction<2> {
  public:
   HStoreContextSlot(HValue* context, int slot_index, HValue* value)
@@ -3948,7 +3958,7 @@
   HStringCharFromCode(HValue* context, HValue* char_code) {
     SetOperandAt(0, context);
     SetOperandAt(1, char_code);
-     set_representation(Representation::Tagged());
+    set_representation(Representation::Tagged());
     SetFlag(kUseGVN);
   }

@@ -3957,6 +3967,7 @@
         ? Representation::Tagged()
         : Representation::Integer32();
   }
+  virtual HType CalculateInferredType();

   HValue* context() { return OperandAt(0); }
   HValue* value() { return OperandAt(1); }
@@ -4034,6 +4045,7 @@
   virtual Representation RequiredInputRepresentation(int index) {
     return Representation::Tagged();
   }
+  virtual HType CalculateInferredType();

   DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral)

@@ -4068,6 +4080,7 @@
   virtual Representation RequiredInputRepresentation(int index) {
     return Representation::Tagged();
   }
+  virtual HType CalculateInferredType();

   DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral)

@@ -4097,6 +4110,7 @@
   virtual Representation RequiredInputRepresentation(int index) {
     return Representation::Tagged();
   }
+  virtual HType CalculateInferredType();

   DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral)

@@ -4121,6 +4135,7 @@
   virtual Representation RequiredInputRepresentation(int index) {
     return Representation::Tagged();
   }
+  virtual HType CalculateInferredType();

   DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral)

=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Tue Sep 27 06:03:19 2011 +++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Fri Oct 14 00:45:18 2011
@@ -2116,12 +2116,18 @@
   __ mov(FieldOperand(object, offset), value);

   // Cells are always in the remembered set.
-  __ RecordWriteField(object,
-                      offset,
-                      value,
-                      address,
-                      kSaveFPRegs,
-                      OMIT_REMEMBERED_SET);
+  if (instr->hydrogen()->NeedsWriteBarrier()) {
+    HType type = instr->hydrogen()->value()->type();
+    SmiCheck check_needed =
+        type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
+    __ RecordWriteField(object,
+                        offset,
+                        value,
+                        address,
+                        kSaveFPRegs,
+                        OMIT_REMEMBERED_SET,
+                        check_needed);
+  }
 }


@@ -2149,10 +2155,19 @@
   Register context = ToRegister(instr->context());
   Register value = ToRegister(instr->value());
   __ mov(ContextOperand(context, instr->slot_index()), value);
-  if (instr->needs_write_barrier()) {
+  if (instr->hydrogen()->NeedsWriteBarrier()) {
+    HType type = instr->hydrogen()->value()->type();
+    SmiCheck check_needed =
+        type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
     Register temp = ToRegister(instr->TempAt(0));
     int offset = Context::SlotOffset(instr->slot_index());
-    __ RecordWriteContextSlot(context, offset, value, temp, kSaveFPRegs);
+    __ RecordWriteContextSlot(context,
+                              offset,
+                              value,
+                              temp,
+                              kSaveFPRegs,
+                              EMIT_REMEMBERED_SET,
+                              check_needed);
   }
 }

@@ -3146,21 +3161,36 @@
   }

   // Do the store.
+  HType type = instr->hydrogen()->value()->type();
+  SmiCheck check_needed =
+      type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
   if (instr->is_in_object()) {
     __ mov(FieldOperand(object, offset), value);
-    if (instr->needs_write_barrier()) {
+    if (instr->hydrogen()->NeedsWriteBarrier()) {
       Register temp = ToRegister(instr->TempAt(0));
       // Update the write barrier for the object for in-object properties.
-      __ RecordWriteField(object, offset, value, temp, kSaveFPRegs);
+      __ RecordWriteField(object,
+                          offset,
+                          value,
+                          temp,
+                          kSaveFPRegs,
+                          EMIT_REMEMBERED_SET,
+                          check_needed);
     }
   } else {
     Register temp = ToRegister(instr->TempAt(0));
     __ mov(temp, FieldOperand(object, JSObject::kPropertiesOffset));
     __ mov(FieldOperand(temp, offset), value);
-    if (instr->needs_write_barrier()) {
+    if (instr->hydrogen()->NeedsWriteBarrier()) {
       // Update the write barrier for the properties array.
       // object is used as a scratch register.
-      __ RecordWriteField(temp, offset, value, object, kSaveFPRegs);
+      __ RecordWriteField(temp,
+                          offset,
+                          value,
+                          object,
+                          kSaveFPRegs,
+                          EMIT_REMEMBERED_SET,
+                          check_needed);
     }
   }
 }
@@ -3259,13 +3289,21 @@
   }

   if (instr->hydrogen()->NeedsWriteBarrier()) {
+    HType type = instr->hydrogen()->value()->type();
+    SmiCheck check_needed =
+        type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
     // Compute address of modified element and store it into key register.
     __ lea(key,
            FieldOperand(elements,
                         key,
                         times_pointer_size,
                         FixedArray::kHeaderSize));
-    __ RecordWrite(elements, key, value, kSaveFPRegs);
+    __ RecordWrite(elements,
+                   key,
+                   value,
+                   kSaveFPRegs,
+                   EMIT_REMEMBERED_SET,
+                   check_needed);
   }
 }

@@ -4247,12 +4285,11 @@
   Label* true_label = chunk_->GetAssemblyLabel(true_block);
   Label* false_label = chunk_->GetAssemblyLabel(false_block);

-  Condition final_branch_condition = EmitTypeofIs(true_label,
-                                                  false_label,
-                                                  input,
-                                                  instr->type_literal());
-
-  EmitBranch(true_block, false_block, final_branch_condition);
+  Condition final_branch_condition =
+      EmitTypeofIs(true_label, false_label, input, instr->type_literal());
+  if (final_branch_condition != no_condition) {
+    EmitBranch(true_block, false_block, final_branch_condition);
+  }
 }


@@ -4319,11 +4356,8 @@
     final_branch_condition = zero;

   } else {
-    final_branch_condition = not_equal;
     __ jmp(false_label);
-    // A dead branch instruction will be generated after this point.
-  }
-
+  }
   return final_branch_condition;
 }

=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.h Mon Sep 26 02:32:10 2011 +++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.h Fri Oct 14 00:45:18 2011
@@ -270,8 +270,10 @@
   // Emits optimized code for typeof x == "y".  Modifies input register.
   // Returns the condition on which a final split to
   // true and false label should be made, to optimize fallthrough.
-  Condition EmitTypeofIs(Label* true_label, Label* false_label,
-                         Register input, Handle<String> type_name);
+  Condition EmitTypeofIs(Label* true_label,
+                         Label* false_label,
+                         Register input,
+                         Handle<String> type_name);

   // Emits optimized code for %_IsObject(x).  Preserves input register.
   // Returns the condition on which a final split to
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-ia32.h     Tue Sep 27 04:42:02 2011
+++ /branches/bleeding_edge/src/ia32/lithium-ia32.h     Fri Oct 14 00:45:18 2011
@@ -1295,7 +1295,6 @@
   LOperand* context() { return InputAt(0); }
   LOperand* value() { return InputAt(1); }
   int slot_index() { return hydrogen()->slot_index(); }
-  int needs_write_barrier() { return hydrogen()->NeedsWriteBarrier(); }

   virtual void PrintDataTo(StringStream* stream);
 };
@@ -1617,7 +1616,6 @@
   Handle<Object> name() const { return hydrogen()->name(); }
   bool is_in_object() { return hydrogen()->is_in_object(); }
   int offset() { return hydrogen()->offset(); }
-  bool needs_write_barrier() { return hydrogen()->NeedsWriteBarrier(); }
   Handle<Map> transition() const { return hydrogen()->transition(); }
 };

=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Tue Sep 27 06:03:19 2011 +++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Fri Oct 14 00:45:18 2011
@@ -2055,19 +2055,24 @@
   // Store the value.
   __ movq(Operand(address, 0), value);

-  Label smi_store;
-  __ JumpIfSmi(value, &smi_store, Label::kNear);
-
-  int offset = JSGlobalPropertyCell::kValueOffset - kHeapObjectTag;
-  __ lea(object, Operand(address, -offset));
-  // Cells are always in the remembered set.
-  __ RecordWrite(object,
-                 address,
-                 value,
-                 kSaveFPRegs,
-                 OMIT_REMEMBERED_SET,
-                 OMIT_SMI_CHECK);
-  __ bind(&smi_store);
+  if (instr->hydrogen()->NeedsWriteBarrier()) {
+    Label smi_store;
+    HType type = instr->hydrogen()->value()->type();
+ if (!type.IsHeapNumber() && !type.IsString() && !type.IsNonPrimitive()) {
+      __ JumpIfSmi(value, &smi_store, Label::kNear);
+    }
+
+    int offset = JSGlobalPropertyCell::kValueOffset - kHeapObjectTag;
+    __ lea(object, Operand(address, -offset));
+    // Cells are always in the remembered set.
+    __ RecordWrite(object,
+                   address,
+                   value,
+                   kSaveFPRegs,
+                   OMIT_REMEMBERED_SET,
+                   OMIT_SMI_CHECK);
+    __ bind(&smi_store);
+  }
 }


@@ -2094,10 +2099,19 @@
   Register context = ToRegister(instr->context());
   Register value = ToRegister(instr->value());
   __ movq(ContextOperand(context, instr->slot_index()), value);
-  if (instr->needs_write_barrier()) {
+  if (instr->hydrogen()->NeedsWriteBarrier()) {
+    HType type = instr->hydrogen()->value()->type();
+    SmiCheck check_needed =
+        type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
     int offset = Context::SlotOffset(instr->slot_index());
     Register scratch = ToRegister(instr->TempAt(0));
- __ RecordWriteContextSlot(context, offset, value, scratch, kSaveFPRegs);
+    __ RecordWriteContextSlot(context,
+                              offset,
+                              value,
+                              scratch,
+                              kSaveFPRegs,
+                              EMIT_REMEMBERED_SET,
+                              check_needed);
   }
 }

@@ -3061,21 +3075,36 @@
   }

   // Do the store.
+  HType type = instr->hydrogen()->value()->type();
+  SmiCheck check_needed =
+      type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
   if (instr->is_in_object()) {
     __ movq(FieldOperand(object, offset), value);
-    if (instr->needs_write_barrier()) {
+    if (instr->hydrogen()->NeedsWriteBarrier()) {
       Register temp = ToRegister(instr->TempAt(0));
       // Update the write barrier for the object for in-object properties.
-      __ RecordWriteField(object, offset, value, temp, kSaveFPRegs);
+      __ RecordWriteField(object,
+                          offset,
+                          value,
+                          temp,
+                          kSaveFPRegs,
+                          EMIT_REMEMBERED_SET,
+                          check_needed);
     }
   } else {
     Register temp = ToRegister(instr->TempAt(0));
     __ movq(temp, FieldOperand(object, JSObject::kPropertiesOffset));
     __ movq(FieldOperand(temp, offset), value);
-    if (instr->needs_write_barrier()) {
+    if (instr->hydrogen()->NeedsWriteBarrier()) {
       // Update the write barrier for the properties array.
       // object is used as a scratch register.
-      __ RecordWriteField(temp, offset, value, object, kSaveFPRegs);
+      __ RecordWriteField(temp,
+                          offset,
+                          value,
+                          object,
+                          kSaveFPRegs,
+                          EMIT_REMEMBERED_SET,
+                          check_needed);
     }
   }
 }
@@ -3182,12 +3211,20 @@
   }

   if (instr->hydrogen()->NeedsWriteBarrier()) {
+    HType type = instr->hydrogen()->value()->type();
+    SmiCheck check_needed =
+        type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
     // Compute address of modified element and store it into key register.
     __ lea(key, FieldOperand(elements,
                              key,
                              times_pointer_size,
                              FixedArray::kHeaderSize));
-    __ RecordWrite(elements, key, value, kSaveFPRegs);
+    __ RecordWrite(elements,
+                   key,
+                   value,
+                   kSaveFPRegs,
+                   EMIT_REMEMBERED_SET,
+                   check_needed);
   }
 }

@@ -3975,12 +4012,11 @@
   Label* true_label = chunk_->GetAssemblyLabel(true_block);
   Label* false_label = chunk_->GetAssemblyLabel(false_block);

-  Condition final_branch_condition = EmitTypeofIs(true_label,
-                                                  false_label,
-                                                  input,
-                                                  instr->type_literal());
-
-  EmitBranch(true_block, false_block, final_branch_condition);
+  Condition final_branch_condition =
+      EmitTypeofIs(true_label, false_label, input, instr->type_literal());
+  if (final_branch_condition != no_condition) {
+    EmitBranch(true_block, false_block, final_branch_condition);
+  }
 }


@@ -4048,7 +4084,6 @@
     final_branch_condition = zero;

   } else {
-    final_branch_condition = never;
     __ jmp(false_label);
   }

=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.h Mon Sep 26 02:32:10 2011 +++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.h Fri Oct 14 00:45:18 2011
@@ -260,8 +260,10 @@
   // Emits optimized code for typeof x == "y".  Modifies input register.
   // Returns the condition on which a final split to
   // true and false label should be made, to optimize fallthrough.
-  Condition EmitTypeofIs(Label* true_label, Label* false_label,
-                         Register input, Handle<String> type_name);
+  Condition EmitTypeofIs(Label* true_label,
+                         Label* false_label,
+                         Register input,
+                         Handle<String> type_name);

   // Emits optimized code for %_IsObject(x).  Preserves input register.
   // Returns the condition on which a final split to
=======================================
--- /branches/bleeding_edge/src/x64/lithium-x64.h       Wed Sep 21 07:46:54 2011
+++ /branches/bleeding_edge/src/x64/lithium-x64.h       Fri Oct 14 00:45:18 2011
@@ -1260,7 +1260,6 @@
   LOperand* context() { return InputAt(0); }
   LOperand* value() { return InputAt(1); }
   int slot_index() { return hydrogen()->slot_index(); }
-  int needs_write_barrier() { return hydrogen()->NeedsWriteBarrier(); }

   virtual void PrintDataTo(StringStream* stream);
 };
@@ -1551,7 +1550,6 @@
   Handle<Object> name() const { return hydrogen()->name(); }
   bool is_in_object() { return hydrogen()->is_in_object(); }
   int offset() { return hydrogen()->offset(); }
-  bool needs_write_barrier() { return hydrogen()->NeedsWriteBarrier(); }
   Handle<Map> transition() const { return hydrogen()->transition(); }
 };

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to