Reviewers: fschneider,

Description:
Simplify CheckPrototypeMaps.

This instruction only depends on the prototype and the holder and can
completely ignore the receiver and its map.

This change also fixes a small bug on arm where a cell was loaded
instead of the prototype from new space.

Please review this at http://codereview.chromium.org/6094020/

Affected files:
  M src/arm/lithium-codegen-arm.cc
  M src/hydrogen-instructions.h
  M src/hydrogen.cc
  M src/ia32/lithium-codegen-ia32.cc
  M src/ia32/lithium-ia32.h


Index: src/arm/lithium-codegen-arm.cc
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index 0e4497fcc8d5196b8c5e785f74e459910972b62e..b5e4284e30546e8ddf8f8d5dedc078dfba429883 100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -2510,6 +2510,7 @@ void LCodeGen::LoadPrototype(Register result,
     Handle<JSGlobalPropertyCell> cell =
         Factory::NewJSGlobalPropertyCell(prototype);
     __ mov(result, Operand(cell));
+ __ ldr(result, FieldMemOperand(result, JSGlobalPropertyCell::kValueOffset));
   } else {
     __ mov(result, Operand(prototype));
   }
@@ -2521,8 +2522,7 @@ void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) {
   Register temp2 = ToRegister(instr->temp2());

   Handle<JSObject> holder = instr->holder();
-  Handle<Map> receiver_map = instr->receiver_map();
- Handle<JSObject> current_prototype(JSObject::cast(receiver_map->prototype()));
+  Handle<JSObject> current_prototype = instr->prototype();

   // Load prototype object.
   LoadPrototype(temp1, current_prototype);
Index: src/hydrogen-instructions.h
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index f7eb17344ad714bfc233cc8ce72cf08025583482..8a95cd78b0ace4e50be0bef6f3bbbce504b12860 100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -92,6 +92,7 @@ class LChunkBuilder;
 //       HCallNew
 //       HCallRuntime
 //     HCallStub
+//     HCheckPrototypeMaps
 //     HConstant
 //     HControlInstruction
 //       HDeoptimize
@@ -125,7 +126,6 @@ class LChunkBuilder;
 //       HCheckInstanceType
 //       HCheckMap
 //       HCheckNonSmi
-//       HCheckPrototypeMaps
 //       HCheckSmi
 //       HDeleteProperty
 //       HFixedArrayLength
@@ -1622,42 +1622,40 @@ class HCheckNonSmi: public HUnaryOperation {
 };


-class HCheckPrototypeMaps: public HUnaryOperation {
+class HCheckPrototypeMaps: public HInstruction {
  public:
-  HCheckPrototypeMaps(HValue* value,
-                      Handle<JSObject> holder,
-                      Handle<Map> receiver_map)
-      : HUnaryOperation(value),
-        holder_(holder),
-        receiver_map_(receiver_map) {
-    set_representation(Representation::Tagged());
+  HCheckPrototypeMaps(Handle<JSObject> prototype, Handle<JSObject> holder)
+      : prototype_(prototype), holder_(holder) {
     SetFlag(kUseGVN);
     SetFlag(kDependsOnMaps);
   }

-  virtual Representation RequiredInputRepresentation(int index) const {
-    return Representation::Tagged();
-  }
-
 #ifdef DEBUG
   virtual void Verify() const;
 #endif

+  Handle<JSObject> prototype() const { return prototype_; }
   Handle<JSObject> holder() const { return holder_; }
-  Handle<Map> receiver_map() const { return receiver_map_; }

   DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps, "check_prototype_maps")

+  virtual intptr_t Hashcode() const {
+    ASSERT(!Heap::allow_allocation(false));
+    intptr_t hash = reinterpret_cast<intptr_t>(*prototype());
+    hash = 17 * hash + reinterpret_cast<intptr_t>(*holder());
+    return hash;
+  }
+
  protected:
   virtual bool DataEquals(HValue* other) const {
     HCheckPrototypeMaps* b = HCheckPrototypeMaps::cast(other);
-    return holder_.is_identical_to(b->holder()) &&
-        receiver_map_.is_identical_to(b->receiver_map());
+    return prototype_.is_identical_to(b->prototype()) &&
+        holder_.is_identical_to(b->holder());
   }

  private:
+  Handle<JSObject> prototype_;
   Handle<JSObject> holder_;
-  Handle<Map> receiver_map_;
 };


Index: src/hydrogen.cc
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index 5da3da54eea2409ced27126b90bac184d540bab0..94137b6b04fa83dc441cfc249473fb195f82b8f5 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -3795,9 +3795,9 @@ void HGraphBuilder::AddCheckConstantFunction(Call* expr,
     AddInstruction(new HCheckMap(receiver, receiver_map));
   }
   if (!expr->holder().is_null()) {
-    AddInstruction(new HCheckPrototypeMaps(receiver,
-                                           expr->holder(),
-                                           receiver_map));
+    AddInstruction(new HCheckPrototypeMaps(
+        Handle<JSObject>(JSObject::cast(receiver_map->prototype())),
+        expr->holder()));
   }
 }

Index: src/ia32/lithium-codegen-ia32.cc
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc index 87592882e7b64d981e2ae41defda14e3945cb3cd..775e3a93965ca1522a0f3ce17c066653ad5835d5 100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -3155,8 +3155,7 @@ void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) {
   Register reg = ToRegister(instr->temp());

   Handle<JSObject> holder = instr->holder();
-  Handle<Map> receiver_map = instr->receiver_map();
- Handle<JSObject> current_prototype(JSObject::cast(receiver_map->prototype()));
+  Handle<JSObject> current_prototype = instr->prototype();

   // Load prototype object.
   LoadPrototype(reg, current_prototype);
Index: src/ia32/lithium-ia32.h
diff --git a/src/ia32/lithium-ia32.h b/src/ia32/lithium-ia32.h
index 326ce7250eb0e824fe6f6de6359c28b600c67f03..5f70379e12df4e0aef347873cd94c24b79c91482 100644
--- a/src/ia32/lithium-ia32.h
+++ b/src/ia32/lithium-ia32.h
@@ -77,6 +77,7 @@ class LCodeGen;
 //   LCallNamed
 //   LCallRuntime
 //   LCallStub
+//   LCheckPrototypeMaps
 //   LConstant
 //     LConstantD
 //     LConstantI
@@ -111,7 +112,6 @@ class LCodeGen;
 //     LCheckFunction
 //     LCheckInstanceType
 //     LCheckMap
-//     LCheckPrototypeMaps
 //     LCheckSmi
 //     LClassOfTest
 //     LClassOfTestAndBranch
@@ -1687,8 +1687,8 @@ class LCheckPrototypeMaps: public LTemplateInstruction<0, 0, 0> {
   DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps, "check-prototype-maps")
   DECLARE_HYDROGEN_ACCESSOR(CheckPrototypeMaps)

+  Handle<JSObject> prototype() const { return hydrogen()->prototype(); }
   Handle<JSObject> holder() const { return hydrogen()->holder(); }
-  Handle<Map> receiver_map() const { return hydrogen()->receiver_map(); }

   LOperand* temp() const { return temp_; }



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

Reply via email to