☠☠ backed out by 441defeeb653 ☠ ☠ | |
author | Nicolas B. Pierron <nicolas.b.pierron@mozilla.com> |
Fri, 19 Oct 2012 14:30:38 -0700 | |
changeset 110826 | 0498e3bb74bdc6aabad86ac10d9c376bdd8a654e |
parent 110825 | 31ab0fe92304517353cb63626de2c855b14befda |
child 110827 | 441defeeb6533f18a9eaa3c09ddb5e3747987049 |
push id | 23716 |
push user | ryanvm@gmail.com |
push date | Sat, 20 Oct 2012 01:43:16 +0000 |
treeherder | mozilla-central@ff4af83233dc [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jandem |
bugs | 799818 |
milestone | 19.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/js/src/ion/IonBuilder.cpp +++ b/js/src/ion/IonBuilder.cpp @@ -4413,24 +4413,26 @@ TestSingletonProperty(JSContext *cx, Han *isKnownConstant = true; return true; } static inline bool TestSingletonPropertyTypes(JSContext *cx, types::StackTypeSet *types, HandleObject globalObj, HandleId id, - bool *isKnownConstant, bool *testObject) + bool *isKnownConstant, bool *testObject, + bool *testString) { // As for TestSingletonProperty, but the input is any value in a type set // rather than a specific object. If testObject is set then the constant // result can only be used after ensuring the input is an object. *isKnownConstant = false; *testObject = false; + *testString = false; if (!types || types->unknownObject()) return true; RootedObject singleton(cx, types->getSingleton()); if (singleton) return TestSingletonProperty(cx, singleton, id, isKnownConstant); @@ -4450,16 +4452,25 @@ TestSingletonPropertyTypes(JSContext *cx break; case JSVAL_TYPE_BOOLEAN: key = JSProto_Boolean; break; case JSVAL_TYPE_OBJECT: case JSVAL_TYPE_UNKNOWN: { + if (types->hasType(types::Type::StringType())) { + // Do not optimize if the object is either a String or an Object. + if (types->maybeObject()) + return true; + key = JSProto_String; + *testString = true; + break; + } + // For property accesses which may be on many objects, we just need to // find a prototype common to all the objects; if that prototype // has the singleton property, the access will not be on a missing property. bool thoughtConstant = true; for (unsigned i = 0; i < types->getObjectCount(); i++) { types::TypeObject *object = types->getTypeObject(i); if (!object) { // Try to get it through the singleton. @@ -5879,28 +5890,32 @@ IonBuilder::getPropTryConstant(bool *emi { JS_ASSERT(*emitted == false); JSObject *singleton = types ? types->getSingleton() : NULL; if (!singleton || barrier) return true; RootedObject global(cx, &script_->global()); - bool isConstant, testObject; - if (!TestSingletonPropertyTypes(cx, unaryTypes.inTypes, global, id, &isConstant, &testObject)) + bool isConstant, testObject, testString; + if (!TestSingletonPropertyTypes(cx, unaryTypes.inTypes, global, id, + &isConstant, &testObject, &testString)) return false; if (!isConstant) return true; MDefinition *obj = current->pop(); // Property access is a known constant -- safe to emit. + JS_ASSERT(!testString || !testObject); if (testObject) current->add(MGuardObject::New(obj)); + else if (testString) + current->add(MGuardString::New(obj)); MConstant *known = MConstant::New(ObjectValue(*singleton)); if (singleton->isFunction()) { RootedFunction singletonFunc(cx, singleton->toFunction()); if (TestAreKnownDOMTypes(cx, unaryTypes.inTypes) && TestShouldDOMCall(cx, unaryTypes.inTypes, singletonFunc)) { FreezeDOMTypes(cx, unaryTypes.inTypes);
--- a/js/src/ion/Lowering.cpp +++ b/js/src/ion/Lowering.cpp @@ -1714,16 +1714,25 @@ LIRGenerator::visitGuardObject(MGuardObj { // The type policy does all the work, so at this point the input // is guaranteed to be an object. JS_ASSERT(ins->input()->type() == MIRType_Object); return redefine(ins, ins->input()); } bool +LIRGenerator::visitGuardString(MGuardString *ins) +{ + // The type policy does all the work, so at this point the input + // is guaranteed to be a string. + JS_ASSERT(ins->input()->type() == MIRType_String); + return redefine(ins, ins->input()); +} + +bool LIRGenerator::visitCallGetProperty(MCallGetProperty *ins) { LCallGetProperty *lir = new LCallGetProperty(); if (!useBoxAtStart(lir, LCallGetProperty::Value, ins->value())) return false; return defineVMReturn(lir, ins) && assignSafepoint(lir, ins); }
--- a/js/src/ion/Lowering.h +++ b/js/src/ion/Lowering.h @@ -160,16 +160,17 @@ class LIRGenerator : public LIRGenerator bool visitClampToUint8(MClampToUint8 *ins); bool visitLoadFixedSlot(MLoadFixedSlot *ins); bool visitStoreFixedSlot(MStoreFixedSlot *ins); bool visitGetPropertyCache(MGetPropertyCache *ins); bool visitGetElementCache(MGetElementCache *ins); bool visitBindNameCache(MBindNameCache *ins); bool visitGuardClass(MGuardClass *ins); bool visitGuardObject(MGuardObject *ins); + bool visitGuardString(MGuardString *ins); bool visitCallGetProperty(MCallGetProperty *ins); bool visitDeleteProperty(MDeleteProperty *ins); bool visitGetNameCache(MGetNameCache *ins); bool visitCallGetElement(MCallGetElement *ins); bool visitCallSetElement(MCallSetElement *ins); bool visitSetPropertyCache(MSetPropertyCache *ins); bool visitCallSetProperty(MCallSetProperty *ins); bool visitIteratorStart(MIteratorStart *ins);
--- a/js/src/ion/MIR.h +++ b/js/src/ion/MIR.h @@ -1496,16 +1496,47 @@ class MGuardObject : public MUnaryInstru TypePolicy *typePolicy() { return this; } AliasSet getAliasSet() const { return AliasSet::None(); } }; +class MGuardString + : public MUnaryInstruction, + public StringPolicy +{ + MGuardString(MDefinition *ins) + : MUnaryInstruction(ins) + { + setGuard(); + setMovable(); + setResultType(MIRType_String); + } + + public: + INSTRUCTION_HEADER(GuardString); + + static MGuardString *New(MDefinition *ins) { + return new MGuardString(ins); + } + + MDefinition *input() const { + return getOperand(0); + } + + TypePolicy *typePolicy() { + return this; + } + AliasSet getAliasSet() const { + return AliasSet::None(); + } +}; + // Caller-side allocation of |this| for |new|: // Given a prototype operand, construct |this| for JSOP_NEW. // For native constructors, returns MagicValue(JS_IS_CONSTRUCTING). class MCreateThis : public MAryInstruction<2>, public MixPolicy<ObjectPolicy<0>, ObjectPolicy<1> > { // Template for |this|, provided by TI, or NULL.
--- a/js/src/ion/MOpcodes.h +++ b/js/src/ion/MOpcodes.h @@ -58,16 +58,17 @@ namespace ion { _(Concat) \ _(CharCodeAt) \ _(FromCharCode) \ _(Return) \ _(Throw) \ _(Box) \ _(Unbox) \ _(GuardObject) \ + _(GuardString) \ _(ToDouble) \ _(ToInt32) \ _(TruncateToInt32) \ _(ToString) \ _(NewSlots) \ _(NewArray) \ _(NewObject) \ _(NewCallObject) \