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