Add more rooting for interpreter, TI and JIT, bug 772303. r=terrence

This commit is contained in:
Brian Hackett 2012-07-11 16:22:41 -06:00
Родитель 5c0fdeafbc
Коммит 2572507a99
19 изменённых файлов: 174 добавлений и 153 удалений

Просмотреть файл

@ -576,7 +576,7 @@ ExecuteRegExp(JSContext *cx, Native native, unsigned argc, Value *vp)
return false;
/* Step 4. */
const Value &lastIndex = reobj->getLastIndex();
Value lastIndex = reobj->getLastIndex();
/* Step 5. */
double i;
@ -588,7 +588,7 @@ ExecuteRegExp(JSContext *cx, Native native, unsigned argc, Value *vp)
i = 0;
const jschar *chars = linearInput->chars();
size_t length = input->length();
size_t length = linearInput->length();
/* Step 9a. */
if (i < 0 || i > length) {

Просмотреть файл

@ -524,7 +524,10 @@ CheckStrictParameters(JSContext *cx, Parser *parser)
return false;
// Start with lastVariable(), not the last argument, for destructuring.
for (Shape::Range r = sc->bindings.lastVariable(); !r.empty(); r.popFront()) {
Shape::Range r = sc->bindings.lastVariable();
Shape::Range::AutoRooter root(cx, &r);
for (; !r.empty(); r.popFront()) {
jsid id = r.front().propid();
if (!JSID_IS_ATOM(id))
continue;

Просмотреть файл

@ -4327,6 +4327,18 @@ JS::CheckStackRoots(JSContext *cx)
// could happen.)
JS_ASSERT(!cx->rootingUnnecessary);
// GCs can't happen when analysis/inference/compilation are active.
if (cx->compartment->activeAnalysis)
return;
// Can switch to the atoms compartment during analysis.
if (IsAtomsCompartment(cx->compartment)) {
for (CompartmentsIter c(rt); !c.done(); c.next()) {
if (c.get()->activeAnalysis)
return;
}
}
AutoCopyFreeListToArenas copy(rt);
JSTracer checker;

Просмотреть файл

@ -4608,8 +4608,8 @@ CheckNewScriptProperties(JSContext *cx, HandleTypeObject type, JSFunction *fun)
* than we will use for subsequent new objects. Generate an object with the
* appropriate final shape.
*/
baseobj = NewReshapedObject(cx, type, baseobj->getParent(), kind,
baseobj->lastProperty());
RootedShape shape(cx, baseobj->lastProperty());
baseobj = NewReshapedObject(cx, type, baseobj->getParent(), kind, shape);
if (!baseobj ||
!type->addDefiniteProperties(cx, baseobj) ||
!initializerList.append(done)) {
@ -5428,13 +5428,15 @@ JSFunction::setTypeForScriptedFunction(JSContext *cx, bool singleton)
if (!setSingletonType(cx))
return false;
} else {
RootedFunction self(cx, this);
TypeObject *type = cx->compartment->types.newTypeObject(cx, script(),
JSProto_Function, getProto());
if (!type)
return false;
setType(type);
type->interpretedFunction = this;
self->setType(type);
type->interpretedFunction = self;
}
return true;
@ -5610,10 +5612,10 @@ JSObject::makeLazyType(JSContext *cx)
* looking at the class prototype key.
*/
if (isSlowArray())
if (self->isSlowArray())
type->flags |= OBJECT_FLAG_NON_DENSE_ARRAY | OBJECT_FLAG_NON_PACKED_ARRAY;
if (IsTypedArrayProto(this))
if (IsTypedArrayProto(self))
type->flags |= OBJECT_FLAG_NON_TYPED_ARRAY;
self->type_ = type;
@ -5666,7 +5668,7 @@ JSObject::setNewTypeUnknown(JSContext *cx)
}
TypeObject *
JSObject::getNewType(JSContext *cx, JSFunction *fun)
JSObject::getNewType(JSContext *cx, JSFunction *fun_)
{
TypeObjectSet &table = cx->compartment->newTypeObjects;
@ -5688,13 +5690,14 @@ JSObject::getNewType(JSContext *cx, JSFunction *fun)
* Object.create is called with a prototype object that is also the
* 'prototype' property of some scripted function.
*/
if (type->newScript && type->newScript->fun != fun)
if (type->newScript && type->newScript->fun != fun_)
type->clearNewScript(cx);
return type;
}
RootedObject self(cx, this);
RootedFunction fun(cx, fun_);
if (!setDelegate(cx))
return NULL;

Просмотреть файл

@ -839,7 +839,7 @@ TryNoteIter::settle()
* in *expr.
*/
static bool
DoIncDec(JSContext *cx, JSScript *script, jsbytecode *pc, const Value &v, Value *slot, Value *expr)
DoIncDec(JSContext *cx, HandleScript script, jsbytecode *pc, const Value &v, Value *slot, Value *expr)
{
const JSCodeSpec &cs = js_CodeSpec[*pc];

Просмотреть файл

@ -2183,16 +2183,16 @@ JSObject::sealOrFreeze(JSContext *cx, ImmutabilityType it)
return true;
}
bool
JSObject::isSealedOrFrozen(JSContext *cx, ImmutabilityType it, bool *resultp)
/* static */ bool
JSObject::isSealedOrFrozen(JSContext *cx, HandleObject obj, ImmutabilityType it, bool *resultp)
{
if (isExtensible()) {
if (obj->isExtensible()) {
*resultp = false;
return true;
}
AutoIdVector props(cx);
if (!GetPropertyNames(cx, this, JSITER_HIDDEN | JSITER_OWNONLY, &props))
if (!GetPropertyNames(cx, obj, JSITER_HIDDEN | JSITER_OWNONLY, &props))
return false;
RootedId id(cx);
@ -2200,7 +2200,7 @@ JSObject::isSealedOrFrozen(JSContext *cx, ImmutabilityType it, bool *resultp)
id = props[i];
unsigned attrs;
if (!getGenericAttributes(cx, id, &attrs))
if (!obj->getGenericAttributes(cx, id, &attrs))
return false;
/*
@ -2241,7 +2241,7 @@ obj_isFrozen(JSContext *cx, unsigned argc, Value *vp)
return false;
bool frozen;
if (!obj->isFrozen(cx, &frozen))
if (!JSObject::isFrozen(cx, obj, &frozen))
return false;
vp->setBoolean(frozen);
return true;
@ -2267,7 +2267,7 @@ obj_isSealed(JSContext *cx, unsigned argc, Value *vp)
return false;
bool sealed;
if (!obj->isSealed(cx, &sealed))
if (!JSObject::isSealed(cx, obj, &sealed))
return false;
vp->setBoolean(sealed);
return true;
@ -2509,7 +2509,7 @@ js::NewObjectWithType(JSContext *cx, HandleTypeObject type, JSObject *parent, gc
JSObject *
js::NewReshapedObject(JSContext *cx, HandleTypeObject type, JSObject *parent,
gc::AllocKind kind, Shape *shape)
gc::AllocKind kind, HandleShape shape)
{
RootedObject res(cx, NewObjectWithType(cx, type, parent, kind));
if (!res)
@ -2612,16 +2612,20 @@ js_CreateThisForFunction(JSContext *cx, HandleObject callee, bool newType)
JSObject *obj = js_CreateThisForFunctionWithProto(cx, callee, proto);
if (obj && newType) {
RootedObject nobj(cx, obj);
/*
* Reshape the object and give it a (lazily instantiated) singleton
* type before passing it as the 'this' value for the call.
*/
obj->clear(cx);
if (!obj->setSingletonType(cx))
nobj->clear(cx);
if (!nobj->setSingletonType(cx))
return NULL;
JSScript *calleeScript = callee->toFunction()->script();
TypeScript::SetThis(cx, calleeScript, types::Type::ObjectType(obj));
TypeScript::SetThis(cx, calleeScript, types::Type::ObjectType(nobj));
return nobj;
}
return obj;
@ -3527,10 +3531,12 @@ JSObject::growSlots(JSContext *cx, uint32_t oldCount, uint32_t newCount)
gc::AllocKind kind = type()->newScript->allocKind;
unsigned newScriptSlots = gc::GetGCKindSlots(kind);
if (newScriptSlots == numFixedSlots() && gc::TryIncrementAllocKind(&kind)) {
AutoEnterTypeInference enter(cx);
Rooted<TypeObject*> typeObj(cx, type());
RootedShape shape(cx, typeObj->newScript->shape);
JSObject *obj = NewReshapedObject(cx, typeObj,
getParent(), kind,
typeObj->newScript->shape);
getParent(), kind, shape);
if (!obj)
return false;

Просмотреть файл

@ -531,7 +531,7 @@ struct JSObject : public js::ObjectImpl
*/
bool sealOrFreeze(JSContext *cx, ImmutabilityType it);
bool isSealedOrFrozen(JSContext *cx, ImmutabilityType it, bool *resultp);
static bool isSealedOrFrozen(JSContext *cx, js::HandleObject obj, ImmutabilityType it, bool *resultp);
static inline unsigned getSealedOrFrozenAttributes(unsigned attrs, ImmutabilityType it);
@ -543,8 +543,12 @@ struct JSObject : public js::ObjectImpl
/* ES5 15.2.3.9: non-extensible, all properties non-configurable, all data props read-only */
bool freeze(JSContext *cx) { return sealOrFreeze(cx, FREEZE); }
bool isSealed(JSContext *cx, bool *resultp) { return isSealedOrFrozen(cx, SEAL, resultp); }
bool isFrozen(JSContext *cx, bool *resultp) { return isSealedOrFrozen(cx, FREEZE, resultp); }
static inline bool isSealed(JSContext *cx, js::HandleObject obj, bool *resultp) {
return isSealedOrFrozen(cx, obj, SEAL, resultp);
}
static inline bool isFrozen(JSContext *cx, js::HandleObject obj, bool *resultp) {
return isSealedOrFrozen(cx, obj, FREEZE, resultp);
}
/* Accessors for elements. */

Просмотреть файл

@ -1552,7 +1552,7 @@ CopyInitializerObject(JSContext *cx, HandleObject baseobj)
JSObject *
NewReshapedObject(JSContext *cx, HandleTypeObject type, JSObject *parent,
gc::AllocKind kind, Shape *shape);
gc::AllocKind kind, HandleShape shape);
/*
* As for gc::GetGCObjectKind, where numSlots is a guess at the final size of

Просмотреть файл

@ -367,7 +367,7 @@ IndirectProxyHandler::getPropertyDescriptor(JSContext *cx, JSObject *proxy,
}
static bool
GetOwnPropertyDescriptor(JSContext *cx, JSObject *obj, jsid id, unsigned flags,
GetOwnPropertyDescriptor(JSContext *cx, HandleObject obj, jsid id, unsigned flags,
JSPropertyDescriptor *desc)
{
// If obj is a proxy, we can do better than just guessing. This is
@ -389,7 +389,8 @@ IndirectProxyHandler::getOwnPropertyDescriptor(JSContext *cx, JSObject *proxy,
jsid id, bool set,
PropertyDescriptor *desc)
{
return GetOwnPropertyDescriptor(cx, GetProxyTargetObject(proxy), id,
RootedObject target(cx, GetProxyTargetObject(proxy));
return GetOwnPropertyDescriptor(cx, target, id,
JSRESOLVE_QUALIFIED, desc);
}

Просмотреть файл

@ -1717,7 +1717,7 @@ GetCurrentScopeChain(JSContext *cx)
}
static JSXML *
ParseXMLSource(JSContext *cx, JSString *src)
ParseXMLSource(JSContext *cx, HandleString src)
{
jsval nsval;
JSLinearString *uri;
@ -1856,7 +1856,7 @@ ToXML(JSContext *cx, jsval v)
JSObject *obj;
JSXML *xml;
Class *clasp;
JSString *str;
RootedString str(cx);
uint32_t length;
if (JSVAL_IS_PRIMITIVE(v)) {
@ -1937,7 +1937,7 @@ ToXMLList(JSContext *cx, jsval v)
JSObject *obj, *listobj;
JSXML *xml, *list, *kid;
Class *clasp;
JSString *str;
RootedString str(cx);
uint32_t i, length;
if (JSVAL_IS_PRIMITIVE(v)) {

Просмотреть файл

@ -1375,7 +1375,7 @@ static const JSC::MacroAssembler::RegisterID JSParamReg_Argc = JSC::MIPSRegiste
};
/* Return f<true> if the script is strict mode code, f<false> otherwise. */
#define STRICT_VARIANT(f) \
#define STRICT_VARIANT(script, f) \
(FunctionTemplateConditional(script->strictModeCode, \
f<true>, f<false>))

Просмотреть файл

@ -2554,7 +2554,7 @@ mjit::Compiler::generateMethod()
prepareStubCall(Uses(1));
masm.move(ImmPtr(name), Registers::ArgReg1);
INLINE_STUBCALL(STRICT_VARIANT(stubs::DelProp), REJOIN_FALLTHROUGH);
INLINE_STUBCALL(STRICT_VARIANT(script, stubs::DelProp), REJOIN_FALLTHROUGH);
frame.pop();
pushSyncedEntry(0);
}
@ -2563,7 +2563,7 @@ mjit::Compiler::generateMethod()
BEGIN_CASE(JSOP_DELELEM)
{
prepareStubCall(Uses(2));
INLINE_STUBCALL(STRICT_VARIANT(stubs::DelElem), REJOIN_FALLTHROUGH);
INLINE_STUBCALL(STRICT_VARIANT(script, stubs::DelElem), REJOIN_FALLTHROUGH);
frame.popn(2);
pushSyncedEntry(0);
}
@ -3064,7 +3064,7 @@ mjit::Compiler::generateMethod()
prepareStubCall(Uses(0));
masm.move(ImmPtr(innerFun), Registers::ArgReg1);
INLINE_STUBCALL(STRICT_VARIANT(stubs::DefFun), REJOIN_FALLTHROUGH);
INLINE_STUBCALL(STRICT_VARIANT(script, stubs::DefFun), REJOIN_FALLTHROUGH);
}
END_CASE(JSOP_DEFFUN)
@ -4236,18 +4236,8 @@ mjit::Compiler::inlineCallHelper(uint32_t argc, bool callingNew, FrameSize &call
if (icCalleeType.isSet())
notObjectJump = masm.testObject(Assembler::NotEqual, icCalleeType.reg());
/*
* For an optimized apply, keep icCalleeData in a callee-saved register for
* the subsequent ic::SplatApplyArgs call.
*/
Registers tempRegs(Registers::AvailRegs);
if (callIC.frameSize.isDynamic() && !Registers::isSaved(icCalleeData)) {
RegisterID x = tempRegs.takeAnyReg(Registers::SavedRegs).reg();
masm.move(icCalleeData, x);
icCalleeData = x;
} else {
tempRegs.takeReg(icCalleeData);
}
/* Reserve space just before initialization of funGuard. */
RESERVE_IC_SPACE(masm);
@ -4288,9 +4278,16 @@ mjit::Compiler::inlineCallHelper(uint32_t argc, bool callingNew, FrameSize &call
* Check after the function is known not to be a native so that the
* catch-all/native path has a static depth.
*/
if (callIC.frameSize.isDynamic())
if (callIC.frameSize.isDynamic()) {
OOL_STUBCALL(ic::SplatApplyArgs, REJOIN_CALL_SPLAT);
/*
* Restore identity of callee after SplatApplyArgs, which may
* have been clobbered (not callee save reg or changed by moving GC).
*/
stubcc.masm.loadPayload(frame.addressOf(origThis), icCalleeData);
}
/*
* No-op jump that gets patched by ic::New/Call to the stub generated
* by generateFullCallStub.
@ -4733,7 +4730,7 @@ mjit::Compiler::jsop_setprop_slow(PropertyName *name)
{
prepareStubCall(Uses(2));
masm.move(ImmPtr(name), Registers::ArgReg1);
INLINE_STUBCALL(STRICT_VARIANT(stubs::SetName), REJOIN_FALLTHROUGH);
INLINE_STUBCALL(STRICT_VARIANT(script, stubs::SetName), REJOIN_FALLTHROUGH);
JS_STATIC_ASSERT(JSOP_SETNAME_LENGTH == JSOP_SETPROP_LENGTH);
frame.shimmy(1);
if (script->hasScriptCounts)
@ -5471,7 +5468,7 @@ mjit::Compiler::jsop_setprop(PropertyName *name, bool popGuaranteed)
stubcc.linkExit(notObject.get(), Uses(2));
stubcc.leave();
stubcc.masm.move(ImmPtr(name), Registers::ArgReg1);
OOL_STUBCALL(STRICT_VARIANT(stubs::SetName), REJOIN_FALLTHROUGH);
OOL_STUBCALL(STRICT_VARIANT(script, stubs::SetName), REJOIN_FALLTHROUGH);
}
frame.storeTo(rhs, Address(reg, JSObject::getFixedSlotOffset(slot)), popGuaranteed);
frame.unpinReg(reg);
@ -5535,7 +5532,7 @@ mjit::Compiler::jsop_setprop(PropertyName *name, bool popGuaranteed)
stubcc.leave();
stubcc.masm.move(ImmPtr(name), Registers::ArgReg1);
OOL_STUBCALL(STRICT_VARIANT(stubs::SetName), REJOIN_FALLTHROUGH);
OOL_STUBCALL(STRICT_VARIANT(script, stubs::SetName), REJOIN_FALLTHROUGH);
typeCheck = stubcc.masm.jump();
pic.hasTypeCheck = true;
@ -6463,7 +6460,7 @@ mjit::Compiler::jsop_setgname_slow(PropertyName *name)
{
prepareStubCall(Uses(2));
masm.move(ImmPtr(name), Registers::ArgReg1);
INLINE_STUBCALL(STRICT_VARIANT(stubs::SetGlobalName), REJOIN_FALLTHROUGH);
INLINE_STUBCALL(STRICT_VARIANT(script, stubs::SetGlobalName), REJOIN_FALLTHROUGH);
frame.popn(2);
pushSyncedEntry(0);
}
@ -6600,7 +6597,7 @@ void
mjit::Compiler::jsop_setelem_slow()
{
prepareStubCall(Uses(3));
INLINE_STUBCALL(STRICT_VARIANT(stubs::SetElem), REJOIN_FALLTHROUGH);
INLINE_STUBCALL(STRICT_VARIANT(script, stubs::SetElem), REJOIN_FALLTHROUGH);
frame.popn(3);
frame.pushSynced(JSVAL_TYPE_UNKNOWN);
}

Просмотреть файл

@ -1212,7 +1212,7 @@ mjit::Compiler::jsop_setelem_dense()
masm.storeValue(vr, BaseIndex(slotsReg, key.reg(), masm.JSVAL_SCALE));
stubcc.leave();
OOL_STUBCALL(STRICT_VARIANT(stubs::SetElem), REJOIN_FALLTHROUGH);
OOL_STUBCALL(STRICT_VARIANT(script, stubs::SetElem), REJOIN_FALLTHROUGH);
if (!hoisted)
frame.freeReg(slotsReg);
@ -1486,7 +1486,7 @@ mjit::Compiler::jsop_setelem_typed(int atype)
frame.freeReg(objReg);
stubcc.leave();
OOL_STUBCALL(STRICT_VARIANT(stubs::SetElem), REJOIN_FALLTHROUGH);
OOL_STUBCALL(STRICT_VARIANT(script, stubs::SetElem), REJOIN_FALLTHROUGH);
frame.shimmy(2);
stubcc.rejoin(Changes(2));
@ -1687,9 +1687,9 @@ mjit::Compiler::jsop_setelem(bool popGuaranteed)
stubcc.leave();
#if defined JS_POLYIC
passICAddress(&ic);
ic.slowPathCall = OOL_STUBCALL(STRICT_VARIANT(ic::SetElement), REJOIN_FALLTHROUGH);
ic.slowPathCall = OOL_STUBCALL(STRICT_VARIANT(script, ic::SetElement), REJOIN_FALLTHROUGH);
#else
OOL_STUBCALL(STRICT_VARIANT(stubs::SetElem), REJOIN_FALLTHROUGH);
OOL_STUBCALL(STRICT_VARIANT(script, stubs::SetElem), REJOIN_FALLTHROUGH);
#endif
ic.fastPathRejoin = masm.label();

Просмотреть файл

@ -58,12 +58,12 @@ PatchGetFallback(VMFrame &f, ic::GetGlobalNameIC *ic)
void JS_FASTCALL
ic::GetGlobalName(VMFrame &f, ic::GetGlobalNameIC *ic)
{
JSObject &obj = f.fp()->global();
RootedObject obj(f.cx, &f.fp()->global());
PropertyName *name = f.script()->getName(GET_UINT32_INDEX(f.pc()));
RecompilationMonitor monitor(f.cx);
Shape *shape = obj.nativeLookup(f.cx, NameToId(name));
Shape *shape = obj->nativeLookup(f.cx, NameToId(name));
if (monitor.recompiled()) {
stubs::Name(f);
@ -83,10 +83,10 @@ ic::GetGlobalName(VMFrame &f, ic::GetGlobalNameIC *ic)
/* Patch shape guard. */
Repatcher repatcher(f.chunk());
repatcher.repatch(ic->fastPathStart.dataLabelPtrAtOffset(ic->shapeOffset), obj.lastProperty());
repatcher.repatch(ic->fastPathStart.dataLabelPtrAtOffset(ic->shapeOffset), obj->lastProperty());
/* Patch loads. */
uint32_t index = obj.dynamicSlotIndex(slot);
uint32_t index = obj->dynamicSlotIndex(slot);
JSC::CodeLocationLabel label = ic->fastPathStart.labelAtOffset(ic->loadStoreOffset);
repatcher.patchAddressOffsetForValueLoad(label, index * sizeof(Value));
@ -107,9 +107,8 @@ template void JS_FASTCALL DisabledSetGlobal<false>(VMFrame &f, ic::SetGlobalName
static void
PatchSetFallback(VMFrame &f, ic::SetGlobalNameIC *ic)
{
JSScript *script = f.script();
Repatcher repatch(f.chunk());
VoidStubSetGlobal stub = STRICT_VARIANT(DisabledSetGlobal);
VoidStubSetGlobal stub = STRICT_VARIANT(f.script(), DisabledSetGlobal);
JSC::FunctionPtr fptr(JS_FUNC_TO_DATA_PTR(void *, stub));
repatch.relink(ic->slowPathCall, fptr);
}
@ -153,21 +152,20 @@ UpdateSetGlobalName(VMFrame &f, ic::SetGlobalNameIC *ic, JSObject *obj, Shape *s
void JS_FASTCALL
ic::SetGlobalName(VMFrame &f, ic::SetGlobalNameIC *ic)
{
JSObject &obj = f.fp()->global();
JSScript *script = f.script();
PropertyName *name = script->getName(GET_UINT32_INDEX(f.pc()));
RootedObject obj(f.cx, &f.fp()->global());
RootedPropertyName name(f.cx, f.script()->getName(GET_UINT32_INDEX(f.pc())));
RecompilationMonitor monitor(f.cx);
Shape *shape = obj.nativeLookup(f.cx, NameToId(name));
Shape *shape = obj->nativeLookup(f.cx, NameToId(name));
if (!monitor.recompiled()) {
LookupStatus status = UpdateSetGlobalName(f, ic, &obj, shape);
LookupStatus status = UpdateSetGlobalName(f, ic, obj, shape);
if (status == Lookup_Error)
THROW();
}
STRICT_VARIANT(stubs::SetGlobalName)(f, name);
STRICT_VARIANT(f.script(), stubs::SetGlobalName)(f, name);
}
class EqualityICLinker : public LinkerHelper
@ -764,8 +762,8 @@ class CallCompiler : public BaseCompiler
args = CallArgsFromSp(f.u.call.dynamicArgc, f.regs.sp);
}
JSFunction *fun;
if (!IsFunctionObject(args.calleev(), &fun))
RootedFunction fun(cx);
if (!IsFunctionObject(args.calleev(), fun.address()))
return false;
if ((!callingNew && !fun->isNative()) || (callingNew && !fun->isNativeConstructor()))

Просмотреть файл

@ -68,7 +68,6 @@ class PICStubCompiler : public BaseCompiler
protected:
const char *type;
VMFrame &f;
JSScript *script;
ic::PICInfo &pic;
void *stub;
uint64_t gcNumber;
@ -76,8 +75,8 @@ class PICStubCompiler : public BaseCompiler
public:
bool canCallHook;
PICStubCompiler(const char *type, VMFrame &f, JSScript *script, ic::PICInfo &pic, void *stub)
: BaseCompiler(f.cx), type(type), f(f), script(script), pic(pic), stub(stub),
PICStubCompiler(const char *type, VMFrame &f, ic::PICInfo &pic, void *stub)
: BaseCompiler(f.cx), type(type), f(f), pic(pic), stub(stub),
gcNumber(f.cx->runtime->gcNumber), canCallHook(pic.canCallHook)
{ }
@ -113,7 +112,7 @@ class PICStubCompiler : public BaseCompiler
void spew(const char *event, const char *op) {
#ifdef JS_METHODJIT_SPEW
JaegerSpew(JSpew_PICs, "%s %s: %s (%s: %d)\n",
type, event, op, script->filename, CurrentLine(cx));
type, event, op, f.script()->filename, CurrentLine(cx));
#endif
}
};
@ -165,15 +164,15 @@ GeneratePrototypeGuards(JSContext *cx, Vector<JSC::MacroAssembler::Jump,8> &mism
class SetPropCompiler : public PICStubCompiler
{
JSObject *obj;
PropertyName *name;
RootedObject obj;
RootedPropertyName name;
int lastStubSecondShapeGuard;
public:
SetPropCompiler(VMFrame &f, JSScript *script, JSObject *obj, ic::PICInfo &pic, PropertyName *name,
SetPropCompiler(VMFrame &f, JSObject *obj, ic::PICInfo &pic, PropertyName *name,
VoidStubPIC stub)
: PICStubCompiler("setprop", f, script, pic, JS_FUNC_TO_DATA_PTR(void *, stub)),
obj(obj), name(name), lastStubSecondShapeGuard(pic.secondShapeGuard)
: PICStubCompiler("setprop", f, pic, JS_FUNC_TO_DATA_PTR(void *, stub)),
obj(f.cx, obj), name(f.cx, name), lastStubSecondShapeGuard(pic.secondShapeGuard)
{ }
static void reset(Repatcher &repatcher, ic::PICInfo &pic)
@ -751,17 +750,17 @@ namespace mjit {
class GetPropCompiler : public PICStubCompiler
{
JSObject *obj;
PropertyName *name;
RootedObject obj;
RootedPropertyName name;
int lastStubSecondShapeGuard;
public:
GetPropCompiler(VMFrame &f, JSScript *script, JSObject *obj, ic::PICInfo &pic, PropertyName *name,
GetPropCompiler(VMFrame &f, JSObject *obj, ic::PICInfo &pic, PropertyName *name,
VoidStubPIC stub)
: PICStubCompiler("getprop", f, script, pic,
: PICStubCompiler("getprop", f, pic,
JS_FUNC_TO_DATA_PTR(void *, stub)),
obj(obj),
name(name),
obj(f.cx, obj),
name(f.cx, name),
lastStubSecondShapeGuard(pic.secondShapeGuard)
{ }
@ -872,7 +871,7 @@ class GetPropCompiler : public PICStubCompiler
RecompilationMonitor monitor(f.cx);
JSObject *obj = f.fp()->global().getOrCreateStringPrototype(f.cx);
RootedObject obj(f.cx, f.fp()->global().getOrCreateStringPrototype(f.cx));
if (!obj)
return error();
@ -1217,12 +1216,15 @@ class GetPropCompiler : public PICStubCompiler
linkerEpilogue(linker, start, shapeMismatches);
}
LookupStatus generateStub(JSObject *holder, Shape *shape)
LookupStatus generateStub(JSObject *holder, HandleShape shape)
{
Vector<Jump, 8> shapeMismatches(cx);
Assembler masm;
// Ignore GC pointers baked into assembly visible on the stack.
SkipRoot skip(cx, &masm);
Label start;
Jump shapeGuardJump;
Jump argsLenGuard;
@ -1445,9 +1447,9 @@ class ScopeNameCompiler : public PICStubCompiler
}
public:
ScopeNameCompiler(VMFrame &f, JSScript *script, JSObject *scopeChain, ic::PICInfo &pic,
ScopeNameCompiler(VMFrame &f, JSObject *scopeChain, ic::PICInfo &pic,
PropertyName *name, VoidStubPIC stub)
: PICStubCompiler("name", f, script, pic, JS_FUNC_TO_DATA_PTR(void *, stub)),
: PICStubCompiler("name", f, pic, JS_FUNC_TO_DATA_PTR(void *, stub)),
scopeChain(f.cx, scopeChain), name(f.cx, name),
getprop(f.cx, NULL, name, *thisFromCtor(), f)
{ }
@ -1713,9 +1715,9 @@ class BindNameCompiler : public PICStubCompiler
RootedPropertyName name;
public:
BindNameCompiler(VMFrame &f, JSScript *script, JSObject *scopeChain, ic::PICInfo &pic,
BindNameCompiler(VMFrame &f, JSObject *scopeChain, ic::PICInfo &pic,
PropertyName *name, VoidStubPIC stub)
: PICStubCompiler("bind", f, script, pic, JS_FUNC_TO_DATA_PTR(void *, stub)),
: PICStubCompiler("bind", f, pic, JS_FUNC_TO_DATA_PTR(void *, stub)),
scopeChain(f.cx, scopeChain), name(f.cx, name)
{ }
@ -1860,9 +1862,7 @@ ic::GetProp(VMFrame &f, ic::PICInfo *pic)
bool cached = pic->cached;
VoidStubPIC stub = cached ? DisabledGetPropIC : DisabledGetPropNoCacheIC;
JSScript *script = f.fp()->script();
PropertyName *name = pic->name;
RootedPropertyName name(f.cx, pic->name);
if (name == f.cx->runtime->atomState.lengthAtom) {
if (IsOptimizedArguments(f.fp(), &f.regs.sp[-1])) {
f.regs.sp[-1].setInt32(f.regs.fp()->numActualArgs());
@ -1871,7 +1871,7 @@ ic::GetProp(VMFrame &f, ic::PICInfo *pic)
if (!f.regs.sp[-1].isPrimitive()) {
JSObject *obj = &f.regs.sp[-1].toObject();
if (obj->isArray() || obj->isString()) {
GetPropCompiler cc(f, script, obj, *pic, NULL, stub);
GetPropCompiler cc(f, obj, *pic, NULL, stub);
if (obj->isArray()) {
LookupStatus status = cc.generateArrayLengthStub();
if (status == Lookup_Error)
@ -1890,7 +1890,7 @@ ic::GetProp(VMFrame &f, ic::PICInfo *pic)
}
if (f.regs.sp[-1].isString()) {
GetPropCompiler cc(f, script, NULL, *pic, name, stub);
GetPropCompiler cc(f, NULL, *pic, name, stub);
if (name == f.cx->runtime->atomState.lengthAtom) {
LookupStatus status = cc.generateStringLengthStub();
if (status == Lookup_Error)
@ -1912,22 +1912,22 @@ ic::GetProp(VMFrame &f, ic::PICInfo *pic)
RecompilationMonitor monitor(f.cx);
JSObject *obj = ValueToObject(f.cx, f.regs.sp[-1]);
RootedObject obj(f.cx, ValueToObject(f.cx, f.regs.sp[-1]));
if (!obj)
THROW();
if (!monitor.recompiled() && pic->shouldUpdate(f.cx)) {
GetPropCompiler cc(f, script, obj, *pic, name, stub);
GetPropCompiler cc(f, obj, *pic, name, stub);
if (!cc.update())
THROW();
}
Value v;
RootedValue v(f.cx);
if (cached) {
if (!GetPropertyOperation(f.cx, f.script(), f.pc(), f.regs.sp[-1], &v))
if (!GetPropertyOperation(f.cx, f.script(), f.pc(), f.regs.sp[-1], v.address()))
THROW();
} else {
if (!obj->getProperty(f.cx, name, &v))
if (!obj->getProperty(f.cx, name, v.address()))
THROW();
}
@ -1944,14 +1944,13 @@ DisabledSetPropIC(VMFrame &f, ic::PICInfo *pic)
void JS_FASTCALL
ic::SetProp(VMFrame &f, ic::PICInfo *pic)
{
JSScript *script = f.fp()->script();
JS_ASSERT(pic->isSet());
VoidStubPIC stub = STRICT_VARIANT(DisabledSetPropIC);
VoidStubPIC stub = STRICT_VARIANT(f.script(), DisabledSetPropIC);
// Save this in case the compiler triggers a recompilation of this script.
PropertyName *name = pic->name;
VoidStubName nstub = STRICT_VARIANT(stubs::SetName);
RootedPropertyName name(f.cx, pic->name);
VoidStubName nstub = STRICT_VARIANT(f.script(), stubs::SetName);
RecompilationMonitor monitor(f.cx);
@ -1962,7 +1961,7 @@ ic::SetProp(VMFrame &f, ic::PICInfo *pic)
// Note, we can't use SetName for PROPINC PICs because the property
// cache can't handle a GET and SET from the same scripted PC.
if (!monitor.recompiled() && pic->shouldUpdate(f.cx)) {
SetPropCompiler cc(f, script, obj, *pic, name, stub);
SetPropCompiler cc(f, obj, *pic, name, stub);
LookupStatus status = cc.update();
if (status == Lookup_Error)
THROW();
@ -1986,12 +1985,10 @@ DisabledXNameIC(VMFrame &f, ic::PICInfo *pic)
void JS_FASTCALL
ic::XName(VMFrame &f, ic::PICInfo *pic)
{
JSScript *script = f.fp()->script();
/* GETXPROP is guaranteed to have an object. */
JSObject *obj = &f.regs.sp[-1].toObject();
ScopeNameCompiler cc(f, script, obj, *pic, pic->name, DisabledXNameIC);
ScopeNameCompiler cc(f, obj, *pic, pic->name, DisabledXNameIC);
LookupStatus status = cc.updateForXName();
if (status == Lookup_Error)
@ -2006,16 +2003,14 @@ ic::XName(VMFrame &f, ic::PICInfo *pic)
void JS_FASTCALL
ic::Name(VMFrame &f, ic::PICInfo *pic)
{
JSScript *script = f.fp()->script();
ScopeNameCompiler cc(f, script, f.fp()->scopeChain(), *pic, pic->name, DisabledNameIC);
ScopeNameCompiler cc(f, f.fp()->scopeChain(), *pic, pic->name, DisabledNameIC);
LookupStatus status = cc.updateForName();
if (status == Lookup_Error)
THROW();
Value rval;
if (!cc.retrieve(&rval, PICInfo::NAME))
RootedValue rval(f.cx);
if (!cc.retrieve(rval.address(), PICInfo::NAME))
THROW();
f.regs.sp[0] = rval;
}
@ -2029,10 +2024,8 @@ DisabledBindNameIC(VMFrame &f, ic::PICInfo *pic)
void JS_FASTCALL
ic::BindName(VMFrame &f, ic::PICInfo *pic)
{
JSScript *script = f.fp()->script();
VoidStubPIC stub = DisabledBindNameIC;
BindNameCompiler cc(f, script, f.fp()->scopeChain(), *pic, pic->name, stub);
BindNameCompiler cc(f, f.fp()->scopeChain(), *pic, pic->name, stub);
JSObject *obj = cc.update();
if (!obj)
@ -2181,7 +2174,7 @@ GetElementIC::purge(Repatcher &repatcher)
}
LookupStatus
GetElementIC::attachGetProp(VMFrame &f, JSObject *obj, const Value &v, PropertyName *name,
GetElementIC::attachGetProp(VMFrame &f, HandleObject obj, HandleValue v, HandlePropertyName name,
Value *vp)
{
JS_ASSERT(v.isString());
@ -2362,7 +2355,7 @@ GetElementIC::attachGetProp(VMFrame &f, JSObject *obj, const Value &v, PropertyN
#if defined JS_METHODJIT_TYPED_ARRAY
LookupStatus
GetElementIC::attachTypedArray(VMFrame &f, JSObject *obj, const Value &v, jsid id, Value *vp)
GetElementIC::attachTypedArray(VMFrame &f, HandleObject obj, HandleValue v, HandleId id, Value *vp)
{
JSContext *cx = f.cx;
@ -2455,16 +2448,18 @@ GetElementIC::attachTypedArray(VMFrame &f, JSObject *obj, const Value &v, jsid i
#endif /* JS_METHODJIT_TYPED_ARRAY */
LookupStatus
GetElementIC::update(VMFrame &f, JSObject *obj, const Value &v, jsid id, Value *vp)
GetElementIC::update(VMFrame &f, HandleObject obj, HandleValue v, HandleId id, Value *vp)
{
/*
/*JSObject *obj, const Value &v, jsid id, Value *vp)
* Only treat this as a GETPROP for non-numeric string identifiers. The
* GETPROP IC assumes the id has already gone through filtering for string
* indexes in the emitter.
*/
uint32_t dummy;
if (v.isString() && JSID_IS_ATOM(id) && !JSID_TO_ATOM(id)->isIndex(&dummy))
return attachGetProp(f, obj, v, JSID_TO_ATOM(id)->asPropertyName(), vp);
if (v.isString() && JSID_IS_ATOM(id) && !JSID_TO_ATOM(id)->isIndex(&dummy)) {
RootedPropertyName name(f.cx, JSID_TO_ATOM(id)->asPropertyName());
return attachGetProp(f, obj, v, name, vp);
}
#if defined JS_METHODJIT_TYPED_ARRAY
/*
@ -2496,7 +2491,8 @@ ic::GetElement(VMFrame &f, ic::GetElementIC *ic)
return;
}
Value idval = f.regs.sp[-1];
RootedValue idval_(cx, f.regs.sp[-1]);
Value &idval = idval_.get();
RecompilationMonitor monitor(cx);
@ -2526,7 +2522,7 @@ ic::GetElement(VMFrame &f, ic::GetElementIC *ic)
#ifdef DEBUG
f.regs.sp[-2] = MagicValue(JS_GENERIC_MAGIC);
#endif
LookupStatus status = ic->update(f, obj, idval, id, &f.regs.sp[-2]);
LookupStatus status = ic->update(f, obj, idval_, id, &f.regs.sp[-2]);
if (status != Lookup_Uncacheable) {
if (status == Lookup_Error)
THROW();

Просмотреть файл

@ -243,10 +243,10 @@ struct GetElementIC : public BasePolyIC {
}
void purge(Repatcher &repatcher);
LookupStatus update(VMFrame &f, JSObject *obj, const Value &v, jsid id, Value *vp);
LookupStatus attachGetProp(VMFrame &f, JSObject *obj, const Value &v, PropertyName *name,
LookupStatus update(VMFrame &f, HandleObject obj, HandleValue v, HandleId id, Value *vp);
LookupStatus attachGetProp(VMFrame &f, HandleObject obj, HandleValue v, HandlePropertyName name,
Value *vp);
LookupStatus attachTypedArray(VMFrame &f, JSObject *obj, const Value &v, jsid id, Value *vp);
LookupStatus attachTypedArray(VMFrame &f, HandleObject obj, HandleValue v, HandleId id, Value *vp);
LookupStatus disable(VMFrame &f, const char *reason);
LookupStatus error(JSContext *cx);
bool shouldUpdate(JSContext *cx);

Просмотреть файл

@ -123,7 +123,7 @@ stubs::SetElem(VMFrame &f)
Value &objval = regs.sp[-3];
Value &idval = regs.sp[-2];
Value rval = regs.sp[-1];
RootedValue rval(cx, regs.sp[-1]);
RootedId id(cx);
@ -155,7 +155,7 @@ stubs::SetElem(VMFrame &f)
}
}
} while (0);
if (!obj->setGeneric(cx, obj, id, &rval, strict))
if (!obj->setGeneric(cx, obj, id, rval.address(), strict))
THROW();
end_setelem:
/* :FIXME: Moving the assigned object into the lowest stack slot
@ -337,13 +337,13 @@ stubs::DefFun(VMFrame &f, JSFunction *fun_)
Rooted<JSObject*> parent(cx, &fp->varObj());
/* ES5 10.5 (NB: with subsequent errata). */
PropertyName *name = fun->atom->asPropertyName();
RootedPropertyName name(cx, fun->atom->asPropertyName());
RootedShape shape(cx);
RootedObject pobj(cx);
if (!parent->lookupProperty(cx, name, &pobj, &shape))
THROW();
Value rval = ObjectValue(*fun);
RootedValue rval(cx, ObjectValue(*fun));
do {
/* Steps 5d, 5f. */
@ -386,7 +386,7 @@ stubs::DefFun(VMFrame &f, JSFunction *fun_)
*/
/* Step 5f. */
if (!parent->setProperty(cx, parent, name, &rval, strict))
if (!parent->setProperty(cx, parent, name, rval.address(), strict))
THROW();
} while (false);
}
@ -465,8 +465,9 @@ StubEqualityOp(VMFrame &f)
JSContext *cx = f.cx;
FrameRegs &regs = f.regs;
Value rval = regs.sp[-1];
Value lval = regs.sp[-2];
RootedValue rval_(cx, regs.sp[-1]);
RootedValue lval_(cx, regs.sp[-2]);
Value &rval = rval_.get(), &lval = lval_.get();
bool cond;
@ -575,8 +576,9 @@ stubs::Add(VMFrame &f)
{
JSContext *cx = f.cx;
FrameRegs &regs = f.regs;
Value rval = regs.sp[-1];
Value lval = regs.sp[-2];
RootedValue rval_(cx, regs.sp[-1]);
RootedValue lval_(cx, regs.sp[-2]);
Value &rval = rval_.get(), &lval = lval_.get();
/* The string + string case is easily the hottest; try it first. */
bool lIsString = lval.isString();
@ -861,11 +863,11 @@ stubs::Neg(VMFrame &f)
void JS_FASTCALL
stubs::NewInitArray(VMFrame &f, uint32_t count)
{
Rooted<TypeObject*> type(f.cx, (TypeObject *) f.scratch);
RootedObject obj(f.cx, NewDenseAllocatedArray(f.cx, count));
if (!obj)
THROW();
TypeObject *type = (TypeObject *) f.scratch;
if (type) {
obj->setType(type);
} else {
@ -881,7 +883,7 @@ void JS_FASTCALL
stubs::NewInitObject(VMFrame &f, JSObject *baseobj)
{
JSContext *cx = f.cx;
TypeObject *type = (TypeObject *) f.scratch;
Rooted<TypeObject*> type(f.cx, (TypeObject *) f.scratch);
RootedObject obj(cx);
if (baseobj) {
@ -919,7 +921,7 @@ stubs::InitElem(VMFrame &f, uint32_t last)
/* Find the object being initialized at top of stack. */
const Value &lref = regs.sp[-3];
JS_ASSERT(lref.isObject());
JSObject *obj = &lref.toObject();
RootedObject obj(cx, &lref.toObject());
/* Fetch id now that we have obj. */
RootedId id(cx);
@ -978,8 +980,8 @@ stubs::GetProp(VMFrame &f, PropertyName *name)
JSContext *cx = f.cx;
FrameRegs &regs = f.regs;
Value rval;
if (!GetPropertyOperation(cx, f.script(), f.pc(), f.regs.sp[-1], &rval))
RootedValue rval(cx);
if (!GetPropertyOperation(cx, f.script(), f.pc(), f.regs.sp[-1], rval.address()))
THROW();
regs.sp[-1] = rval;
@ -1022,8 +1024,7 @@ InitPropOrMethod(VMFrame &f, PropertyName *name, JSOp op)
/* Load the property's initial value into rval. */
JS_ASSERT(regs.stackDepth() >= 2);
Value rval;
rval = regs.sp[-1];
RootedValue rval(f.cx, regs.sp[-1]);
/* Load the object being initialized into lval/obj. */
RootedObject obj(cx, &regs.sp[-2].toObject());
@ -1033,7 +1034,7 @@ InitPropOrMethod(VMFrame &f, PropertyName *name, JSOp op)
RootedId id(cx, NameToId(name));
if (JS_UNLIKELY(name == cx->runtime->atomState.protoAtom)
? !baseops::SetPropertyHelper(cx, obj, obj, id, 0, &rval, false)
? !baseops::SetPropertyHelper(cx, obj, obj, id, 0, rval.address(), false)
: !DefineNativeProperty(cx, obj, id, rval, NULL, NULL,
JSPROP_ENUMERATE, 0, 0, 0)) {
THROW();
@ -1434,7 +1435,7 @@ stubs::In(VMFrame &f)
THROWV(JS_FALSE);
}
JSObject *obj = &rref.toObject();
RootedObject obj(cx, &rref.toObject());
RootedId id(cx);
if (!FetchElementId(f.cx, obj, f.regs.sp[-2], id.address(), &f.regs.sp[-2]))
THROWV(JS_FALSE);

Просмотреть файл

@ -1472,7 +1472,7 @@ SetThrowHook(JSContext *cx, unsigned argc, jsval *vp)
static JSBool
LineToPC(JSContext *cx, unsigned argc, jsval *vp)
{
JSScript *script;
RootedScript script(cx);
int32_t lineArg = 0;
uint32_t lineno;
jsbytecode *pc;

Просмотреть файл

@ -4040,10 +4040,10 @@ DebuggerObject_isSealedHelper(JSContext *cx, unsigned argc, Value *vp, SealHelpe
ErrorCopier ec(ac, dbg->toJSObject());
bool r;
if (op == Seal) {
if (!obj->isSealed(cx, &r))
if (!JSObject::isSealed(cx, obj, &r))
return false;
} else if (op == Freeze) {
if (!obj->isFrozen(cx, &r))
if (!JSObject::isFrozen(cx, obj, &r))
return false;
} else {
r = obj->isExtensible();