Bug 1146165 - Stop calling Proxy::set directly from Ion IC stub. EmitObjectOpResultCheck is retained because GenerateCallSetter still uses it in the JSSetterOp case. r=efaust.

This commit is contained in:
Jason Orendorff
2015-03-22 14:54:48 -05:00
parent fa86db3453
commit 1b52d72b95
2 changed files with 24 additions and 39 deletions

View File

@@ -1567,9 +1567,6 @@ EmitCallProxyGet(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &at
masm.Push(object);
masm.movePtr(StackPointer, argProxyReg);
// Unused space, to keep the same stack layout as Proxy::set frames.
PushObjectOpResult(masm);
masm.loadJSContext(argJSContextReg);
if (!masm.icBuildOOLFakeExitFrame(returnAddr, aic))
@@ -2220,6 +2217,15 @@ EmitObjectOpResultCheck(MacroAssembler &masm, Label *failure, bool strict,
masm.bind(&noStrictError);
}
static bool
ProxySetProperty(JSContext *cx, HandleObject proxy, HandleId id, MutableHandleValue vp,
bool strict)
{
ObjectOpResult result;
return Proxy::set(cx, proxy, proxy, id, vp, result)
&& result.checkStrictErrorOrWarning(cx, proxy, id, strict);
}
static bool
EmitCallProxySet(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &attacher,
HandleId propId, RegisterSet liveRegs, Register object,
@@ -2237,23 +2243,26 @@ EmitCallProxySet(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &at
RegisterSet regSet(RegisterSet::All());
regSet.take(AnyRegister(object));
// Proxy::set(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id,
// MutableHandleValue vp, ObjectOpResult &result)
// ProxySetProperty(JSContext *cx, HandleObject proxy, HandleId id, MutableHandleValue vp,
// bool strict);
Register argJSContextReg = regSet.takeGeneral();
Register argProxyReg = regSet.takeGeneral();
Register argIdReg = regSet.takeGeneral();
Register argVpReg = regSet.takeGeneral();
Register argResultReg = regSet.takeGeneral();
Register argStrictReg = regSet.takeGeneral();
Register scratch = regSet.takeGeneral();
// Push stubCode for marking.
attacher.pushStubCodePointer(masm);
// Push args on stack first so we can take pointers to make handles.
// Push args on stack so we can take pointers to make handles.
// Push value before touching any other registers (see WARNING above).
masm.Push(value);
masm.movePtr(StackPointer, argVpReg);
masm.move32(Imm32(strict), argStrictReg);
masm.Push(propId, scratch);
masm.movePtr(StackPointer, argIdReg);
@@ -2263,10 +2272,6 @@ EmitCallProxySet(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &at
masm.Push(object);
masm.movePtr(StackPointer, argProxyReg);
// Allocate result out-param.
PushObjectOpResult(masm);
masm.movePtr(StackPointer, argResultReg);
masm.loadJSContext(argJSContextReg);
if (!masm.icBuildOOLFakeExitFrame(returnAddr, aic))
@@ -2274,24 +2279,17 @@ EmitCallProxySet(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &at
masm.enterFakeExitFrame(IonOOLProxyExitFrameLayout::Token());
// Make the call.
masm.setupUnalignedABICall(6, scratch);
masm.setupUnalignedABICall(5, scratch);
masm.passABIArg(argJSContextReg);
masm.passABIArg(argProxyReg);
masm.passABIArg(argProxyReg);
masm.passABIArg(argIdReg);
masm.passABIArg(argVpReg);
masm.passABIArg(argResultReg);
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, Proxy::set));
masm.passABIArg(argStrictReg);
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, ProxySetProperty));
// Test for error.
masm.branchIfFalseBool(ReturnReg, masm.exceptionLabel());
// Test for strict failure. We emit the check even in non-strict mode in
// order to pick up the warning if extraWarnings is enabled.
EmitObjectOpResultCheck<IonOOLProxyExitFrameLayout>(masm, masm.exceptionLabel(), strict,
scratch, argJSContextReg, argProxyReg,
argIdReg, argVpReg, argResultReg);
// masm.leaveExitFrame & pop locals
masm.adjustStack(IonOOLProxyExitFrameLayout::Size());
@@ -2508,6 +2506,7 @@ GenerateCallSetter(JSContext *cx, IonScript *ion, MacroAssembler &masm,
SetterOp target = shape->setterOp();
MOZ_ASSERT(target);
// JSSetterOp: bool fn(JSContext *cx, HandleObject obj,
// HandleId id, MutableHandleValue vp, ObjectOpResult &result);
@@ -2561,7 +2560,8 @@ GenerateCallSetter(JSContext *cx, IonScript *ion, MacroAssembler &masm,
// Test for error.
masm.branchIfFalseBool(ReturnReg, masm.exceptionLabel());
// Test for failure.
// Test for strict failure. We emit the check even in non-strict mode
// in order to pick up the warning if extraWarnings is enabled.
EmitObjectOpResultCheck<IonOOLSetterOpExitFrameLayout>(masm, masm.exceptionLabel(),
strict, scratchReg,
argJSContextReg, argObjReg,

View File

@@ -699,17 +699,14 @@ class IonOOLSetterOpExitFrameLayout : public IonOOLPropertyOpExitFrameLayout
// Proxy::get(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id,
// MutableHandleValue vp)
// Proxy::set(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id,
// MutableHandleValue vp, ObjectOpResult &result)
// ProxySetProperty(JSContext *cx, HandleObject proxy, HandleId id, MutableHandleValue vp,
// bool strict)
class IonOOLProxyExitFrameLayout
{
protected: // only to silence a clang warning about unused private fields
ExitFooterFrame footer_;
ExitFrameLayout exit_;
// result out-parameter (unused for Proxy::get)
JS::ObjectOpResult result_;
// The proxy object.
JSObject *proxy_;
@@ -734,22 +731,10 @@ class IonOOLProxyExitFrameLayout
return sizeof(IonOOLProxyExitFrameLayout);
}
static size_t offsetOfObject() {
return offsetof(IonOOLProxyExitFrameLayout, proxy_);
}
static size_t offsetOfResult() {
return offsetof(IonOOLProxyExitFrameLayout, vp0_);
}
static size_t offsetOfId() {
return offsetof(IonOOLProxyExitFrameLayout, id_);
}
static size_t offsetOfObjectOpResult() {
return offsetof(IonOOLProxyExitFrameLayout, result_);
}
inline JitCode **stubCode() {
return &stubCode_;
}