Bug 686582 - Begin to specialize ObjectOps::getElement to not just delegate to ObjectOps::getProperty. r=dvander
authorJeff Walden <jwalden@mit.edu>
Wed, 10 Aug 2011 14:54:52 -0700
changeset 77030 ac7511f7bbc10492c3b1965a130571230b349de6
parent 77029 6806beccdeaffd39a5852f1692e89c225e840cee
child 77031 0e57034d12801b30b59dcffac0aac4bab5940745
push id3
push userfelipc@gmail.com
push dateFri, 30 Sep 2011 20:09:13 +0000
reviewersdvander
bugs686582
milestone9.0a1
Bug 686582 - Begin to specialize ObjectOps::getElement to not just delegate to ObjectOps::getProperty. r=dvander
js/src/jsarray.cpp
js/src/jsobj.cpp
js/src/jsobj.h
js/src/jstypedarray.cpp
--- a/js/src/jsarray.cpp
+++ b/js/src/jsarray.cpp
@@ -817,20 +817,48 @@ array_getProperty(JSContext *cx, JSObjec
                  js::types::TypeHasProperty(cx, obj->type(), JSID_VOID, *vp));
 
     return JS_TRUE;
 }
 
 static JSBool
 array_getElement(JSContext *cx, JSObject *obj, JSObject *receiver, uint32 index, Value *vp)
 {
+    if (!obj->isDenseArray())
+        return js_GetElement(cx, obj, index, vp);
+
+    if (index < obj->getDenseArrayCapacity() &&
+        !obj->getDenseArrayElement(index).isMagic(JS_ARRAY_HOLE))
+    {
+        *vp = obj->getDenseArrayElement(index);
+        return true;
+    }
+
+    JSObject *proto = obj->getProto();
+    if (!proto) {
+        vp->setUndefined();
+        return true;
+    }
+
+    vp->setUndefined();
+
     jsid id;
     if (!IndexToId(cx, index, &id))
         return false;
-    return array_getProperty(cx, obj, receiver, id, vp);
+
+    JSObject *obj2;
+    JSProperty *prop;
+    if (!LookupPropertyWithFlags(cx, proto, id, cx->resolveFlags, &obj2, &prop))
+        return false;
+
+    if (!prop || !obj2->isNative())
+        return true;
+
+    const Shape *shape = (const Shape *) prop;
+    return js_NativeGet(cx, obj, obj2, shape, JSGET_METHOD_BARRIER, vp);
 }
 
 static JSBool
 slowarray_addProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp)
 {
     jsuint index, length;
 
     if (!js_IdIsIndex(id, &index))
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -5873,16 +5873,27 @@ js_GetPropertyHelper(JSContext *cx, JSOb
 JSBool
 js_GetProperty(JSContext *cx, JSObject *obj, JSObject *receiver, jsid id, Value *vp)
 {
     /* This call site is hot -- use the always-inlined variant of js_GetPropertyHelper(). */
     return js_GetPropertyHelperInline(cx, obj, receiver, id, JSGET_METHOD_BARRIER, vp);
 }
 
 JSBool
+js_GetElement(JSContext *cx, JSObject *obj, JSObject *receiver, uint32 index, Value *vp)
+{
+    jsid id;
+    if (!IndexToId(cx, index, &id))
+        return false;
+
+    /* This call site is hot -- use the always-inlined variant of js_GetPropertyHelper(). */
+    return js_GetPropertyHelperInline(cx, obj, receiver, id, JSGET_METHOD_BARRIER, vp);
+}
+
+JSBool
 js::GetPropertyDefault(JSContext *cx, JSObject *obj, jsid id, const Value &def, Value *vp)
 {
     JSProperty *prop;
     JSObject *obj2;
     if (!LookupPropertyWithFlags(cx, obj, id, JSRESOLVE_QUALIFIED, &obj2, &prop))
         return false;
 
     if (!prop) {
--- a/js/src/jsobj.h
+++ b/js/src/jsobj.h
@@ -252,22 +252,31 @@ js_LookupElement(JSContext *cx, JSObject
 
 extern JSBool
 js_DefineProperty(JSContext *cx, JSObject *obj, jsid id, const js::Value *value,
                   js::PropertyOp getter, js::StrictPropertyOp setter, uintN attrs);
 
 extern JSBool
 js_GetProperty(JSContext *cx, JSObject *obj, JSObject *receiver, jsid id, js::Value *vp);
 
+extern JSBool
+js_GetElement(JSContext *cx, JSObject *obj, JSObject *receiver, uint32, js::Value *vp);
+
 inline JSBool
 js_GetProperty(JSContext *cx, JSObject *obj, jsid id, js::Value *vp)
 {
     return js_GetProperty(cx, obj, obj, id, vp);
 }
 
+inline JSBool
+js_GetElement(JSContext *cx, JSObject *obj, uint32 index, js::Value *vp)
+{
+    return js_GetElement(cx, obj, obj, index, vp);
+}
+
 namespace js {
 
 extern JSBool
 GetPropertyDefault(JSContext *cx, JSObject *obj, jsid id, const Value &def, Value *vp);
 
 } /* namespace js */
 
 extern JSBool
--- a/js/src/jstypedarray.cpp
+++ b/js/src/jstypedarray.cpp
@@ -346,20 +346,20 @@ ArrayBuffer::obj_getProperty(JSContext *
     if (!delegate)
         return false;
     return js_GetProperty(cx, delegate, receiver, id, vp);
 }
 
 JSBool
 ArrayBuffer::obj_getElement(JSContext *cx, JSObject *obj, JSObject *receiver, uint32 index, Value *vp)
 {
-    jsid id;
-    if (!IndexToId(cx, index, &id))
+    JSObject *delegate = DelegateObject(cx, getArrayBuffer(obj));
+    if (!delegate)
         return false;
-    return obj_getProperty(cx, obj, receiver, id, vp);
+    return js_GetElement(cx, delegate, receiver, index, vp);
 }
 
 JSBool
 ArrayBuffer::obj_setProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp, JSBool strict)
 {
     if (JSID_IS_ATOM(id, cx->runtime->atomState.byteLengthAtom))
         return true;
 
@@ -903,20 +903,46 @@ class TypedArrayTemplate
         }
 
         return true;
     }
 
     static JSBool
     obj_getElement(JSContext *cx, JSObject *obj, JSObject *receiver, uint32 index, Value *vp)
     {
+        JSObject *tarray = getTypedArray(obj);
+
+        if (index < getLength(tarray)) {
+            // this inline function is specialized for each type
+            copyIndexToValue(cx, tarray, index, vp);
+            return true;
+        }
+
+        JSObject *proto = obj->getProto();
+        if (!proto) {
+            vp->setUndefined();
+            return true;
+        }
+
+        vp->setUndefined();
+
         jsid id;
         if (!IndexToId(cx, index, &id))
             return false;
-        return obj_getProperty(cx, obj, receiver, id, vp);
+
+        JSObject *obj2;
+        JSProperty *prop;
+        if (!LookupPropertyWithFlags(cx, proto, id, cx->resolveFlags, &obj2, &prop))
+            return false;
+
+        if (!prop || !obj2->isNative())
+            return true;
+
+        const Shape *shape = (Shape *) prop;
+        return js_NativeGet(cx, obj, obj2, shape, JSGET_METHOD_BARRIER, vp);
     }
 
     static JSBool
     obj_setProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp, JSBool strict)
     {
         JSObject *tarray = getTypedArray(obj);
         JS_ASSERT(tarray);