Bug 935952 - Clean up TypeObjectKey property interface to avoid querying objects with unknown properties, r=jandem.
authorBrian Hackett <bhackett1024@gmail.com>
Fri, 08 Nov 2013 08:56:10 -0700
changeset 168757 0fdbc3f4d34ee6df5da20f76e3c2fe81828e6b49
parent 168731 a712c9fec54f78453055f0e64998e6146781625a
child 168758 4a248fb47a8e48530ffb298377ec36ecb98678d5
push id3224
push userlsblakk@mozilla.com
push dateTue, 04 Feb 2014 01:06:49 +0000
treeherdermozilla-beta@60c04d0987f1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs935952
milestone28.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 935952 - Clean up TypeObjectKey property interface to avoid querying objects with unknown properties, r=jandem.
js/src/jit/IonBuilder.cpp
js/src/jit/MIR.cpp
js/src/jsinfer.cpp
js/src/jsinfer.h
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -5969,20 +5969,23 @@ IonBuilder::testSingletonProperty(JSObje
     // reconfigured as a getter/setter then the type information for the
     // property will change and trigger invalidation.
 
     while (obj) {
         if (!ClassHasEffectlessLookup(obj->getClass()))
             return nullptr;
 
         types::TypeObjectKey *objType = types::TypeObjectKey::get(obj);
+        if (context())
+            objType->ensureTrackedProperty(context(), NameToId(name));
+
         if (objType->unknownProperties())
             return nullptr;
 
-        types::HeapTypeSetKey property = objType->property(NameToId(name), context());
+        types::HeapTypeSetKey property = objType->property(NameToId(name));
         if (property.isOwnProperty(constraints())) {
             if (obj->hasSingletonType())
                 return property.singleton(constraints());
             return nullptr;
         }
 
         if (ClassHasResolveHook(compartment, obj->getClass(), name))
             return nullptr;
@@ -6044,20 +6047,22 @@ IonBuilder::testSingletonPropertyTypes(M
 
         // 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.
         for (unsigned i = 0; i < types->getObjectCount(); i++) {
             types::TypeObjectKey *object = types->getObject(i);
             if (!object)
                 continue;
+            if (context())
+                object->ensureTrackedProperty(context(), NameToId(name));
 
             if (object->unknownProperties())
                 return false;
-            types::HeapTypeSetKey property = object->property(NameToId(name), context());
+            types::HeapTypeSetKey property = object->property(NameToId(name));
             if (property.isOwnProperty(constraints()))
                 return false;
 
             if (JSObject *proto = object->proto().toObjectOrNull()) {
                 // Test this type.
                 if (testSingletonProperty(proto, name) != singleton)
                     return false;
             } else {
@@ -6182,22 +6187,25 @@ IonBuilder::getStaticName(JSObject *stat
             return pushConstant(UndefinedValue());
         if (name == names().NaN)
             return pushConstant(compartment->runtimeFromAnyThread()->NaNValue);
         if (name == names().Infinity)
             return pushConstant(compartment->runtimeFromAnyThread()->positiveInfinityValue);
     }
 
     types::TypeObjectKey *staticType = types::TypeObjectKey::get(staticObject);
+    if (context())
+        staticType->ensureTrackedProperty(context(), NameToId(name));
+
     if (staticType->unknownProperties()) {
         *psucceeded = false;
         return true;
     }
 
-    types::HeapTypeSetKey property = staticType->property(id, context());
+    types::HeapTypeSetKey property = staticType->property(id);
     if (!property.maybeTypes() ||
         !property.maybeTypes()->definiteProperty() ||
         property.configured(constraints(), staticType))
     {
         // The property has been reconfigured as non-configurable, non-enumerable
         // or non-writable.
         *psucceeded = false;
         return true;
--- a/js/src/jit/MIR.cpp
+++ b/js/src/jit/MIR.cpp
@@ -2923,18 +2923,21 @@ jit::PropertyReadNeedsTypeBarrier(JSCont
     if (updateObserved && observed->empty() && name) {
         JSObject *obj = object->singleton() ? object->singleton() : object->proto().toObjectOrNull();
 
         while (obj) {
             if (!obj->isNative())
                 break;
 
             types::TypeObjectKey *typeObj = types::TypeObjectKey::get(obj);
+            if (propertycx)
+                typeObj->ensureTrackedProperty(propertycx, NameToId(name));
+
             if (!typeObj->unknownProperties()) {
-                types::HeapTypeSetKey property = typeObj->property(NameToId(name), propertycx);
+                types::HeapTypeSetKey property = typeObj->property(NameToId(name));
                 if (property.maybeTypes()) {
                     types::TypeSet::TypeList types;
                     if (!property.maybeTypes()->enumerateTypes(&types))
                         return false;
                     if (types.length()) {
                         if (!observed->addType(types[0], GetIonContext()->temp->lifoAlloc()))
                             return false;
                         break;
--- a/js/src/jsinfer.cpp
+++ b/js/src/jsinfer.cpp
@@ -822,42 +822,44 @@ bool
 TypeObjectKey::unknownProperties()
 {
     if (TypeObject *type = maybeType())
         return type->unknownProperties();
     return false;
 }
 
 HeapTypeSetKey
-TypeObjectKey::property(jsid id, JSContext *maybecx /* = nullptr */)
+TypeObjectKey::property(jsid id)
 {
     JS_ASSERT(!unknownProperties());
 
     HeapTypeSetKey property;
     property.object_ = this;
     property.id_ = id;
     if (TypeObject *type = maybeType())
         property.maybeTypes_ = type->maybeGetProperty(id);
 
+    return property;
+}
+
+void
+TypeObjectKey::ensureTrackedProperty(JSContext *cx, jsid id)
+{
 #ifdef JS_ION
     // If we are accessing a lazily defined property which actually exists in
     // the VM and has not been instantiated yet, instantiate it now if we are
     // on the main thread and able to do so.
-    if (maybecx && !property.maybeTypes() && !JSID_IS_VOID(id) && !JSID_IS_EMPTY(id)) {
-        JS_ASSERT(CurrentThreadCanAccessRuntime(maybecx->runtime()));
-        JSObject *singleton = isSingleObject() ? asSingleObject() : asTypeObject()->singleton;
-        if (singleton && singleton->isNative() && singleton->nativeLookupPure(id)) {
-            EnsureTrackPropertyTypes(maybecx, singleton, id);
-            if (TypeObject *type = maybeType())
-                property.maybeTypes_ = type->maybeGetProperty(id);
+    if (!JSID_IS_VOID(id) && !JSID_IS_EMPTY(id)) {
+        JS_ASSERT(CurrentThreadCanAccessRuntime(cx->runtime()));
+        if (JSObject *obj = singleton()) {
+            if (obj->isNative() && obj->nativeLookupPure(id))
+                EnsureTrackPropertyTypes(cx, obj, id);
         }
     }
 #endif // JS_ION
-
-    return property;
 }
 
 bool
 HeapTypeSetKey::instantiate(JSContext *cx)
 {
     if (maybeTypes())
         return true;
     if (object()->isSingleObject() && !object()->asSingleObject()->getType(cx))
--- a/js/src/jsinfer.h
+++ b/js/src/jsinfer.h
@@ -1252,17 +1252,18 @@ struct TypeObjectKey
     JSObject *singleton();
     TypeNewScript *newScript();
 
     bool unknownProperties();
     bool hasFlags(CompilerConstraintList *constraints, TypeObjectFlags flags);
     void watchStateChangeForInlinedCall(CompilerConstraintList *constraints);
     void watchStateChangeForNewScriptTemplate(CompilerConstraintList *constraints);
     void watchStateChangeForTypedArrayBuffer(CompilerConstraintList *constraints);
-    HeapTypeSetKey property(jsid id, JSContext *maybecx = nullptr);
+    HeapTypeSetKey property(jsid id);
+    void ensureTrackedProperty(JSContext *cx, jsid id);
 
     TypeObject *maybeType();
 };
 
 // Representation of a heap type property which may or may not be instantiated.
 // Heap properties for singleton types are instantiated lazily as they are used
 // by the compiler, but this is only done on the main thread. If we are
 // compiling off thread and use a property which has not yet been instantiated,