Skip to content

Commit

Permalink
Bug 1394290 - Optimize Proxy::get/set by avoiding unnecessary receive…
Browse files Browse the repository at this point in the history
…r checking. r=jandem

MozReview-Commit-ID: 7K67zt3JrQl

--HG--
extra : rebase_source : 3a4796844a922c59949f787b0e40d9470e4c94f8
  • Loading branch information
janus926 committed Aug 28, 2017
1 parent f1a8845 commit e5727d7
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 19 deletions.
54 changes: 35 additions & 19 deletions js/src/proxy/Proxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -300,17 +300,19 @@ js::ProxyHasOwn(JSContext* cx, HandleObject proxy, HandleValue idVal, MutableHan
}

static MOZ_ALWAYS_INLINE Value
ValueToWindowProxyIfWindow(const Value& v)
ValueToWindowProxyIfWindow(const Value& v, JSObject* proxy)
{
if (v.isObject())
if (v.isObject() && v != ObjectValue(*proxy))
return ObjectValue(*ToWindowProxyIfWindow(&v.toObject()));
return v;
}

MOZ_ALWAYS_INLINE bool
Proxy::get(JSContext* cx, HandleObject proxy, HandleValue receiver_, HandleId id,
MutableHandleValue vp)
Proxy::getInternal(JSContext* cx, HandleObject proxy, HandleValue receiver,
HandleId id, MutableHandleValue vp)
{
MOZ_ASSERT_IF(receiver.isObject(), !IsWindow(&receiver.toObject()));

if (!CheckRecursionLimit(cx))
return false;
const BaseProxyHandler* handler = proxy->as<ProxyObject>().handler();
Expand All @@ -319,10 +321,6 @@ Proxy::get(JSContext* cx, HandleObject proxy, HandleValue receiver_, HandleId id
if (!policy.allowed())
return policy.returnValue();

// Use the WindowProxy as receiver if receiver_ is a Window. Proxy handlers
// shouldn't have to know about the Window/WindowProxy distinction.
RootedValue receiver(cx, ValueToWindowProxyIfWindow(receiver_));

if (handler->hasPrototype()) {
bool own;
if (!handler->hasOwn(cx, proxy, id, &own))
Expand All @@ -340,11 +338,21 @@ Proxy::get(JSContext* cx, HandleObject proxy, HandleValue receiver_, HandleId id
return handler->get(cx, proxy, receiver, id, vp);
}

bool
Proxy::get(JSContext* cx, HandleObject proxy, HandleValue receiver_, HandleId id,
MutableHandleValue vp)
{
// Use the WindowProxy as receiver if receiver_ is a Window. Proxy handlers
// shouldn't have to know about the Window/WindowProxy distinction.
RootedValue receiver(cx, ValueToWindowProxyIfWindow(receiver_, proxy));
return getInternal(cx, proxy, receiver, id, vp);
}

bool
js::ProxyGetProperty(JSContext* cx, HandleObject proxy, HandleId id, MutableHandleValue vp)
{
RootedValue receiver(cx, ObjectValue(*proxy));
return Proxy::get(cx, proxy, receiver, id, vp);
return Proxy::getInternal(cx, proxy, receiver, id, vp);
}

bool
Expand All @@ -356,13 +364,15 @@ js::ProxyGetPropertyByValue(JSContext* cx, HandleObject proxy, HandleValue idVal
return false;

RootedValue receiver(cx, ObjectValue(*proxy));
return Proxy::get(cx, proxy, receiver, id, vp);
return Proxy::getInternal(cx, proxy, receiver, id, vp);
}

bool
Proxy::set(JSContext* cx, HandleObject proxy, HandleId id, HandleValue v, HandleValue receiver_,
ObjectOpResult& result)
MOZ_ALWAYS_INLINE bool
Proxy::setInternal(JSContext* cx, HandleObject proxy, HandleId id, HandleValue v,
HandleValue receiver, ObjectOpResult& result)
{
MOZ_ASSERT_IF(receiver.isObject(), !IsWindow(&receiver.toObject()));

if (!CheckRecursionLimit(cx))
return false;
const BaseProxyHandler* handler = proxy->as<ProxyObject>().handler();
Expand All @@ -373,23 +383,29 @@ Proxy::set(JSContext* cx, HandleObject proxy, HandleId id, HandleValue v, Handle
return result.succeed();
}

// Use the WindowProxy as receiver if receiver_ is a Window. Proxy handlers
// shouldn't have to know about the Window/WindowProxy distinction.
RootedValue receiver(cx, ValueToWindowProxyIfWindow(receiver_));

// Special case. See the comment on BaseProxyHandler::mHasPrototype.
if (handler->hasPrototype())
return handler->BaseProxyHandler::set(cx, proxy, id, v, receiver, result);

return handler->set(cx, proxy, id, v, receiver, result);
}

bool
Proxy::set(JSContext* cx, HandleObject proxy, HandleId id, HandleValue v, HandleValue receiver_,
ObjectOpResult& result)
{
// Use the WindowProxy as receiver if receiver_ is a Window. Proxy handlers
// shouldn't have to know about the Window/WindowProxy distinction.
RootedValue receiver(cx, ValueToWindowProxyIfWindow(receiver_, proxy));
return setInternal(cx, proxy, id, v, receiver, result);
}

bool
js::ProxySetProperty(JSContext* cx, HandleObject proxy, HandleId id, HandleValue val, bool strict)
{
ObjectOpResult result;
RootedValue receiver(cx, ObjectValue(*proxy));
if (!Proxy::set(cx, proxy, id, val, receiver, result))
if (!Proxy::setInternal(cx, proxy, id, val, receiver, result))
return false;
return result.checkStrictErrorOrWarning(cx, proxy, id, strict);
}
Expand All @@ -404,7 +420,7 @@ js::ProxySetPropertyByValue(JSContext* cx, HandleObject proxy, HandleValue idVal

ObjectOpResult result;
RootedValue receiver(cx, ObjectValue(*proxy));
if (!Proxy::set(cx, proxy, id, val, receiver, result))
if (!Proxy::setInternal(cx, proxy, id, val, receiver, result))
return false;
return result.checkStrictErrorOrWarning(cx, proxy, id, strict);
}
Expand Down
4 changes: 4 additions & 0 deletions js/src/proxy/Proxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,12 @@ class Proxy
static bool has(JSContext* cx, HandleObject proxy, HandleId id, bool* bp);
static bool get(JSContext* cx, HandleObject proxy, HandleValue receiver, HandleId id,
MutableHandleValue vp);
static bool getInternal(JSContext* cx, HandleObject proxy, HandleValue receiver,
HandleId id, MutableHandleValue vp);
static bool set(JSContext* cx, HandleObject proxy, HandleId id, HandleValue v,
HandleValue receiver, ObjectOpResult& result);
static bool setInternal(JSContext* cx, HandleObject proxy, HandleId id, HandleValue v,
HandleValue receiver, ObjectOpResult& result);
static bool call(JSContext* cx, HandleObject proxy, const CallArgs& args);
static bool construct(JSContext* cx, HandleObject proxy, const CallArgs& args);

Expand Down

0 comments on commit e5727d7

Please sign in to comment.