Commit 9e204dd5 authored by vitalyr@chromium.org's avatar vitalyr@chromium.org

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.

Review URL: http://codereview.chromium.org/6094020

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6290 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent ad58227f
...@@ -76,6 +76,7 @@ class LCodeGen; ...@@ -76,6 +76,7 @@ class LCodeGen;
// LCallNamed // LCallNamed
// LCallRuntime // LCallRuntime
// LCallStub // LCallStub
// LCheckPrototypeMaps
// LConstant // LConstant
// LConstantD // LConstantD
// LConstantI // LConstantI
...@@ -109,7 +110,6 @@ class LCodeGen; ...@@ -109,7 +110,6 @@ class LCodeGen;
// LCheckFunction // LCheckFunction
// LCheckInstanceType // LCheckInstanceType
// LCheckMap // LCheckMap
// LCheckPrototypeMaps
// LCheckSmi // LCheckSmi
// LClassOfTest // LClassOfTest
// LClassOfTestAndBranch // LClassOfTestAndBranch
...@@ -1596,8 +1596,9 @@ class LCheckPrototypeMaps: public LInstruction { ...@@ -1596,8 +1596,9 @@ class LCheckPrototypeMaps: public LInstruction {
DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps, "check-prototype-maps") DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps, "check-prototype-maps")
DECLARE_HYDROGEN_ACCESSOR(CheckPrototypeMaps) DECLARE_HYDROGEN_ACCESSOR(CheckPrototypeMaps)
Handle<JSObject> prototype() const { return hydrogen()->prototype(); }
Handle<JSObject> holder() const { return hydrogen()->holder(); } Handle<JSObject> holder() const { return hydrogen()->holder(); }
Handle<Map> receiver_map() const { return hydrogen()->receiver_map(); }
LOperand* temp1() const { return temp1_; } LOperand* temp1() const { return temp1_; }
LOperand* temp2() const { return temp2_; } LOperand* temp2() const { return temp2_; }
......
...@@ -2510,6 +2510,7 @@ void LCodeGen::LoadPrototype(Register result, ...@@ -2510,6 +2510,7 @@ void LCodeGen::LoadPrototype(Register result,
Handle<JSGlobalPropertyCell> cell = Handle<JSGlobalPropertyCell> cell =
Factory::NewJSGlobalPropertyCell(prototype); Factory::NewJSGlobalPropertyCell(prototype);
__ mov(result, Operand(cell)); __ mov(result, Operand(cell));
__ ldr(result, FieldMemOperand(result, JSGlobalPropertyCell::kValueOffset));
} else { } else {
__ mov(result, Operand(prototype)); __ mov(result, Operand(prototype));
} }
...@@ -2521,8 +2522,7 @@ void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) { ...@@ -2521,8 +2522,7 @@ void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) {
Register temp2 = ToRegister(instr->temp2()); Register temp2 = ToRegister(instr->temp2());
Handle<JSObject> holder = instr->holder(); Handle<JSObject> holder = instr->holder();
Handle<Map> receiver_map = instr->receiver_map(); Handle<JSObject> current_prototype = instr->prototype();
Handle<JSObject> current_prototype(JSObject::cast(receiver_map->prototype()));
// Load prototype object. // Load prototype object.
LoadPrototype(temp1, current_prototype); LoadPrototype(temp1, current_prototype);
......
...@@ -92,6 +92,7 @@ class LChunkBuilder; ...@@ -92,6 +92,7 @@ class LChunkBuilder;
// HCallNew // HCallNew
// HCallRuntime // HCallRuntime
// HCallStub // HCallStub
// HCheckPrototypeMaps
// HConstant // HConstant
// HControlInstruction // HControlInstruction
// HDeoptimize // HDeoptimize
...@@ -125,7 +126,6 @@ class LChunkBuilder; ...@@ -125,7 +126,6 @@ class LChunkBuilder;
// HCheckInstanceType // HCheckInstanceType
// HCheckMap // HCheckMap
// HCheckNonSmi // HCheckNonSmi
// HCheckPrototypeMaps
// HCheckSmi // HCheckSmi
// HDeleteProperty // HDeleteProperty
// HFixedArrayLength // HFixedArrayLength
...@@ -1622,42 +1622,40 @@ class HCheckNonSmi: public HUnaryOperation { ...@@ -1622,42 +1622,40 @@ class HCheckNonSmi: public HUnaryOperation {
}; };
class HCheckPrototypeMaps: public HUnaryOperation { class HCheckPrototypeMaps: public HInstruction {
public: public:
HCheckPrototypeMaps(HValue* value, HCheckPrototypeMaps(Handle<JSObject> prototype, Handle<JSObject> holder)
Handle<JSObject> holder, : prototype_(prototype), holder_(holder) {
Handle<Map> receiver_map)
: HUnaryOperation(value),
holder_(holder),
receiver_map_(receiver_map) {
set_representation(Representation::Tagged());
SetFlag(kUseGVN); SetFlag(kUseGVN);
SetFlag(kDependsOnMaps); SetFlag(kDependsOnMaps);
} }
virtual Representation RequiredInputRepresentation(int index) const {
return Representation::Tagged();
}
#ifdef DEBUG #ifdef DEBUG
virtual void Verify() const; virtual void Verify() const;
#endif #endif
Handle<JSObject> prototype() const { return prototype_; }
Handle<JSObject> holder() const { return holder_; } Handle<JSObject> holder() const { return holder_; }
Handle<Map> receiver_map() const { return receiver_map_; }
DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps, "check_prototype_maps") DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps, "check_prototype_maps")
virtual intptr_t Hashcode() const {
ASSERT(!Heap::IsAllocationAllowed());
intptr_t hash = reinterpret_cast<intptr_t>(*prototype());
hash = 17 * hash + reinterpret_cast<intptr_t>(*holder());
return hash;
}
protected: protected:
virtual bool DataEquals(HValue* other) const { virtual bool DataEquals(HValue* other) const {
HCheckPrototypeMaps* b = HCheckPrototypeMaps::cast(other); HCheckPrototypeMaps* b = HCheckPrototypeMaps::cast(other);
return holder_.is_identical_to(b->holder()) && return prototype_.is_identical_to(b->prototype()) &&
receiver_map_.is_identical_to(b->receiver_map()); holder_.is_identical_to(b->holder());
} }
private: private:
Handle<JSObject> prototype_;
Handle<JSObject> holder_; Handle<JSObject> holder_;
Handle<Map> receiver_map_;
}; };
......
...@@ -3795,9 +3795,9 @@ void HGraphBuilder::AddCheckConstantFunction(Call* expr, ...@@ -3795,9 +3795,9 @@ void HGraphBuilder::AddCheckConstantFunction(Call* expr,
AddInstruction(new HCheckMap(receiver, receiver_map)); AddInstruction(new HCheckMap(receiver, receiver_map));
} }
if (!expr->holder().is_null()) { if (!expr->holder().is_null()) {
AddInstruction(new HCheckPrototypeMaps(receiver, AddInstruction(new HCheckPrototypeMaps(
expr->holder(), Handle<JSObject>(JSObject::cast(receiver_map->prototype())),
receiver_map)); expr->holder()));
} }
} }
......
...@@ -3155,8 +3155,7 @@ void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) { ...@@ -3155,8 +3155,7 @@ void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) {
Register reg = ToRegister(instr->temp()); Register reg = ToRegister(instr->temp());
Handle<JSObject> holder = instr->holder(); Handle<JSObject> holder = instr->holder();
Handle<Map> receiver_map = instr->receiver_map(); Handle<JSObject> current_prototype = instr->prototype();
Handle<JSObject> current_prototype(JSObject::cast(receiver_map->prototype()));
// Load prototype object. // Load prototype object.
LoadPrototype(reg, current_prototype); LoadPrototype(reg, current_prototype);
......
...@@ -77,6 +77,7 @@ class LCodeGen; ...@@ -77,6 +77,7 @@ class LCodeGen;
// LCallNamed // LCallNamed
// LCallRuntime // LCallRuntime
// LCallStub // LCallStub
// LCheckPrototypeMaps
// LConstant // LConstant
// LConstantD // LConstantD
// LConstantI // LConstantI
...@@ -111,7 +112,6 @@ class LCodeGen; ...@@ -111,7 +112,6 @@ class LCodeGen;
// LCheckFunction // LCheckFunction
// LCheckInstanceType // LCheckInstanceType
// LCheckMap // LCheckMap
// LCheckPrototypeMaps
// LCheckSmi // LCheckSmi
// LClassOfTest // LClassOfTest
// LClassOfTestAndBranch // LClassOfTestAndBranch
...@@ -1680,8 +1680,8 @@ class LCheckPrototypeMaps: public LTemplateInstruction<0, 0, 0> { ...@@ -1680,8 +1680,8 @@ class LCheckPrototypeMaps: public LTemplateInstruction<0, 0, 0> {
DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps, "check-prototype-maps") DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps, "check-prototype-maps")
DECLARE_HYDROGEN_ACCESSOR(CheckPrototypeMaps) DECLARE_HYDROGEN_ACCESSOR(CheckPrototypeMaps)
Handle<JSObject> prototype() const { return hydrogen()->prototype(); }
Handle<JSObject> holder() const { return hydrogen()->holder(); } Handle<JSObject> holder() const { return hydrogen()->holder(); }
Handle<Map> receiver_map() const { return hydrogen()->receiver_map(); }
LOperand* temp() const { return temp_; } LOperand* temp() const { return temp_; }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment