Bug 815161: Use caching getproperty to fetch prototype to create this, r=jandem
authorHannes Verschore <hv1989@gmail.com>
Sat, 01 Dec 2012 16:23:23 +0100
changeset 114698 e83393045b95dbb973ecec2fdf245e3d34cf0d0f
parent 114696 1aea4afb63d91c1b2122e24a1805cbb5f0c98ce9
child 114699 1cdee6935ae2257a3c65699636955cbec003e5ea
push id23927
push userryanvm@gmail.com
push dateSun, 02 Dec 2012 01:58:27 +0000
treeherdermozilla-central@2533bce8e045 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs815161
milestone20.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
Bug 815161: Use caching getproperty to fetch prototype to create this, r=jandem
js/src/ion/IonBuilder.cpp
js/src/ion/MIR.h
--- a/js/src/ion/IonBuilder.cpp
+++ b/js/src/ion/IonBuilder.cpp
@@ -3512,25 +3512,39 @@ IonBuilder::createThisNative()
     current->add(magic);
     return magic;
 }
 
 MDefinition *
 IonBuilder::createThisScripted(MDefinition *callee)
 {
     // Get callee.prototype.
+    //
     // This instruction MUST be idempotent: since it does not correspond to an
-    // explicit operation in the bytecode, we cannot use resumeAfter(). But
-    // calling GetProperty can trigger a GC, and thus invalidation.
-    MCallGetProperty *getProto = MCallGetProperty::New(callee, cx->names().classPrototype);
-
-    // Getters may not override |prototype| fetching, so this is repeatable.
-    getProto->markUneffectful();
+    // explicit operation in the bytecode, we cannot use resumeAfter().
+    // Getters may not override |prototype| fetching, so this operation is indeed idempotent.
+    // - First try an idempotent property cache.
+    // - Upon failing idempotent property cache, we can't use a non-idempotent cache,
+    //   therefore we fallback to CallGetProperty
+    //
+    // Note: both CallGetProperty and GetPropertyCache can trigger a GC,
+    //       and thus invalidation.
+    MInstruction *getProto;
+    if (!invalidatedIdempotentCache()) {
+        MGetPropertyCache *getPropCache = MGetPropertyCache::New(callee, cx->names().classPrototype);
+        getPropCache->setIdempotent();
+        getProto = getPropCache;
+    } else {
+        MCallGetProperty *callGetProp = MCallGetProperty::New(callee, cx->names().classPrototype);
+        callGetProp->setIdempotent();
+        getProto = callGetProp;
+    }
     current->add(getProto);
 
+    // Create this from prototype
     MCreateThis *createThis = MCreateThis::New(callee, getProto, NULL);
     current->add(createThis);
 
     return createThis;
 }
 
 JSObject *
 IonBuilder::getSingletonPrototype(JSFunction *target)
--- a/js/src/ion/MIR.h
+++ b/js/src/ion/MIR.h
@@ -4818,21 +4818,21 @@ class MSetPropertyCache
     }
 };
 
 class MCallGetProperty
   : public MUnaryInstruction,
     public BoxInputsPolicy
 {
     CompilerRootPropertyName name_;
-    bool markEffectful_;
+    bool idempotent_;
 
     MCallGetProperty(MDefinition *value, HandlePropertyName name)
       : MUnaryInstruction(value), name_(name),
-        markEffectful_(true)
+        idempotent_(false)
     {
         setResultType(MIRType_Value);
     }
 
   public:
     INSTRUCTION_HEADER(CallGetProperty);
 
     static MCallGetProperty *New(MDefinition *value, HandlePropertyName name) {
@@ -4846,21 +4846,21 @@ class MCallGetProperty
     }
     TypePolicy *typePolicy() {
         return this;
     }
 
     // Constructors need to perform a GetProp on the function prototype.
     // Since getters cannot be set on the prototype, fetching is non-effectful.
     // The operation may be safely repeated in case of bailout.
-    void markUneffectful() {
-        markEffectful_ = false;
+    void setIdempotent() {
+        idempotent_ = true;
     }
     AliasSet getAliasSet() const {
-        if (markEffectful_)
+        if (!idempotent_)
             return AliasSet::Store(AliasSet::Any);
         return AliasSet::None();
     }
 };
 
 // Inline call to handle lhs[rhs]. The first input is a Value so that this
 // instruction can handle both objects and strings.
 class MCallGetElement