| Index: src/hydrogen-instructions.h
|
| diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
|
| index 88d217a862d9a6ddf77dd934a1d4848db9eefd5c..77352b147eec37c3c1ad837007b2b9de3bdb7624 100644
|
| --- a/src/hydrogen-instructions.h
|
| +++ b/src/hydrogen-instructions.h
|
| @@ -2446,14 +2446,24 @@ class HCheckNonSmi: public HUnaryOperation {
|
|
|
| class HCheckPrototypeMaps: public HTemplateInstruction<0> {
|
| public:
|
| - HCheckPrototypeMaps(Handle<JSObject> prototype, Handle<JSObject> holder)
|
| - : prototype_(prototype), holder_(holder) {
|
| + HCheckPrototypeMaps(Handle<JSObject> prototype,
|
| + Handle<JSObject> holder,
|
| + Zone* zone) : prototypes_(2, zone), maps_(2, zone) {
|
| SetFlag(kUseGVN);
|
| SetGVNFlag(kDependsOnMaps);
|
| + // Keep a list of all objects on the prototype chain up to the holder
|
| + // and the expected maps.
|
| + while (true) {
|
| + prototypes_.Add(prototype, zone);
|
| + maps_.Add(Handle<Map>(prototype->map()), zone);
|
| + if (prototype.is_identical_to(holder)) break;
|
| + prototype = Handle<JSObject>(JSObject::cast(prototype->GetPrototype()));
|
| + }
|
| }
|
|
|
| - Handle<JSObject> prototype() const { return prototype_; }
|
| - Handle<JSObject> holder() const { return holder_; }
|
| + ZoneList<Handle<JSObject> >* prototypes() { return &prototypes_; }
|
| +
|
| + ZoneList<Handle<Map> >* maps() { return &maps_; }
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps)
|
|
|
| @@ -2465,21 +2475,28 @@ class HCheckPrototypeMaps: public HTemplateInstruction<0> {
|
|
|
| virtual intptr_t Hashcode() {
|
| ASSERT_ALLOCATION_DISABLED;
|
| - intptr_t hash = reinterpret_cast<intptr_t>(*prototype());
|
| - hash = 17 * hash + reinterpret_cast<intptr_t>(*holder());
|
| + intptr_t hash = 0;
|
| + for (int i = 0; i < prototypes_.length(); i++) {
|
| + hash = 17 * hash + reinterpret_cast<intptr_t>(*prototypes_[i]);
|
| + hash = 17 * hash + reinterpret_cast<intptr_t>(*maps_[i]);
|
| + }
|
| return hash;
|
| }
|
|
|
| protected:
|
| virtual bool DataEquals(HValue* other) {
|
| HCheckPrototypeMaps* b = HCheckPrototypeMaps::cast(other);
|
| - return prototype_.is_identical_to(b->prototype()) &&
|
| - holder_.is_identical_to(b->holder());
|
| + if (prototypes_.length() != b->prototypes()->length()) return false;
|
| + for (int i = 0; i < prototypes_.length(); i++) {
|
| + if (!prototypes_[i].is_identical_to(b->prototypes()->at(i))) return false;
|
| + if (!maps_[i].is_identical_to(b->maps()->at(i))) return false;
|
| + }
|
| + return true;
|
| }
|
|
|
| private:
|
| - Handle<JSObject> prototype_;
|
| - Handle<JSObject> holder_;
|
| + ZoneList<Handle<JSObject> > prototypes_;
|
| + ZoneList<Handle<Map> > maps_;
|
| };
|
|
|
|
|
| @@ -3614,9 +3631,9 @@ class HSub: public HArithmeticBinaryOperation {
|
| virtual HValue* Canonicalize();
|
|
|
| static HInstruction* NewHSub(Zone* zone,
|
| - HValue* context,
|
| - HValue* left,
|
| - HValue* right);
|
| + HValue* context,
|
| + HValue* left,
|
| + HValue* right);
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(Sub)
|
|
|
|
|