Revision: 16403
Author:   [email protected]
Date:     Wed Aug 28 14:16:57 2013 UTC
Log:      Implement proper map checks of captured objects.

[email protected]
TEST=mjsunit/compiler/escape-analysis

Review URL: https://codereview.chromium.org/23697002
http://code.google.com/p/v8/source/detail?r=16403

Modified:
 /branches/bleeding_edge/src/arm/lithium-arm.cc
 /branches/bleeding_edge/src/arm/lithium-arm.h
 /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc
 /branches/bleeding_edge/src/hydrogen-escape-analysis.cc
 /branches/bleeding_edge/src/hydrogen-escape-analysis.h
 /branches/bleeding_edge/src/hydrogen-instructions.cc
 /branches/bleeding_edge/src/hydrogen-instructions.h
 /branches/bleeding_edge/src/hydrogen.cc
 /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc
 /branches/bleeding_edge/src/ia32/lithium-ia32.cc
 /branches/bleeding_edge/src/ia32/lithium-ia32.h
 /branches/bleeding_edge/src/mips/lithium-codegen-mips.cc
 /branches/bleeding_edge/src/mips/lithium-mips.cc
 /branches/bleeding_edge/src/mips/lithium-mips.h
 /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc
 /branches/bleeding_edge/src/x64/lithium-x64.cc
 /branches/bleeding_edge/src/x64/lithium-x64.h
 /branches/bleeding_edge/test/mjsunit/compiler/escape-analysis.js

=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.cc Tue Aug 27 14:02:08 2013 UTC +++ /branches/bleeding_edge/src/arm/lithium-arm.cc Wed Aug 28 14:16:57 2013 UTC
@@ -2027,9 +2027,9 @@
 }


-LInstruction* LChunkBuilder::DoCheckFunction(HCheckFunction* instr) {
+LInstruction* LChunkBuilder::DoCheckValue(HCheckValue* instr) {
   LOperand* value = UseRegisterAtStart(instr->value());
-  return AssignEnvironment(new(zone()) LCheckFunction(value));
+  return AssignEnvironment(new(zone()) LCheckValue(value));
 }


=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.h Tue Aug 27 11:55:08 2013 UTC +++ /branches/bleeding_edge/src/arm/lithium-arm.h Wed Aug 28 14:16:57 2013 UTC
@@ -62,12 +62,12 @@
   V(CallNewArray)                               \
   V(CallRuntime)                                \
   V(CallStub)                                   \
-  V(CheckFunction)                              \
   V(CheckInstanceType)                          \
   V(CheckNonSmi)                                \
   V(CheckMaps)                                  \
   V(CheckMapValue)                              \
   V(CheckSmi)                                   \
+  V(CheckValue)                                 \
   V(ClampDToUint8)                              \
   V(ClampIToUint8)                              \
   V(ClampTToUint8)                              \
@@ -2338,16 +2338,16 @@
 };


-class LCheckFunction V8_FINAL : public LTemplateInstruction<0, 1, 0> {
+class LCheckValue V8_FINAL : public LTemplateInstruction<0, 1, 0> {
  public:
-  explicit LCheckFunction(LOperand* value) {
+  explicit LCheckValue(LOperand* value) {
     inputs_[0] = value;
   }

   LOperand* value() { return inputs_[0]; }

-  DECLARE_CONCRETE_INSTRUCTION(CheckFunction, "check-function")
-  DECLARE_HYDROGEN_ACCESSOR(CheckFunction)
+  DECLARE_CONCRETE_INSTRUCTION(CheckValue, "check-value")
+  DECLARE_HYDROGEN_ACCESSOR(CheckValue)
 };


=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Tue Aug 27 13:55:00 2013 UTC +++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Wed Aug 28 14:16:57 2013 UTC
@@ -5131,18 +5131,18 @@
 }


-void LCodeGen::DoCheckFunction(LCheckFunction* instr) {
+void LCodeGen::DoCheckValue(LCheckValue* instr) {
   Register reg = ToRegister(instr->value());
-  Handle<JSFunction> target = instr->hydrogen()->target();
+  Handle<HeapObject> object = instr->hydrogen()->object();
   AllowDeferredHandleDereference smi_check;
-  if (isolate()->heap()->InNewSpace(*target)) {
+  if (isolate()->heap()->InNewSpace(*object)) {
     Register reg = ToRegister(instr->value());
-    Handle<Cell> cell = isolate()->factory()->NewCell(target);
+    Handle<Cell> cell = isolate()->factory()->NewCell(object);
     __ mov(ip, Operand(Handle<Object>(cell)));
     __ ldr(ip, FieldMemOperand(ip, Cell::kValueOffset));
     __ cmp(reg, ip);
   } else {
-    __ cmp(reg, Operand(target));
+    __ cmp(reg, Operand(object));
   }
   DeoptimizeIf(ne, instr->environment());
 }
=======================================
--- /branches/bleeding_edge/src/hydrogen-escape-analysis.cc Wed Aug 28 12:36:32 2013 UTC +++ /branches/bleeding_edge/src/hydrogen-escape-analysis.cc Wed Aug 28 14:16:57 2013 UTC
@@ -86,7 +86,8 @@

 // Create a new state full of phis for loop header entries.
 HCapturedObject* HEscapeAnalysisPhase::NewStateForLoopHeader(
-    HInstruction* previous, HCapturedObject* old_state) {
+    HInstruction* previous,
+    HCapturedObject* old_state) {
   HBasicBlock* block = previous->block();
   HCapturedObject* state = NewState(previous);
   for (int index = 0; index < number_of_values_; index++) {
@@ -100,7 +101,8 @@

 // Create a new state by copying an existing one.
 HCapturedObject* HEscapeAnalysisPhase::NewStateCopy(
-    HInstruction* previous, HCapturedObject* old_state) {
+    HInstruction* previous,
+    HCapturedObject* old_state) {
   HCapturedObject* state = NewState(previous);
   for (int index = 0; index < number_of_values_; index++) {
     HValue* operand = old_state->OperandAt(index);
@@ -112,8 +114,9 @@

 // Insert a newly created phi into the given block and fill all incoming
 // edges with the given value.
-HPhi* HEscapeAnalysisPhase::NewPhiAndInsert(
-    HBasicBlock* block, HValue* incoming_value, int index) {
+HPhi* HEscapeAnalysisPhase::NewPhiAndInsert(HBasicBlock* block,
+                                            HValue* incoming_value,
+                                            int index) {
   Zone* zone = graph()->zone();
   HPhi* phi = new(zone) HPhi(HPhi::kInvalidMergedIndex, zone);
   for (int i = 0; i < block->predecessors()->length(); i++) {
@@ -122,6 +125,21 @@
   block->AddPhi(phi);
   return phi;
 }
+
+
+// Insert a newly created value check as a replacement for map checks.
+HValue* HEscapeAnalysisPhase::NewMapCheckAndInsert(HCapturedObject* state,
+                                                   HCheckMaps* mapcheck) {
+  Zone* zone = graph()->zone();
+  HValue* value = state->map_value();
+  // TODO(mstarzinger): This will narrow a map check against a set of maps
+  // down to the first element in the set. Revisit and fix this.
+  Handle<Map> map_object = mapcheck->map_set()->first();
+  UniqueValueId map_id = mapcheck->map_unique_ids()->first();
+ HCheckValue* check = HCheckValue::New(zone, NULL, value, map_object, map_id);
+  check->InsertBefore(mapcheck);
+  return check;
+}


 // Performs a forward data-flow analysis of all loads and stores on the
@@ -180,7 +198,7 @@
           if (store->HasObservableSideEffects()) {
             state->ReuseSideEffectsFromStore(store);
           }
-          store->DeleteAndReplaceWith(NULL);
+          store->DeleteAndReplaceWith(store->ActualValue());
           if (FLAG_trace_escape_analysis) {
             PrintF("Replacing store #%d%s\n", instr->id(),
                    store->has_transition() ? " (with transition)" : "");
@@ -199,15 +217,13 @@
         case HValue::kCheckHeapObject: {
           HCheckHeapObject* check = HCheckHeapObject::cast(instr);
           if (check->value() != allocate) continue;
-          check->DeleteAndReplaceWith(NULL);
+          check->DeleteAndReplaceWith(check->ActualValue());
           break;
         }
         case HValue::kCheckMaps: {
           HCheckMaps* mapcheck = HCheckMaps::cast(instr);
           if (mapcheck->value() != allocate) continue;
- // TODO(mstarzinger): This approach breaks if the tracked map value
-          // is not a HConstant. Find a repro test case and fix this.
-          ASSERT(mapcheck->ActualValue() == allocate);
+          NewMapCheckAndInsert(state, mapcheck);
           mapcheck->DeleteAndReplaceWith(mapcheck->ActualValue());
           break;
         }
=======================================
--- /branches/bleeding_edge/src/hydrogen-escape-analysis.h Mon Aug 26 16:43:19 2013 UTC +++ /branches/bleeding_edge/src/hydrogen-escape-analysis.h Wed Aug 28 14:16:57 2013 UTC
@@ -63,6 +63,8 @@

HPhi* NewPhiAndInsert(HBasicBlock* block, HValue* incoming_value, int index);

+ HValue* NewMapCheckAndInsert(HCapturedObject* state, HCheckMaps* mapcheck);
+
   HCapturedObject* StateAt(HBasicBlock* block) {
     return block_states_.at(block->block_id());
   }
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.cc Wed Aug 28 12:35:07 2013 UTC +++ /branches/bleeding_edge/src/hydrogen-instructions.cc Wed Aug 28 14:16:57 2013 UTC
@@ -1451,15 +1451,16 @@
 }


-void HCheckFunction::PrintDataTo(StringStream* stream) {
+void HCheckValue::PrintDataTo(StringStream* stream) {
   value()->PrintNameTo(stream);
-  stream->Add(" %p", *target());
+  stream->Add(" ");
+  object()->ShortPrint(stream);
 }


-HValue* HCheckFunction::Canonicalize() {
+HValue* HCheckValue::Canonicalize() {
   return (value()->IsConstant() &&
-          HConstant::cast(value())->UniqueValueIdsMatch(target_unique_id_))
+          HConstant::cast(value())->UniqueValueIdsMatch(object_unique_id_))
       ? NULL
       : this;
 }
@@ -4052,7 +4053,7 @@
 }


-void HCheckFunction::Verify() {
+void HCheckValue::Verify() {
   HInstruction::Verify();
   ASSERT(HasNoUses());
 }
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.h Wed Aug 28 12:36:32 2013 UTC +++ /branches/bleeding_edge/src/hydrogen-instructions.h Wed Aug 28 14:16:57 2013 UTC
@@ -88,12 +88,12 @@
   V(CallStub)                                  \
   V(CapturedObject)                            \
   V(Change)                                    \
-  V(CheckFunction)                             \
   V(CheckHeapObject)                           \
   V(CheckInstanceType)                         \
   V(CheckMaps)                                 \
   V(CheckMapValue)                             \
   V(CheckSmi)                                  \
+  V(CheckValue)                                \
   V(ClampToUint8)                              \
   V(ClassOfTestAndBranch)                      \
   V(CompareNumericAndBranch)                   \
@@ -2562,6 +2562,7 @@

   HValue* value() { return OperandAt(0); }
   SmallMapList* map_set() { return &map_set_; }
+  ZoneList<UniqueValueId>* map_unique_ids() { return &map_unique_ids_; }

   bool has_migration_target() {
     return has_migration_target_;
@@ -2630,9 +2631,20 @@
 };


-class HCheckFunction V8_FINAL : public HUnaryOperation {
+class HCheckValue V8_FINAL : public HUnaryOperation {
  public:
- DECLARE_INSTRUCTION_FACTORY_P2(HCheckFunction, HValue*, Handle<JSFunction>);
+  static HCheckValue* New(Zone* zone, HValue* context,
+                          HValue* value, Handle<JSFunction> target) {
+    bool in_new_space = Isolate::Current()->heap()->InNewSpace(*target);
+ HCheckValue* check = new(zone) HCheckValue(value, target, in_new_space);
+    return check;
+  }
+  static HCheckValue* New(Zone* zone, HValue* context,
+ HValue* value, Handle<Map> map, UniqueValueId id) {
+    HCheckValue* check = new(zone) HCheckValue(value, map, false);
+    check->object_unique_id_ = id;
+    return check;
+  }

virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
     return Representation::Tagged();
@@ -2646,32 +2658,31 @@
 #endif

   virtual void FinalizeUniqueValueId() V8_OVERRIDE {
-    target_unique_id_ = UniqueValueId(target_);
+    object_unique_id_ = UniqueValueId(object_);
   }

-  Handle<JSFunction> target() const { return target_; }
-  bool target_in_new_space() const { return target_in_new_space_; }
+  Handle<HeapObject> object() const { return object_; }
+  bool object_in_new_space() const { return object_in_new_space_; }

-  DECLARE_CONCRETE_INSTRUCTION(CheckFunction)
+  DECLARE_CONCRETE_INSTRUCTION(CheckValue)

  protected:
   virtual bool DataEquals(HValue* other) V8_OVERRIDE {
-    HCheckFunction* b = HCheckFunction::cast(other);
-    return target_unique_id_ == b->target_unique_id_;
+    HCheckValue* b = HCheckValue::cast(other);
+    return object_unique_id_ == b->object_unique_id_;
   }

  private:
-  HCheckFunction(HValue* value, Handle<JSFunction> function)
+  HCheckValue(HValue* value, Handle<HeapObject> object, bool in_new_space)
       : HUnaryOperation(value, value->type()),
-        target_(function), target_unique_id_() {
+        object_(object), object_in_new_space_(in_new_space) {
     set_representation(Representation::Tagged());
     SetFlag(kUseGVN);
- target_in_new_space_ = Isolate::Current()->heap()->InNewSpace(*function);
   }

-  Handle<JSFunction> target_;
-  UniqueValueId target_unique_id_;
-  bool target_in_new_space_;
+  Handle<HeapObject> object_;
+  UniqueValueId object_unique_id_;
+  bool object_in_new_space_;
 };


@@ -3229,6 +3240,9 @@
   const ZoneList<HValue*>* values() const { return &values_; }
   int length() const { return values_.length(); }
   int capture_id() const { return capture_id_; }
+
+  // Shortcut for the map value of this captured object.
+  HValue* map_value() const { return values()->first(); }

   void ReuseSideEffectsFromStore(HInstruction* store) {
     ASSERT(store->HasObservableSideEffects());
=======================================
--- /branches/bleeding_edge/src/hydrogen.cc     Wed Aug 28 13:03:06 2013 UTC
+++ /branches/bleeding_edge/src/hydrogen.cc     Wed Aug 28 14:16:57 2013 UTC
@@ -7110,7 +7110,7 @@

         CHECK_ALIVE(VisitForValue(expr->expression()));
         HValue* function = Pop();
-        Add<HCheckFunction>(function, expr->target());
+        Add<HCheckValue>(function, expr->target());

         // Replace the global object with the global receiver.
HGlobalReceiver* global_receiver = Add<HGlobalReceiver>(global_object);
@@ -7162,7 +7162,7 @@
       HGlobalReceiver* receiver = New<HGlobalReceiver>(global);
       PushAndAdd(receiver);
       CHECK_ALIVE(VisitExpressions(expr->arguments()));
-      Add<HCheckFunction>(function, expr->target());
+      Add<HCheckValue>(function, expr->target());

if (TryInlineBuiltinFunctionCall(expr, true)) { // Drop the function.
         if (FLAG_trace_inlining) {
@@ -7225,7 +7225,7 @@
     HValue* function = Top();
     CHECK_ALIVE(VisitExpressions(expr->arguments()));
     Handle<JSFunction> constructor = expr->target();
-    HValue* check = Add<HCheckFunction>(function, constructor);
+    HValue* check = Add<HCheckValue>(function, constructor);

     // Force completion of inobject slack tracking before generating
     // allocation code to finalize instance size.
@@ -7317,7 +7317,7 @@
     HBinaryCall* call;
     if (expr->target().is_identical_to(array_function)) {
       Handle<Cell> cell = expr->allocation_info_cell();
-      Add<HCheckFunction>(constructor, array_function);
+      Add<HCheckValue>(constructor, array_function);
call = new(zone()) HCallNewArray(context, constructor, argument_count,
                                        cell, expr->elements_kind());
     } else {
@@ -8149,7 +8149,7 @@
       result->set_position(expr->position());
       return ast_context()->ReturnInstruction(result, expr->id());
     } else {
-      Add<HCheckFunction>(right, target);
+      Add<HCheckValue>(right, target);
       HInstanceOfKnownGlobal* result =
           new(zone()) HInstanceOfKnownGlobal(context, left, target);
       result->set_position(expr->position());
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Tue Aug 27 11:55:08 2013 UTC +++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Wed Aug 28 14:16:57 2013 UTC
@@ -5800,15 +5800,15 @@
 }


-void LCodeGen::DoCheckFunction(LCheckFunction* instr) {
-  Handle<JSFunction> target = instr->hydrogen()->target();
-  if (instr->hydrogen()->target_in_new_space()) {
+void LCodeGen::DoCheckValue(LCheckValue* instr) {
+  Handle<HeapObject> object = instr->hydrogen()->object();
+  if (instr->hydrogen()->object_in_new_space()) {
     Register reg = ToRegister(instr->value());
-    Handle<Cell> cell = isolate()->factory()->NewCell(target);
+    Handle<Cell> cell = isolate()->factory()->NewCell(object);
     __ cmp(reg, Operand::ForCell(cell));
   } else {
     Operand operand = ToOperand(instr->value());
-    __ cmp(operand, target);
+    __ cmp(operand, object);
   }
   DeoptimizeIf(not_equal, instr->environment());
 }
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-ia32.cc Tue Aug 27 14:02:08 2013 UTC +++ /branches/bleeding_edge/src/ia32/lithium-ia32.cc Wed Aug 28 14:16:57 2013 UTC
@@ -2060,14 +2060,14 @@
 }


-LInstruction* LChunkBuilder::DoCheckFunction(HCheckFunction* instr) {
-  // If the target is in new space, we'll emit a global cell compare and so
-  // want the value in a register.  If the target gets promoted before we
+LInstruction* LChunkBuilder::DoCheckValue(HCheckValue* instr) {
+  // If the object is in new space, we'll emit a global cell compare and so
+  // want the value in a register.  If the object gets promoted before we
   // emit code, we will still get the register but will do an immediate
   // compare instead of the cell compare.  This is safe.
-  LOperand* value = instr->target_in_new_space()
+  LOperand* value = instr->object_in_new_space()
       ? UseRegisterAtStart(instr->value()) : UseAtStart(instr->value());
-  return AssignEnvironment(new(zone()) LCheckFunction(value));
+  return AssignEnvironment(new(zone()) LCheckValue(value));
 }


=======================================
--- /branches/bleeding_edge/src/ia32/lithium-ia32.h Tue Aug 27 11:55:08 2013 UTC +++ /branches/bleeding_edge/src/ia32/lithium-ia32.h Wed Aug 28 14:16:57 2013 UTC
@@ -62,12 +62,12 @@
   V(CallNewArray)                               \
   V(CallRuntime)                                \
   V(CallStub)                                   \
-  V(CheckFunction)                              \
   V(CheckInstanceType)                          \
   V(CheckMaps)                                  \
   V(CheckMapValue)                              \
   V(CheckNonSmi)                                \
   V(CheckSmi)                                   \
+  V(CheckValue)                                 \
   V(ClampDToUint8)                              \
   V(ClampIToUint8)                              \
   V(ClampTToUint8)                              \
@@ -2437,16 +2437,16 @@
 };


-class LCheckFunction V8_FINAL : public LTemplateInstruction<0, 1, 0> {
+class LCheckValue V8_FINAL : public LTemplateInstruction<0, 1, 0> {
  public:
-  explicit LCheckFunction(LOperand* value) {
+  explicit LCheckValue(LOperand* value) {
     inputs_[0] = value;
   }

   LOperand* value() { return inputs_[0]; }

-  DECLARE_CONCRETE_INSTRUCTION(CheckFunction, "check-function")
-  DECLARE_HYDROGEN_ACCESSOR(CheckFunction)
+  DECLARE_CONCRETE_INSTRUCTION(CheckValue, "check-value")
+  DECLARE_HYDROGEN_ACCESSOR(CheckValue)
 };


=======================================
--- /branches/bleeding_edge/src/mips/lithium-codegen-mips.cc Tue Aug 27 23:05:07 2013 UTC +++ /branches/bleeding_edge/src/mips/lithium-codegen-mips.cc Wed Aug 28 14:16:57 2013 UTC
@@ -5116,20 +5116,20 @@
 }


-void LCodeGen::DoCheckFunction(LCheckFunction* instr) {
+void LCodeGen::DoCheckValue(LCheckValue* instr) {
   Register reg = ToRegister(instr->value());
-  Handle<JSFunction> target = instr->hydrogen()->target();
+  Handle<HeapObject> object = instr->hydrogen()->object();
   AllowDeferredHandleDereference smi_check;
-  if (isolate()->heap()->InNewSpace(*target)) {
+  if (isolate()->heap()->InNewSpace(*object)) {
     Register reg = ToRegister(instr->value());
-    Handle<Cell> cell = isolate()->factory()->NewCell(target);
+    Handle<Cell> cell = isolate()->factory()->NewCell(object);
     __ li(at, Operand(Handle<Object>(cell)));
     __ lw(at, FieldMemOperand(at, Cell::kValueOffset));
     DeoptimizeIf(ne, instr->environment(), reg,
                  Operand(at));
   } else {
     DeoptimizeIf(ne, instr->environment(), reg,
-                 Operand(target));
+                 Operand(object));
   }
 }

=======================================
--- /branches/bleeding_edge/src/mips/lithium-mips.cc Tue Aug 27 23:07:03 2013 UTC +++ /branches/bleeding_edge/src/mips/lithium-mips.cc Wed Aug 28 14:16:57 2013 UTC
@@ -1951,9 +1951,9 @@
 }


-LInstruction* LChunkBuilder::DoCheckFunction(HCheckFunction* instr) {
+LInstruction* LChunkBuilder::DoCheckValue(HCheckValue* instr) {
   LOperand* value = UseRegisterAtStart(instr->value());
-  return AssignEnvironment(new(zone()) LCheckFunction(value));
+  return AssignEnvironment(new(zone()) LCheckValue(value));
 }


=======================================
--- /branches/bleeding_edge/src/mips/lithium-mips.h Tue Aug 27 22:53:25 2013 UTC +++ /branches/bleeding_edge/src/mips/lithium-mips.h Wed Aug 28 14:16:57 2013 UTC
@@ -62,12 +62,12 @@
   V(CallNewArray)                               \
   V(CallRuntime)                                \
   V(CallStub)                                   \
-  V(CheckFunction)                              \
   V(CheckInstanceType)                          \
   V(CheckMaps)                                  \
   V(CheckMapValue)                              \
   V(CheckNonSmi)                                \
   V(CheckSmi)                                   \
+  V(CheckValue)                                 \
   V(ClampDToUint8)                              \
   V(ClampIToUint8)                              \
   V(ClampTToUint8)                              \
@@ -2321,16 +2321,16 @@
 };


-class LCheckFunction V8_FINAL : public LTemplateInstruction<0, 1, 0> {
+class LCheckValue V8_FINAL : public LTemplateInstruction<0, 1, 0> {
  public:
-  explicit LCheckFunction(LOperand* value) {
+  explicit LCheckValue(LOperand* value) {
     inputs_[0] = value;
   }

   LOperand* value() { return inputs_[0]; }

-  DECLARE_CONCRETE_INSTRUCTION(CheckFunction, "check-function")
-  DECLARE_HYDROGEN_ACCESSOR(CheckFunction)
+  DECLARE_CONCRETE_INSTRUCTION(CheckValue, "check-value")
+  DECLARE_HYDROGEN_ACCESSOR(CheckValue)
 };


=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Tue Aug 27 13:55:00 2013 UTC +++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Wed Aug 28 14:16:57 2013 UTC
@@ -4915,10 +4915,10 @@
 }


-void LCodeGen::DoCheckFunction(LCheckFunction* instr) {
+void LCodeGen::DoCheckValue(LCheckValue* instr) {
   Register reg = ToRegister(instr->value());
-  Handle<JSFunction> target = instr->hydrogen()->target();
-  __ CmpHeapObject(reg, target);
+  Handle<HeapObject> object = instr->hydrogen()->object();
+  __ CmpHeapObject(reg, object);
   DeoptimizeIf(not_equal, instr->environment());
 }

=======================================
--- /branches/bleeding_edge/src/x64/lithium-x64.cc Tue Aug 27 14:02:08 2013 UTC +++ /branches/bleeding_edge/src/x64/lithium-x64.cc Wed Aug 28 14:16:57 2013 UTC
@@ -1940,9 +1940,9 @@
 }


-LInstruction* LChunkBuilder::DoCheckFunction(HCheckFunction* instr) {
+LInstruction* LChunkBuilder::DoCheckValue(HCheckValue* instr) {
   LOperand* value = UseRegisterAtStart(instr->value());
-  return AssignEnvironment(new(zone()) LCheckFunction(value));
+  return AssignEnvironment(new(zone()) LCheckValue(value));
 }


=======================================
--- /branches/bleeding_edge/src/x64/lithium-x64.h Tue Aug 27 11:55:08 2013 UTC +++ /branches/bleeding_edge/src/x64/lithium-x64.h Wed Aug 28 14:16:57 2013 UTC
@@ -62,12 +62,12 @@
   V(CallNewArray)                               \
   V(CallRuntime)                                \
   V(CallStub)                                   \
-  V(CheckFunction)                              \
   V(CheckInstanceType)                          \
   V(CheckMaps)                                  \
   V(CheckMapValue)                              \
   V(CheckNonSmi)                                \
   V(CheckSmi)                                   \
+  V(CheckValue)                                 \
   V(ClampDToUint8)                              \
   V(ClampIToUint8)                              \
   V(ClampTToUint8)                              \
@@ -2260,16 +2260,16 @@
 };


-class LCheckFunction V8_FINAL : public LTemplateInstruction<0, 1, 0> {
+class LCheckValue V8_FINAL : public LTemplateInstruction<0, 1, 0> {
  public:
-  explicit LCheckFunction(LOperand* value) {
+  explicit LCheckValue(LOperand* value) {
     inputs_[0] = value;
   }

   LOperand* value() { return inputs_[0]; }

-  DECLARE_CONCRETE_INSTRUCTION(CheckFunction, "check-function")
-  DECLARE_HYDROGEN_ACCESSOR(CheckFunction)
+  DECLARE_CONCRETE_INSTRUCTION(CheckValue, "check-value")
+  DECLARE_HYDROGEN_ACCESSOR(CheckValue)
 };


=======================================
--- /branches/bleeding_edge/test/mjsunit/compiler/escape-analysis.js Mon Aug 26 16:43:19 2013 UTC +++ /branches/bleeding_edge/test/mjsunit/compiler/escape-analysis.js Wed Aug 28 14:16:57 2013 UTC
@@ -173,3 +173,30 @@
   delete deopt.deopt;
   func(); func();
 })();
+
+
+// Test map checks on captured objects.
+(function testMapCheck() {
+  var sum = 0;
+  function getter() { return 27; }
+  function setter(v) { sum += v; }
+  function constructor() {
+    this.x = 23;
+    this.y = 42;
+  }
+  function check(x, y) {
+    var o = new constructor();
+    assertEquals(x, o.x);
+    assertEquals(y, o.y);
+  }
+  var monkey = Object.create(null, {
+    x: { get:getter, set:setter },
+    y: { get:getter, set:setter }
+  });
+  check(23, 42); check(23, 42);
+  %OptimizeFunctionOnNextCall(check);
+  check(23, 42); check(23, 42);
+  constructor.prototype = monkey;
+  check(27, 27); check(27, 27);
+  assertEquals(130, sum);
+})();

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to