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
This commit is contained in:
parent
ad58227fcf
commit
9e204dd5df
@ -76,6 +76,7 @@ class LCodeGen;
|
||||
// LCallNamed
|
||||
// LCallRuntime
|
||||
// LCallStub
|
||||
// LCheckPrototypeMaps
|
||||
// LConstant
|
||||
// LConstantD
|
||||
// LConstantI
|
||||
@ -109,7 +110,6 @@ class LCodeGen;
|
||||
// LCheckFunction
|
||||
// LCheckInstanceType
|
||||
// LCheckMap
|
||||
// LCheckPrototypeMaps
|
||||
// LCheckSmi
|
||||
// LClassOfTest
|
||||
// LClassOfTestAndBranch
|
||||
@ -1596,8 +1596,9 @@ class LCheckPrototypeMaps: public LInstruction {
|
||||
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* temp1() const { return temp1_; }
|
||||
LOperand* temp2() const { return temp2_; }
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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::IsAllocationAllowed());
|
||||
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_;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
@ -1680,8 +1680,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_; }
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user