Bug 817091 - Merge Unrooted<T> and Return<T>; r=billm

After Bug 811168, Unrooted<T> and Return<T> perform the same assertions and
allow the same implicit casts. Given this and the performance impact of keeping
Return<T> as a struct, it would be better to just merge these two classes.

--HG--
extra : rebase_source : 173ab623c21b3da9b693b56a33f72aa8efef7b87
This commit is contained in:
Terrence Cole 2012-12-04 11:10:53 -08:00
parent 64bc10205a
commit 7a3ea75982
46 changed files with 189 additions and 409 deletions

View File

@ -612,7 +612,8 @@ class ReadBarriered
public:
ReadBarriered() : value(NULL) {}
ReadBarriered(T *value) : value(value) {}
ReadBarriered(Unrooted<T*> unrooted) : value(unrooted) {}
ReadBarriered(const Unrooted<T*> &unrooted) : value(unrooted) {}
ReadBarriered(const Rooted<T*> &rooted) : value(rooted) {}
T *get() const {
if (!value)

View File

@ -76,11 +76,6 @@
* updating the value of the referenced Rooted<T>. A MutableHandle<T> can be
* created from a Rooted<T> by using |Rooted<T>::operator&()|.
*
* - Return<T> is the type of a value returned from a function. Return<T> is
* opaque and cannot be accessed unless correctly rooted. It is invalid to
* create a named Return<T>, so the return value must be assigned to
* Rooted<T> immediately, or discarded and not referenced again.
*
* In some cases the small performance overhead of exact rooting is too much.
* In these cases, try the following:
*
@ -117,6 +112,24 @@
* There also exists a set of RawT typedefs for modules without rooting
* concerns, such as the GC. Do not use these as they provide no rooting
* protection whatsoever.
*
* The following diagram explains the list of supported, implicit type
* conversions between classes of this family:
*
* RawT ----> UnrootedT
* | ^
* | |
* | v
* +--------> Rooted<T> <---> Handle<T>
* ^ ^
* | |
* | |
* +---> MutableHandle<T>
* (via &)
*
* Currently all of these types implicit conversion to RawT. These are present
* only for the purpose of bootstrapping exact rooting and will be removed in
* the future (Bug 817164).
*/
namespace js {
@ -310,6 +323,10 @@ typedef MutableHandle<JSString*> MutableHandleString;
typedef MutableHandle<jsid> MutableHandleId;
typedef MutableHandle<Value> MutableHandleValue;
} /* namespace JS */
namespace js {
/*
* Raw pointer used as documentation that a parameter does not need to be
* rooted.
@ -321,10 +338,6 @@ typedef JSString * RawString;
typedef jsid RawId;
typedef Value RawValue;
} /* namespace JS */
namespace js {
/*
* InternalHandle is a handle to an internal pointer into a gcthing. Use
* InternalHandle when you have a pointer to a direct field of a gcthing, or
@ -383,172 +396,11 @@ class InternalHandle<T*>
{}
};
/*
* Return<T> wraps GC things that are returned from accessor methods. The
* wrapper helps to ensure correct rooting of the returned pointer and safe
* access while unrooted.
*
* Example usage in a method declaration:
*
* class Foo {
* HeapPtrScript script_;
* ...
* public:
* Return<JSScript*> script() { return script_; }
* };
*
* Example usage of method (1):
*
* Foo foo(...);
* RootedScript script(cx, foo->script());
*
* Example usage of method (2):
*
* Foo foo(...);
* foo->script()->needsArgsObj();
*
* The purpose of this class is to assert eagerly on incorrect use of GC thing
* pointers. For example:
*
* RootedShape shape(cx, ...);
* shape->parent.init(js_NewGCThing<Shape*>(cx, ...));
*
* In this expression, C++ is allowed to order these calls as follows:
*
* Call Effect
* ---- ------
* 1) RootedShape::operator-> Stores shape::ptr_ to stack.
* 2) js_NewGCThing<Shape*> Triggers GC and compaction of shapes. This
* moves shape::ptr_ to a new location.
* 3) HeapPtrObject::init This call takes the relocated shape::ptr_
* as |this|, crashing or, worse, corrupting
* the program's state on the first access
* to a member variable.
*
* If Shape::parent were an accessor function returning a Return<Shape*>, this
* could not happen: Return ensures either immediate rooting or no GC within
* the same expression.
*/
template <typename T>
class Return
{
typedef void (Return<T>::* ConvertibleToBool)();
void nonNull() {}
public:
template <typename S>
inline Return(const Unrooted<S> &unrooted,
typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy = 0);
template <typename S>
Return(const S &ptr,
typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy = 0)
: ptr_(ptr)
{
EnterAssertNoGCScope();
}
Return(NullPtr) : ptr_(NULL) {
EnterAssertNoGCScope();
}
Return(const Return &ret) : ptr_(ret.ptr_) {
EnterAssertNoGCScope();
}
~Return() {
LeaveAssertNoGCScope();
}
#ifndef DEBUG
/*
* In DEBUG builds, |Unrooted<T>| has a constructor that accepts
* |Return<T>|, which allows direct assignment into a |Unrooted<T>|. This
* is safe because |Unrooted<T>| implies a NoGCScope. In optimized builds,
* however, |Unrooted<T>| does not exist, only the UnrootedT typedef to a
* raw T. Thus, this unsafe unpack is protected by a different mechanism
* in debug builds.
*/
operator const T &() { return ptr_; }
#endif /* DEBUG */
/*
* |get(AutoAssertNoGC &)| is the safest way to access a Return<T> without
* rooting it first: it is impossible to call this method without an
* AutoAssertNoGC in scope, so the compiler will automatically catch any
* incorrect usage.
*
* Example:
* AutoAssertNoGC nogc;
* UnrootedScript script = fun->script().get(nogc);
*/
const T &get(AutoAssertNoGC &) const {
return ptr_;
}
/*
* |operator->|'s result cannot be stored in a local variable, so it is
* safe to use in a CanGC context iff no GC can occur anywhere within the
* same expression (generally from one |;| to the next). |operator->| is
* protected at runtime by the fact that |Return<T>| is an AutoAssertNoGC.
* Still, care must be taken to avoid having the |Return<T>| on the stack
* during a GC, which would result in a runtime assertion.
*
* INCORRECT:
* fun->script()->bindings = myBindings->clone(cx, ...);
*
* The compiler is allowed to reorder |fun->script()::operator->()| above
* the call to |clone(cx, ...)|. In this case, the raw js::Script* C++
* stores on the stack may be corrupted by a GC under |clone|. The
* subsequent dereference of this pointer to get |bindings| will result in
* an invalid access. |Return<T>| ensures that such usage asserts in DEBUG
* builds when it encounters this situation. Without this assertion, it is
* possible for such access to corrupt program state instead of crashing
* immediately.
*
* CORRECT:
* RootedScript clone(cx, myBindings->clone(cx, ...));
* fun->script()->bindings = clone;
*/
const T &operator->() const {
return ptr_;
}
/*
* |unsafeGet()| is unsafe for most uses. Usage of this method should be
* restricted to GC internals, assertions, or include a comment explaining
* how its usage is protected.
*/
const T &unsafeGet() const {
return ptr_;
}
/*
* |operator==| is safe to use in any context. It is present to allow:
* JS_ASSERT(myScript == fun->script().unsafeGet());
*
* To be rewritten as:
* JS_ASSERT(fun->script() == myScript);
*
* Note: the new order tells C++ to use |Return<JSScript*>::operator=|
* instead of direct pointer comparison.
*/
operator ConvertibleToBool() const { return ptr_ ? &Return<T>::nonNull : 0; }
bool operator==(const T &other) { return ptr_ == other; }
bool operator!=(const T &other) { return ptr_ != other; }
bool operator==(const Return<T> &other) { return ptr_ == other.ptr_; }
bool operator==(const JS::Handle<T> &other) { return ptr_ == other.get(); }
inline bool operator==(const Rooted<T> &other);
private:
const T ptr_;
};
#ifdef DEBUG
/*
* |Unrooted<T>| acts as an AutoAssertNoGC after it is initialized. It otherwise
* acts like as a normal pointer of type T.
*/
#ifdef DEBUG
template <typename T>
class Unrooted
{
@ -565,40 +417,18 @@ class Unrooted
* type, this is safe because Unrooted<T> acts as an AutoAssertNoGC scope.
*/
template <typename S>
inline Unrooted(Rooted<S> &root,
typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy = 0);
inline Unrooted(const Rooted<S> &root,
typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy = 0);
template <typename S>
Unrooted(JS::Handle<S> &root,
typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy = 0)
Unrooted(const JS::Handle<S> &root,
typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy = 0)
: ptr_(root.get())
{
JS_ASSERT(ptr_ != UninitializedTag());
EnterAssertNoGCScope();
}
/*
* |Unrooted<T>| can accept |Return<T>| without any casts. This is safe
* because |Unrooted<T>| acts as an |AutoAssertNoGC| scope. This is to
* enable usage such as:
*
* Return<Foo*>
* CreateFoo(JSContext *cx, ...)
* {
* Unrooted<Foo*> foo = js_NewFoo(cx);
* foo.initialize(...);
* return foo;
* }
*/
template <typename S>
Unrooted(const Return<S> &ret,
typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy = 0)
: ptr_(ret.unsafeGet())
{
JS_ASSERT(ptr_ != UninitializedTag());
EnterAssertNoGCScope();
}
/*
* |Unrooted<T>| can initialize by copying from a convertible type
* |Unrooted<S>|. This enables usage such as:
@ -625,6 +455,10 @@ class Unrooted
EnterAssertNoGCScope();
}
Unrooted(const JS::NullPtr &) : ptr_(NULL) {
EnterAssertNoGCScope();
}
~Unrooted() {
if (ptr_ != UninitializedTag())
LeaveAssertNoGCScope();
@ -636,16 +470,6 @@ class Unrooted
ptr_ = UninitializedTag();
}
/* See notes for Unrooted::Unrooted(const Return<S> &) */
template <typename S>
Unrooted &operator=(const Return<S> &other) {
JS_ASSERT(other.unsafeGet() != UninitializedTag());
if (ptr_ == UninitializedTag())
EnterAssertNoGCScope();
ptr_ = other.unsafeGet();
return *this;
}
/* See notes for Unrooted::Unrooted(const T &) */
Unrooted &operator=(T other) {
JS_ASSERT(other != UninitializedTag());
@ -682,11 +506,19 @@ class Unrooted
* This macro simplifies declaration of the required matching raw-pointer for
* optimized builds and Unrooted<T> template for debug builds.
*/
# define ForwardDeclare(type) \
class type; \
typedef Unrooted<type*> Unrooted##type; \
# define ForwardDeclare(type) \
class type; \
typedef Unrooted<type*> Unrooted##type; \
typedef type * Raw##type
# define ForwardDeclareJS(type) \
struct JS##type; \
namespace js { \
typedef Unrooted<JS##type*> Unrooted##type; \
typedef JS##type * Raw##type; \
} \
struct JS##type
template <typename T>
T DropUnrooted(Unrooted<T> &unrooted)
{
@ -709,16 +541,19 @@ inline RawId DropUnrooted(RawId &id) { return id; }
#else /* NDEBUG */
/* In opt builds |UnrootedFoo| is a real |Foo*|. */
# define ForwardDeclare(type) \
class type; \
typedef type * Unrooted##type; \
# define ForwardDeclare(type) \
class type; \
typedef type * Unrooted##type; \
typedef type * Raw##type
/*
* Note: we still define Unrooted<T> in optimized builds so that we do not need
* #ifdef DEBUG around every debug specialization. We just ensure that the
* class is never initialized by deleting its constructors.
*/
# define ForwardDeclareJS(type) \
struct JS##type; \
namespace js { \
typedef JS##type * Unrooted##type; \
typedef JS##type * Raw##type; \
} \
struct JS##type
template <typename T>
class Unrooted
{
@ -733,16 +568,6 @@ T DropUnrooted(T &unrooted) { return unrooted; }
#endif /* DEBUG */
template <typename T> template <typename S>
inline
Return<T>::Return(const Unrooted<S> &unrooted,
typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy)
/* Note: |static_cast| acquires raw.ptr_ in DEBUG builds. */
: ptr_(static_cast<S>(unrooted))
{
EnterAssertNoGCScope();
}
/*
* By default, pointers should use the inheritance hierarchy to find their
* ThingRootKind. Some pointer types are explicitly set in jspubtd.h so that
@ -855,19 +680,10 @@ class Rooted : public RootedBase<T>
init(pt);
}
template <typename S>
Rooted(JSContext *cx, const Return<S> &initial
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
: ptr(initial.unsafeGet())
{
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
init(cx);
}
template <typename S>
Rooted(JSContext *cx, const Unrooted<S> &initial
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
: ptr(initial.ptr_)
: ptr(static_cast<S>(initial))
#if defined(JSGC_ROOT_ANALYSIS)
, scanned(false)
#endif
@ -876,15 +692,6 @@ class Rooted : public RootedBase<T>
init(cx);
}
template <typename S>
Rooted(js::PerThreadData *pt, const Return<S> &initial
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
: ptr(initial.ptr_)
{
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
init(pt);
}
~Rooted() {
#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING)
JS_ASSERT(*stack == this);
@ -914,12 +721,6 @@ class Rooted : public RootedBase<T>
return ptr;
}
template <typename S>
T &operator=(const Return<S> &value) {
ptr = value.unsafeGet();
return ptr;
}
private:
void commonInit(Rooted<void*> **thingGCRooters) {
#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING)
@ -953,18 +754,11 @@ template <>
class Rooted<JSStableString *>;
#endif
template <typename T>
bool
Return<T>::operator==(const Rooted<T> &other)
{
return ptr_ == other.get();
}
#ifdef DEBUG
template <typename T> template <typename S>
inline
Unrooted<T>::Unrooted(Rooted<S> &root,
typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy)
Unrooted<T>::Unrooted(const Rooted<S> &root,
typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy)
: ptr_(root.get())
{
JS_ASSERT(ptr_ != UninitializedTag());

View File

@ -74,7 +74,7 @@ IonBailoutIterator::dump() const
}
}
static JSScript*
static UnrootedScript
GetBailedJSScript(JSContext *cx)
{
AutoAssertNoGC nogc;
@ -85,7 +85,7 @@ GetBailedJSScript(JSContext *cx)
switch (GetCalleeTokenTag(frame->calleeToken())) {
case CalleeToken_Function: {
JSFunction *fun = CalleeTokenToFunction(frame->calleeToken());
return fun->nonLazyScript().get(nogc);
return fun->nonLazyScript();
}
case CalleeToken_Script:
return CalleeTokenToScript(frame->calleeToken());
@ -178,8 +178,8 @@ StackFrame::initFromBailout(JSContext *cx, SnapshotIterator &iter)
regs.pc = GetNextPc(regs.pc);
IonSpew(IonSpew_Bailouts, " new PC is offset %u within script %p (line %d)",
pcOff, (void *)script().get(nogc), PCToLineNumber(script().get(nogc), regs.pc));
JS_ASSERT(exprStackSlots == js_ReconstructStackDepth(cx, script().get(nogc), regs.pc));
pcOff, (void *)script(), PCToLineNumber(script(), regs.pc));
JS_ASSERT(exprStackSlots == js_ReconstructStackDepth(cx, script(), regs.pc));
}
static StackFrame *
@ -324,7 +324,7 @@ ConvertFrames(JSContext *cx, IonActivation *activation, IonBailoutIterator &it)
// we flag it here manually that the entry has happened.
case Bailout_ArgumentCheck:
fp->unsetPushedSPSFrame();
Probes::enterScript(cx, fp->script().unsafeGet(), fp->script()->function(), fp);
Probes::enterScript(cx, fp->script(), fp->script()->function(), fp);
return BAILOUT_RETURN_ARGUMENT_CHECK;
}
@ -502,8 +502,9 @@ ion::ReflowTypeInfo(uint32_t bailoutResult)
uint32_t
ion::RecompileForInlining()
{
AutoAssertNoGC nogc;
JSContext *cx = GetIonContext()->cx;
RawScript script = cx->fp()->script().unsafeGet();
UnrootedScript script = cx->fp()->script();
IonSpew(IonSpew_Inlining, "Recompiling script to inline calls %s:%d", script->filename,
script->lineno);
@ -663,7 +664,7 @@ ion::ThunkToInterpreter(Value *vp)
IonSpew(IonSpew_Bailouts, "Performing inline OSR %s:%d",
cx->fp()->script()->filename,
PCToLineNumber(cx->fp()->script().unsafeGet(), cx->regs().pc));
PCToLineNumber(cx->fp()->script(), cx->regs().pc));
// We want to OSR again. We need to avoid the problem where frequent
// bailouts cause recursive nestings of Interpret and EnterIon. The

View File

@ -311,7 +311,7 @@ CodeGenerator::visitLambda(LLambda *lir)
JS_STATIC_ASSERT(offsetof(JSFunction, flags) == offsetof(JSFunction, nargs) + 2);
masm.store32(Imm32(u.word), Address(output, offsetof(JSFunction, nargs)));
masm.storePtr(ImmGCPtr(fun->nonLazyScript().unsafeGet()),
masm.storePtr(ImmGCPtr(fun->nonLazyScript()),
Address(output, JSFunction::offsetOfNativeOrScript()));
masm.storePtr(scopeChain, Address(output, JSFunction::offsetOfEnvironment()));
masm.storePtr(ImmGCPtr(fun->displayAtom()), Address(output, JSFunction::offsetOfAtom()));

View File

@ -1170,7 +1170,7 @@ SequentialCompileContext::compile(IonBuilder *builder, MIRGraph *graph,
JS_ASSERT(!builder->script()->ion);
JSContext *cx = GetIonContext()->cx;
IonSpewNewFunction(graph, builder->script().unsafeGet());
IonSpewNewFunction(graph, builder->script());
if (!builder->build()) {
IonSpew(IonSpew_Abort, "Builder failed to build.");
@ -1510,7 +1510,7 @@ EnterIon(JSContext *cx, StackFrame *fp, void *jitcode)
}
calleeToken = CalleeToToken(&fp->callee());
} else {
calleeToken = CalleeToToken(fp->script().unsafeGet());
calleeToken = CalleeToToken(fp->script());
}
// Caller must construct |this| before invoking the Ion function.
@ -1817,6 +1817,7 @@ void
ion::Invalidate(types::TypeCompartment &types, FreeOp *fop,
const Vector<types::RecompileInfo> &invalid, bool resetUses)
{
AutoAssertNoGC nogc;
IonSpew(IonSpew_Invalidate, "Start invalidation.");
AutoFlushCache afc ("Invalidate");

View File

@ -152,7 +152,7 @@ IonBuilder::getSingleCallTarget(uint32_t argc, jsbytecode *pc)
{
AutoAssertNoGC nogc;
types::StackTypeSet *calleeTypes = oracle->getCallTarget(script().get(nogc), argc, pc);
types::StackTypeSet *calleeTypes = oracle->getCallTarget(script(), argc, pc);
if (!calleeTypes)
return NULL;
@ -3849,7 +3849,7 @@ IonBuilder::createThisScriptedSingleton(HandleFunction target, HandleObject prot
types::TypeObject *type = proto->getNewType(cx, target);
if (!type)
return NULL;
if (!types::TypeScript::ThisTypes(target->nonLazyScript().unsafeGet())->hasType(types::Type::ObjectType(type)))
if (!types::TypeScript::ThisTypes(target->nonLazyScript())->hasType(types::Type::ObjectType(type)))
return NULL;
RootedObject templateObject(cx, js_CreateThisForFunctionWithProto(cx, target, proto));

View File

@ -479,7 +479,7 @@ class IonBuilder : public MIRGenerator
void clearForBackEnd();
Return<JSScript*> script() const { return script_; }
UnrootedScript script() const { return script_.get(); }
CodeGenerator *backgroundCodegen() const { return backgroundCodegen_; }
void setBackgroundCodegen(CodeGenerator *codegen) { backgroundCodegen_ = codegen; }

View File

@ -1626,7 +1626,7 @@ GenerateScopeChainGuard(MacroAssembler &masm, JSObject *scopeObj,
CallObject *callObj = &scopeObj->asCall();
if (!callObj->isForEval()) {
RawFunction fun = &callObj->callee();
RawScript script = fun->nonLazyScript().get(nogc);
UnrootedScript script = fun->nonLazyScript();
if (!script->funHasExtensibleScope)
return;
}

View File

@ -81,7 +81,7 @@ IonFrameIterator::frameSize() const
}
// Returns the JSScript associated with the topmost Ion frame.
inline JSScript *
inline UnrootedScript
GetTopIonJSScript(JSContext *cx, const SafepointIndex **safepointIndexOut, void **returnAddrOut)
{
AutoAssertNoGC nogc;

View File

@ -926,7 +926,7 @@ InlineFrameIterator::findNextFrame()
si_.nextFrame();
callee_ = funval.toObject().toFunction();
script_ = callee_->nonLazyScript().get(nogc);
script_ = callee_->nonLazyScript();
pc_ = script_->code + si_.pcOffset();
}

View File

@ -42,7 +42,7 @@ CalleeToToken(JSFunction *fun)
return CalleeToken(uintptr_t(fun) | uintptr_t(CalleeToken_Function));
}
static inline CalleeToken
CalleeToToken(JSScript *script)
CalleeToToken(RawScript script)
{
return CalleeToken(uintptr_t(script) | uintptr_t(CalleeToken_Script));
}
@ -57,14 +57,14 @@ CalleeTokenToFunction(CalleeToken token)
JS_ASSERT(CalleeTokenIsFunction(token));
return (JSFunction *)token;
}
static inline JSScript *
static inline UnrootedScript
CalleeTokenToScript(CalleeToken token)
{
JS_ASSERT(GetCalleeTokenTag(token) == CalleeToken_Script);
return (JSScript *)(uintptr_t(token) & ~uintptr_t(0x3));
return (RawScript)(uintptr_t(token) & ~uintptr_t(0x3));
}
static inline JSScript *
static inline UnrootedScript
ScriptFromCalleeToken(CalleeToken token)
{
AutoAssertNoGC nogc;
@ -72,10 +72,10 @@ ScriptFromCalleeToken(CalleeToken token)
case CalleeToken_Script:
return CalleeTokenToScript(token);
case CalleeToken_Function:
return CalleeTokenToFunction(token)->nonLazyScript().get(nogc);
return CalleeTokenToFunction(token)->nonLazyScript();
}
JS_NOT_REACHED("invalid callee token tag");
return NULL;
return UnrootedScript(NULL);
}
// In between every two frames lies a small header describing both frames. This
@ -269,7 +269,7 @@ MakeFrameDescriptor(uint32_t frameSize, FrameType type)
namespace js {
namespace ion {
JSScript *
UnrootedScript
GetTopIonJSScript(JSContext *cx,
const SafepointIndex **safepointIndexOut = NULL,
void **returnAddrOut = NULL);

View File

@ -53,7 +53,7 @@ InvokeFunction(JSContext *cx, JSFunction *fun, uint32_t argc, Value *argv, Value
// In order to prevent massive bouncing between Ion and JM, see if we keep
// hitting functions that are uncompilable.
if (fun->isInterpreted()) {
if (fun->isInterpretedLazy() && !fun->getOrCreateScript(cx).unsafeGet())
if (fun->isInterpretedLazy() && !fun->getOrCreateScript(cx))
return false;
if (!fun->nonLazyScript()->canIonCompile()) {
JSScript *script = GetTopIonJSScript(cx);
@ -103,7 +103,7 @@ InvokeConstructor(JSContext *cx, JSObject *obj, uint32_t argc, Value *argv, Valu
if (obj->isFunction()) {
if (obj->toFunction()->isInterpretedLazy() &&
!obj->toFunction()->getOrCreateScript(cx).unsafeGet())
!obj->toFunction()->getOrCreateScript(cx))
{
return false;
}

View File

@ -7096,9 +7096,9 @@ JS_DescribeScriptedCaller(JSContext *cx, JSScript **script, unsigned *lineno)
return JS_FALSE;
if (script)
*script = i.script().get(nogc);
*script = i.script();
if (lineno)
*lineno = js::PCToLineNumber(i.script().get(nogc), i.pc());
*lineno = js::PCToLineNumber(i.script(), i.pc());
return JS_TRUE;
}

View File

@ -1621,12 +1621,12 @@ typedef JS::MutableHandle<JSString*> JSMutableHandleString;
typedef JS::MutableHandle<JS::Value> JSMutableHandleValue;
typedef JS::MutableHandle<jsid> JSMutableHandleId;
typedef JS::RawObject JSRawObject;
typedef JS::RawFunction JSRawFunction;
typedef JS::RawScript JSRawScript;
typedef JS::RawString JSRawString;
typedef JS::RawId JSRawId;
typedef JS::RawValue JSRawValue;
typedef js::RawObject JSRawObject;
typedef js::RawFunction JSRawFunction;
typedef js::RawScript JSRawScript;
typedef js::RawString JSRawString;
typedef js::RawId JSRawId;
typedef js::RawValue JSRawValue;
/* JSClass operation signatures. */

View File

@ -663,7 +663,7 @@ PopulateReportBlame(JSContext *cx, JSErrorReport *report)
return;
report->filename = iter.script()->filename;
report->lineno = PCToLineNumber(iter.script().get(nogc), iter.pc(), &report->column);
report->lineno = PCToLineNumber(iter.script(), iter.pc(), &report->column);
report->originPrincipals = iter.script()->originPrincipals;
}

View File

@ -448,8 +448,7 @@ JS_ReleaseFunctionLocalNameArray(JSContext *cx, void *mark)
JS_PUBLIC_API(JSScript *)
JS_GetFunctionScript(JSContext *cx, JSFunction *fun)
{
AutoAssertNoGC nogc;
return fun->maybeNonLazyScript().get(nogc);
return fun->maybeNonLazyScript();
}
JS_PUBLIC_API(JSNative)
@ -497,8 +496,7 @@ JS_BrokenFrameIterator(JSContext *cx, JSStackFrame **iteratorp)
JS_PUBLIC_API(JSScript *)
JS_GetFrameScript(JSContext *cx, JSStackFrame *fpArg)
{
AutoAssertNoGC nogc;
return Valueify(fpArg)->script().get(nogc);
return Valueify(fpArg)->script();
}
JS_PUBLIC_API(jsbytecode *)
@ -543,7 +541,7 @@ JS_SetTopFrameAnnotation(JSContext *cx, void *annotation)
// because we will never EnterIon on a frame with an annotation.
fp->setAnnotation(annotation);
RawScript script = fp->script().get(nogc);
UnrootedScript script = fp->script();
ReleaseAllJITCode(cx->runtime->defaultFreeOp());
@ -1013,7 +1011,7 @@ JS_GetFunctionTotalSize(JSContext *cx, JSFunction *fun)
size_t nbytes = sizeof *fun;
nbytes += JS_GetObjectTotalSize(cx, fun);
if (fun->isInterpreted())
nbytes += JS_GetScriptTotalSize(cx, fun->nonLazyScript().get(nogc));
nbytes += JS_GetScriptTotalSize(cx, fun->nonLazyScript());
if (fun->displayAtom())
nbytes += GetAtomTotalSize(cx, fun->displayAtom());
return nbytes;
@ -1205,8 +1203,8 @@ JS::DescribeStack(JSContext *cx, unsigned maxFrames)
for (ScriptFrameIter i(cx); !i.done(); ++i) {
FrameDescription desc;
desc.script = i.script().get(nogc);
desc.lineno = PCToLineNumber(i.script().get(nogc), i.pc());
desc.script = i.script();
desc.lineno = PCToLineNumber(i.script(), i.pc());
desc.fun = i.maybeCallee();
if (!frames.append(desc))
return NULL;

View File

@ -125,13 +125,11 @@ fun_getProperty(JSContext *cx, HandleObject obj_, HandleId id, MutableHandleValu
return false;
#ifdef JS_ION
AutoAssertNoGC nogc;
// If this script hasn't been compiled yet, make sure it will never
// be compiled. IonMonkey does not guarantee |f.arguments| can be
// fully recovered, so we try to mitigate observing this behavior by
// detecting its use early.
RawScript script = iter.script().get(nogc);
UnrootedScript script = iter.script();
if (!script->hasAnyIonScript())
ion::ForbidCompilation(cx, script);
#endif
@ -344,7 +342,7 @@ fun_resolve(JSContext *cx, HandleObject obj, HandleId id, unsigned flags,
PropertyOp getter;
StrictPropertyOp setter;
unsigned attrs = JSPROP_PERMANENT;
if (fun->isInterpretedLazy() && !fun->getOrCreateScript(cx).unsafeGet())
if (fun->isInterpretedLazy() && !fun->getOrCreateScript(cx))
return false;
if (fun->isInterpreted() ? fun->inStrictMode() : fun->isBoundFunction()) {
JSObject *throwTypeError = fun->global().getThrowTypeError();
@ -1112,7 +1110,7 @@ fun_isGenerator(JSContext *cx, unsigned argc, Value *vp)
bool result = false;
if (fun->hasScript()) {
RawScript script = fun->nonLazyScript().get(nogc);
UnrootedScript script = fun->nonLazyScript();
JS_ASSERT(script->length != 0);
result = script->isGenerator;
}
@ -1480,7 +1478,7 @@ js_CloneFunctionObject(JSContext *cx, HandleFunction fun, HandleObject parent,
clone->nargs = fun->nargs;
clone->flags = fun->flags & ~JSFunction::EXTENDED;
if (fun->isInterpreted()) {
clone->initScript(fun->nonLazyScript().unsafeGet());
clone->initScript(fun->nonLazyScript());
clone->initEnvironment(parent);
} else {
clone->initNative(fun->native(), fun->jitInfo());

View File

@ -13,11 +13,12 @@
#include "jspubtd.h"
#include "jsobj.h"
#include "jsatom.h"
#include "jsscript.h"
#include "jsstr.h"
#include "gc/Barrier.h"
ForwardDeclareJS(Script);
namespace js { class FunctionExtended; }
struct JSFunction : public JSObject
@ -178,13 +179,13 @@ struct JSFunction : public JSObject
static inline size_t offsetOfEnvironment() { return offsetof(JSFunction, u.i.env_); }
static inline size_t offsetOfAtom() { return offsetof(JSFunction, atom_); }
js::Return<JSScript*> getOrCreateScript(JSContext *cx) {
js::UnrootedScript getOrCreateScript(JSContext *cx) {
JS_ASSERT(isInterpreted());
if (isInterpretedLazy()) {
js::RootedFunction self(cx, this);
js::MaybeCheckStackRoots(cx);
if (!initializeLazyScript(cx))
return js::NullPtr();
return js::UnrootedScript(NULL);
}
JS_ASSERT(hasScript());
return JS::HandleScript::fromMarkedLocation(&u.i.script_);
@ -195,17 +196,17 @@ struct JSFunction : public JSObject
script.set(NULL);
return true;
}
script.set(getOrCreateScript(cx).unsafeGet());
script.set(getOrCreateScript(cx));
return hasScript();
}
js::Return<JSScript*> nonLazyScript() const {
js::UnrootedScript nonLazyScript() const {
JS_ASSERT(hasScript());
return JS::HandleScript::fromMarkedLocation(&u.i.script_);
}
js::Return<JSScript*> maybeNonLazyScript() const {
return isInterpreted() ? nonLazyScript() : JS::NullPtr();
js::UnrootedScript maybeNonLazyScript() const {
return isInterpreted() ? nonLazyScript() : js::UnrootedScript(NULL);
}
js::HeapPtrScript &mutableScript() {

View File

@ -601,7 +601,7 @@ js_NewGCShape(JSContext *cx)
return js::gc::NewGCThing<js::Shape>(cx, js::gc::FINALIZE_SHAPE, sizeof(js::Shape));
}
inline js::Return<js::BaseShape*>
inline js::UnrootedBaseShape
js_NewGCBaseShape(JSContext *cx)
{
return js::gc::NewGCThing<js::BaseShape>(cx, js::gc::FINALIZE_BASE_SHAPE, sizeof(js::BaseShape));

View File

@ -1423,10 +1423,10 @@ TypeConstraintPropagateThis::newType(JSContext *cx, TypeSet *source, Type type)
return;
}
if (!(callee->getOrCreateScript(cx).unsafeGet() && callee->nonLazyScript()->ensureHasTypes(cx)))
if (!(callee->getOrCreateScript(cx) && callee->nonLazyScript()->ensureHasTypes(cx)))
return;
TypeSet *thisTypes = TypeScript::ThisTypes(callee->nonLazyScript().unsafeGet());
TypeSet *thisTypes = TypeScript::ThisTypes(callee->nonLazyScript());
if (this->types)
this->types->addSubset(cx, thisTypes);
else
@ -5561,7 +5561,7 @@ JSScript::makeAnalysis(JSContext *cx)
/* static */ bool
JSFunction::setTypeForScriptedFunction(JSContext *cx, HandleFunction fun, bool singleton)
{
JS_ASSERT(fun->nonLazyScript().unsafeGet());
JS_ASSERT(fun->nonLazyScript());
JS_ASSERT(fun->nonLazyScript()->function() == fun);
if (!cx->typeInferenceEnabled())
@ -5717,7 +5717,7 @@ JSObject::makeLazyType(JSContext *cx)
RootedObject self(cx, this);
/* De-lazification of functions can GC, so we need to do it up here. */
if (self->isFunction() && self->toFunction()->isInterpretedLazy()) {
if (!self->toFunction()->getOrCreateScript(cx).unsafeGet())
if (!self->toFunction()->getOrCreateScript(cx))
return NULL;
}
JSProtoKey key = JSCLASS_CACHED_PROTO_KEY(getClass());

View File

@ -703,7 +703,7 @@ UseNewTypeForClone(JSFunction *fun)
* instance a singleton type and clone the underlying script.
*/
RawScript script = fun->nonLazyScript().get(nogc);
UnrootedScript script = fun->nonLazyScript();
if (script->length >= 50)
return false;
@ -905,7 +905,7 @@ TypeScript::GetPcScript(JSContext *cx, MutableHandleScript script, jsbytecode **
return;
}
#endif
script.set(cx->fp()->script().get(nogc));
script.set(cx->fp()->script());
*pc = cx->regs().pc;
}

View File

@ -2333,7 +2333,7 @@ BEGIN_CASE(JSOP_FUNCALL)
InitialFrameFlags initial = construct ? INITIAL_CONSTRUCT : INITIAL_NONE;
bool newType = cx->typeInferenceEnabled() && UseNewType(cx, script, regs.pc);
RawScript funScript = fun->getOrCreateScript(cx).unsafeGet();
RawScript funScript = fun->getOrCreateScript(cx);
if (!funScript)
goto error;
if (!cx->stack.pushInlineFrame(cx, regs, args, *fun, funScript, initial))

View File

@ -5240,7 +5240,7 @@ dumpValue(const Value &v)
fputs("<unnamed function", stderr);
}
if (fun->hasScript()) {
JSScript *script = fun->nonLazyScript().get(nogc);
UnrootedScript script = fun->nonLazyScript();
fprintf(stderr, " (%s:%u)",
script->filename ? script->filename : "", script->lineno);
}
@ -5506,9 +5506,9 @@ js_DumpBacktrace(JSContext *cx)
size_t depth = 0;
for (StackIter i(cx); !i.done(); ++i, ++depth) {
if (i.isScript()) {
const char *filename = JS_GetScriptFilename(cx, i.script().get(nogc));
unsigned line = JS_PCToLineNumber(cx, i.script().get(nogc), i.pc());
RawScript script = i.script().get(nogc);
const char *filename = JS_GetScriptFilename(cx, i.script());
unsigned line = JS_PCToLineNumber(cx, i.script(), i.pc());
RawScript script = i.script();
sprinter.printf("#%d %14p %s:%d (%p @ %d)\n",
depth, (i.isIon() ? 0 : i.interpFrame()), filename, line,
script, i.pc() - script->code);

View File

@ -815,7 +815,7 @@ inline bool JSObject::isWith() const { return hasClass(&js::WithClass); }
inline bool
JSObject::isDebugScope() const
{
extern bool js_IsDebugScopeSlow(JS::RawObject obj);
extern bool js_IsDebugScopeSlow(js::RawObject obj);
return getClass() == &js::ObjectProxyClass && js_IsDebugScopeSlow(const_cast<JSObject*>(this));
}

View File

@ -1192,7 +1192,7 @@ js_NewPrinter(JSContext *cx, const char *name, JSFunction *fun,
jp->localNames = NULL;
jp->decompiledOpcodes = NULL;
if (fun && fun->hasScript()) {
if (!SetPrinterLocalNames(cx, fun->nonLazyScript().unsafeGet(), jp)) {
if (!SetPrinterLocalNames(cx, fun->nonLazyScript(), jp)) {
js_DestroyPrinter(jp);
return NULL;
}
@ -1853,7 +1853,7 @@ GetArgOrVarAtom(JSPrinter *jp, unsigned slot)
{
LOCAL_ASSERT_RV(jp->fun, NULL);
LOCAL_ASSERT_RV(slot < jp->script->bindings.count(), NULL);
LOCAL_ASSERT_RV(jp->script == jp->fun->nonLazyScript().unsafeGet(), NULL);
LOCAL_ASSERT_RV(jp->script == jp->fun->nonLazyScript(), NULL);
JSAtom *name = (*jp->localNames)[slot].name();
#if !JS_HAS_DESTRUCTURING
LOCAL_ASSERT_RV(name, NULL);
@ -4812,10 +4812,10 @@ Decompile(SprintStack *ss, jsbytecode *pc, int nb)
*/
LifoAllocScope las(&cx->tempLifoAlloc());
outerLocalNames = jp->localNames;
if (!SetPrinterLocalNames(cx, fun->nonLazyScript().unsafeGet(), jp))
if (!SetPrinterLocalNames(cx, fun->nonLazyScript(), jp))
return NULL;
inner = fun->nonLazyScript().unsafeGet();
inner = fun->nonLazyScript();
if (!InitSprintStack(cx, &ss2, jp, StackDepth(inner))) {
js_delete(jp->localNames);
jp->localNames = outerLocalNames;
@ -6224,7 +6224,7 @@ FindStartPC(JSContext *cx, ScriptFrameIter &iter, int spindex, int skipStackHits
*valuepc = NULL;
PCStack pcstack;
if (!pcstack.init(cx, iter.script().unsafeGet(), current))
if (!pcstack.init(cx, iter.script(), current))
return false;
if (spindex == JSDVG_SEARCH_STACK) {

View File

@ -2133,7 +2133,7 @@ unsigned
js::CurrentLine(JSContext *cx)
{
AutoAssertNoGC nogc;
return PCToLineNumber(cx->fp()->script().get(nogc), cx->regs().pc);
return PCToLineNumber(cx->fp()->script(), cx->regs().pc);
}
void
@ -2150,9 +2150,9 @@ js::CurrentScriptFileLineOriginSlow(JSContext *cx, const char **file, unsigned *
return;
}
RawScript script = iter.script().get(nogc);
UnrootedScript script = iter.script();
*file = script->filename;
*linenop = PCToLineNumber(iter.script().get(nogc), iter.pc());
*linenop = PCToLineNumber(iter.script(), iter.pc());
*origin = script->originPrincipals;
}

View File

@ -48,7 +48,7 @@ CurrentScriptFileLineOrigin(JSContext *cx, const char **file, unsigned *linenop,
AutoAssertNoGC nogc;
JS_ASSERT(JSOp(*cx->regs().pc) == JSOP_EVAL);
JS_ASSERT(*(cx->regs().pc + JSOP_EVAL_LENGTH) == JSOP_LINENO);
RawScript script = cx->fp()->script().get(nogc);
UnrootedScript script = cx->fp()->script();
*file = script->filename;
*linenop = GET_UINT16(cx->regs().pc + JSOP_EVAL_LENGTH);
*origin = script->originPrincipals;

View File

@ -2369,7 +2369,7 @@ LambdaIsGetElem(JSObject &lambda)
if (!fun->hasScript())
return NULL;
RawScript script = fun->nonLazyScript().get(nogc);
UnrootedScript script = fun->nonLazyScript();
jsbytecode *pc = script->code;
/*

View File

@ -92,7 +92,7 @@ js::CancelOffThreadIonCompile(JSCompartment *compartment, JSScript *script)
/* Cancel any pending entries for which processing hasn't started. */
for (size_t i = 0; i < state.ionWorklist.length(); i++) {
ion::IonBuilder *builder = state.ionWorklist[i];
if (CompiledScriptMatches(compartment, script, builder->script().unsafeGet())) {
if (CompiledScriptMatches(compartment, script, builder->script())) {
FinishOffThreadIonCompile(builder);
state.ionWorklist[i--] = state.ionWorklist.back();
state.ionWorklist.popBack();
@ -103,7 +103,7 @@ js::CancelOffThreadIonCompile(JSCompartment *compartment, JSScript *script)
for (size_t i = 0; i < state.numThreads; i++) {
const WorkerThread &helper = state.threads[i];
while (helper.ionBuilder &&
CompiledScriptMatches(compartment, script, helper.ionBuilder->script().unsafeGet()))
CompiledScriptMatches(compartment, script, helper.ionBuilder->script()))
{
helper.ionBuilder->cancel();
state.wait(WorkerThreadState::MAIN);
@ -115,7 +115,7 @@ js::CancelOffThreadIonCompile(JSCompartment *compartment, JSScript *script)
/* Cancel code generation for any completed entries. */
for (size_t i = 0; i < compilations.length(); i++) {
ion::IonBuilder *builder = compilations[i];
if (CompiledScriptMatches(compartment, script, builder->script().unsafeGet())) {
if (CompiledScriptMatches(compartment, script, builder->script())) {
ion::FinishOffThreadBuilder(builder);
compilations[i--] = compilations.back();
compilations.popBack();
@ -316,7 +316,7 @@ WorkerThread::threadLoop()
ionBuilder = state.ionWorklist.popCopy();
DebugOnly<ion::ExecutionMode> executionMode = ionBuilder->info().executionMode();
JS_ASSERT(GetIonScript(ionBuilder->script().unsafeGet(), executionMode) == ION_COMPILING_SCRIPT);
JS_ASSERT(GetIonScript(ionBuilder->script(), executionMode) == ION_COMPILING_SCRIPT);
state.unlock();

View File

@ -148,7 +148,7 @@ class Assembler : public ValueAssembler
AutoAssertNoGC nogc;
startLabel = label();
if (vmframe)
sps->setPushed(vmframe->script().get(nogc));
sps->setPushed(vmframe->script());
}
Assembler(MJITInstrumentation *sps, jsbytecode **pc)

View File

@ -138,7 +138,7 @@ class LinkerHelper : public JSC::LinkBuffer
AutoAssertNoGC nogc;
masm.finalize(*this);
JSC::CodeLocationLabel label = finalizeCodeAddendum();
Probes::registerICCode(f.cx, f.chunk(), f.script().get(nogc), f.pc(),
Probes::registerICCode(f.cx, f.chunk(), f.script(), f.pc(),
label.executableAddress(), masm.size());
return label;
}

View File

@ -299,7 +299,7 @@ UncachedInlineCall(VMFrame &f, InitialFrameFlags initial,
return false;
/* Try to compile if not already compiled. */
if (ShouldJaegerCompileCallee(cx, f.script().unsafeGet(), newscript, f.jit())) {
if (ShouldJaegerCompileCallee(cx, f.script(), newscript, f.jit())) {
CompileStatus status = CanMethodJIT(cx, newscript, newscript->code, construct,
CompileRequest_JIT, f.fp());
if (status == Compile_Error) {
@ -663,7 +663,7 @@ void JS_FASTCALL
stubs::ScriptDebugPrologue(VMFrame &f)
{
AssertCanGC();
Probes::enterScript(f.cx, f.script().unsafeGet(), f.script()->function(), f.fp());
Probes::enterScript(f.cx, f.script(), f.script()->function(), f.fp());
JSTrapStatus status = js::ScriptDebugPrologue(f.cx, f.fp());
switch (status) {
case JSTRAP_CONTINUE:
@ -690,14 +690,14 @@ void JS_FASTCALL
stubs::ScriptProbeOnlyPrologue(VMFrame &f)
{
AutoAssertNoGC nogc;
Probes::enterScript(f.cx, f.script().get(nogc), f.script()->function(), f.fp());
Probes::enterScript(f.cx, f.script(), f.script()->function(), f.fp());
}
void JS_FASTCALL
stubs::ScriptProbeOnlyEpilogue(VMFrame &f)
{
AutoAssertNoGC nogc;
Probes::exitScript(f.cx, f.script().get(nogc), f.script()->function(), f.fp());
Probes::exitScript(f.cx, f.script(), f.script()->function(), f.fp());
}
void JS_FASTCALL
@ -708,13 +708,13 @@ stubs::CrossChunkShim(VMFrame &f, void *edge_)
mjit::ExpandInlineFrames(f.cx->compartment);
RawScript script = f.script().unsafeGet();
UnrootedScript script = f.script();
JS_ASSERT(edge->target < script->length);
JS_ASSERT(script->code + edge->target == f.pc());
CompileStatus status = CanMethodJIT(f.cx, script, f.pc(), f.fp()->isConstructing(),
CompileStatus status = CanMethodJIT(f.cx, DropUnrooted(script), f.pc(),
f.fp()->isConstructing(),
CompileRequest_Interpreter, f.fp());
script = NULL;
if (status == Compile_Error)
THROW();
@ -870,7 +870,7 @@ js_InternalInterpret(void *returnData, void *returnType, void *returnReg, js::VM
}
case REJOIN_THIS_CREATED: {
Probes::enterScript(f.cx, f.script().unsafeGet(), f.script()->function(), fp);
Probes::enterScript(f.cx, f.script(), f.script()->function(), fp);
if (script->debugMode) {
JSTrapStatus status = js::ScriptDebugPrologue(f.cx, f.fp());
@ -930,7 +930,7 @@ js_InternalInterpret(void *returnData, void *returnType, void *returnReg, js::VM
}
/* FALLTHROUGH */
case REJOIN_EVAL_PROLOGUE:
Probes::enterScript(cx, f.script().unsafeGet(), f.script()->function(), fp);
Probes::enterScript(cx, f.script(), f.script()->function(), fp);
if (cx->compartment->debugMode()) {
JSTrapStatus status = ScriptDebugPrologue(cx, fp);
switch (status) {

View File

@ -218,7 +218,7 @@ struct VMFrame
inline unsigned chunkIndex();
/* Get the inner script/PC in case of inlining. */
inline Return<JSScript*> script();
inline UnrootedScript script();
inline jsbytecode *pc();
#if defined(JS_CPU_SPARC)
@ -1064,7 +1064,7 @@ VMFrame::chunkIndex()
return jit()->chunkIndex(regs.pc);
}
inline Return<JSScript*>
inline UnrootedScript
VMFrame::script()
{
AutoAssertNoGC nogc;

View File

@ -884,7 +884,7 @@ class CallCompiler : public BaseCompiler
masm.storePtr(ImmPtr((void *) ic.frameSize.rejoinState(f.pc(), false)),
FrameAddress(offsetof(VMFrame, stubRejoin)));
masm.bumpStubCount(f.script().get(nogc), f.pc(), Registers::tempCallReg());
masm.bumpStubCount(f.script(), f.pc(), Registers::tempCallReg());
/* Try and compile. On success we get back the nmap pointer. */
void *compilePtr = JS_FUNC_TO_DATA_PTR(void *, stubs::CompileFunction);
@ -1001,7 +1001,7 @@ class CallCompiler : public BaseCompiler
/* Guard that it's the same script. */
Address scriptAddr(ic.funObjReg, JSFunction::offsetOfNativeOrScript());
Jump funGuard = masm.branchPtr(Assembler::NotEqual, scriptAddr,
ImmPtr(obj->toFunction()->nonLazyScript().get(nogc)));
ImmPtr(obj->toFunction()->nonLazyScript()));
Jump done = masm.jump();
LinkerHelper linker(masm, JSC::JAEGER_CODE);
@ -1259,9 +1259,8 @@ class CallCompiler : public BaseCompiler
return NULL;
}
AutoAssertNoGC nogc;
JS_ASSERT(fun);
JSScript *script = fun->nonLazyScript().get(nogc);
UnrootedScript script = fun->nonLazyScript();
JS_ASSERT(script);
uint32_t flags = callingNew ? StackFrame::CONSTRUCTING : 0;
@ -1433,7 +1432,7 @@ ic::GenerateArgumentCheckStub(VMFrame &f)
JITScript *jit = f.jit();
StackFrame *fp = f.fp();
JSFunction *fun = fp->fun();
JSScript *script = fun->nonLazyScript().get(nogc);
UnrootedScript script = fun->nonLazyScript();
if (jit->argsCheckPool)
jit->resetArgsCheck();

View File

@ -770,7 +770,7 @@ namespace js {
namespace mjit {
inline void
MarkNotIdempotent(JSScript *script, jsbytecode *pc)
MarkNotIdempotent(UnrootedScript script, jsbytecode *pc)
{
if (!script->hasAnalysis())
return;
@ -1080,7 +1080,7 @@ class GetPropCompiler : public PICStubCompiler
}
RegisterID t0 = tempRegs.takeAnyReg().reg();
masm.bumpStubCount(f.script().get(nogc), f.pc(), t0);
masm.bumpStubCount(f.script(), f.pc(), t0);
/*
* Use three values above sp on the stack for use by the call to store
@ -1194,7 +1194,7 @@ class GetPropCompiler : public PICStubCompiler
}
RegisterID t0 = tempRegs.takeAnyReg().reg();
masm.bumpStubCount(f.script().get(nogc), f.pc(), t0);
masm.bumpStubCount(f.script(), f.pc(), t0);
/*
* A JSNative has the following signature:
@ -1273,10 +1273,7 @@ class GetPropCompiler : public PICStubCompiler
bool setStubShapeOffset = true;
if (obj->isDenseArray()) {
{
RawScript script = f.script().unsafeGet();
MarkNotIdempotent(script, f.pc());
}
MarkNotIdempotent(f.script(), f.pc());
start = masm.label();
shapeGuardJump = masm.branchPtr(Assembler::NotEqual,
@ -1392,10 +1389,7 @@ class GetPropCompiler : public PICStubCompiler
}
if (shape && !shape->hasDefaultGetter()) {
{
RawScript script = f.script().unsafeGet();
MarkNotIdempotent(script, f.pc());
}
MarkNotIdempotent(f.script(), f.pc());
if (shape->hasGetterValue()) {
generateNativeGetterStub(masm, shape, start, shapeMismatches);
@ -1500,24 +1494,19 @@ class GetPropCompiler : public PICStubCompiler
/* Don't touch the IC if it may have been destroyed. */
if (!monitor.recompiled())
pic.hadUncacheable = true;
RawScript script = f.script().unsafeGet();
MarkNotIdempotent(script, f.pc());
MarkNotIdempotent(f.script(), f.pc());
return status;
}
// Mark as not idempotent to avoid recompilation in Ion Monkey
// GetPropertyCache.
if (!obj->hasIdempotentProtoChain()) {
RawScript script = f.script().unsafeGet();
MarkNotIdempotent(script, f.pc());
}
if (!obj->hasIdempotentProtoChain())
MarkNotIdempotent(f.script(), f.pc());
// The property is missing, Mark as not idempotent to avoid
// recompilation in Ion Monkey GetPropertyCache.
if (!getprop.holder) {
RawScript script = f.script().unsafeGet();
MarkNotIdempotent(script, f.pc());
}
if (!getprop.holder)
MarkNotIdempotent(f.script(), f.pc());
if (hadGC())
return Lookup_Uncacheable;

View File

@ -350,7 +350,7 @@ ClearAllFrames(JSCompartment *compartment)
if (f->entryfp->compartment() != compartment)
continue;
Recompiler::patchFrame(compartment, f, f->fp()->script().get(nogc));
Recompiler::patchFrame(compartment, f, f->fp()->script());
// Clear ncode values from all frames associated with the VMFrame.
// Patching the VMFrame's return address will cause all its frames to

View File

@ -866,7 +866,7 @@ stubs::RecompileForInline(VMFrame &f)
{
AutoAssertNoGC nogc;
ExpandInlineFrames(f.cx->compartment);
Recompiler::clearStackReferences(f.cx->runtime->defaultFreeOp(), f.script().get(nogc));
Recompiler::clearStackReferences(f.cx->runtime->defaultFreeOp(), f.script());
f.jit()->destroyChunk(f.cx->runtime->defaultFreeOp(), f.chunkIndex(), /* resetUses = */ false);
}
@ -1334,7 +1334,7 @@ stubs::LookupSwitch(VMFrame &f, jsbytecode *pc)
{
AutoAssertNoGC nogc;
jsbytecode *jpc = pc;
JSScript *script = f.fp()->script().get(nogc);
UnrootedScript script = f.fp()->script();
/* This is correct because the compiler adjusts the stack beforehand. */
Value lval = f.regs.sp[-1];
@ -1660,7 +1660,7 @@ stubs::AssertArgumentTypes(VMFrame &f)
AutoAssertNoGC nogc;
StackFrame *fp = f.fp();
JSFunction *fun = fp->fun();
RawScript script = fun->nonLazyScript().get(nogc);
UnrootedScript script = fun->nonLazyScript();
/*
* Don't check the type of 'this' for constructor frames, the 'this' value
@ -1705,7 +1705,7 @@ stubs::InvariantFailure(VMFrame &f, void *rval)
*frameAddr = repatchCode;
/* Recompile the outermost script, and don't hoist any bounds checks. */
RawScript script = f.fp()->script().get(nogc);
UnrootedScript script = f.fp()->script();
JS_ASSERT(!script->failedBoundsCheck);
script->failedBoundsCheck = true;

View File

@ -1541,7 +1541,7 @@ TrapHandler(JSContext *cx, JSScript *, jsbytecode *pc, jsval *rval,
/* Debug-mode currently disables Ion compilation. */
JSStackFrame *caller = Jsvalify(iter.interpFrame());
RawScript script = iter.script().unsafeGet();
RootedScript script(cx, iter.script());
size_t length;
const jschar *chars = JS_GetStringCharsAndLength(cx, str, &length);

View File

@ -74,7 +74,7 @@ ArgumentsObject::element(uint32_t i) const
const Value &v = data()->args[i];
if (v.isMagic(JS_FORWARD_TO_CALL_OBJECT)) {
CallObject &callobj = getFixedSlot(MAYBE_CALL_SLOT).toObject().asCall();
for (AliasedFormalIter fi(callobj.callee().nonLazyScript().get(nogc)); ; fi++) {
for (AliasedFormalIter fi(callobj.callee().nonLazyScript()); ; fi++) {
if (fi.frameIndex() == i)
return callobj.aliasedVar(fi);
}
@ -90,7 +90,7 @@ ArgumentsObject::setElement(uint32_t i, const Value &v)
HeapValue &lhs = data()->args[i];
if (lhs.isMagic(JS_FORWARD_TO_CALL_OBJECT)) {
CallObject &callobj = getFixedSlot(MAYBE_CALL_SLOT).toObject().asCall();
for (AliasedFormalIter fi(callobj.callee().nonLazyScript().get(nogc)); ; fi++) {
for (AliasedFormalIter fi(callobj.callee().nonLazyScript()); ; fi++) {
if (fi.frameIndex() == i) {
callobj.setAliasedVar(fi, v);
return;

View File

@ -48,8 +48,7 @@ CopyStackFrameArguments(const StackFrame *fp, HeapValue *dst)
/* static */ void
ArgumentsObject::MaybeForwardToCallObject(StackFrame *fp, JSObject *obj, ArgumentsData *data)
{
AutoAssertNoGC nogc;
RawScript script = fp->script().get(nogc);
UnrootedScript script = fp->script();
if (fp->fun()->isHeavyweight() && script->argsObjAliasesFormals()) {
obj->initFixedSlot(MAYBE_CALL_SLOT, ObjectValue(fp->callObj()));
for (AliasedFormalIter fi(script); fi; fi++)

View File

@ -1198,7 +1198,7 @@ Debugger::onSingleStep(JSContext *cx, Value *vp)
{
AutoAssertNoGC nogc;
uint32_t stepperCount = 0;
JSScript *trappingScript = fp->script().get(nogc);
UnrootedScript trappingScript = fp->script();
GlobalObject *global = &fp->global();
if (GlobalObject::DebuggerVector *debuggers = global->getDebuggers()) {
for (Debugger **p = debuggers->begin(); p != debuggers->end(); p++) {
@ -3496,7 +3496,7 @@ DebuggerFrame_getOffset(JSContext *cx, unsigned argc, Value *vp)
{
THIS_FRAME(cx, argc, vp, "get offset", args, thisobj, fp);
AutoAssertNoGC nogc;
RawScript script = fp->script().get(nogc);
UnrootedScript script = fp->script();
jsbytecode *pc = fp->pcQuadratic(cx);
JS_ASSERT(script->code <= pc);
JS_ASSERT(pc < script->code + script->length);

View File

@ -367,7 +367,7 @@ SPSProfiler::discardMJITCode(mjit::JITScript *jscr,
unregisterScript(jscr->script, chunk);
for (unsigned i = 0; i < chunk->nInlineFrames; i++)
unregisterScript(chunk->inlineFrames()[i].fun->nonLazyScript().get(nogc), chunk);
unregisterScript(chunk->inlineFrames()[i].fun->nonLazyScript(), chunk);
}
void

View File

@ -81,12 +81,11 @@ StaticScopeIter::block() const
return obj->asStaticBlock();
}
JSScript *
UnrootedScript
StaticScopeIter::funScript() const
{
AutoAssertNoGC nogc;
JS_ASSERT(type() == FUNCTION);
return obj->toFunction()->nonLazyScript().get(nogc);
return obj->toFunction()->nonLazyScript();
}
/*****************************************************************************/
@ -1206,7 +1205,7 @@ class DebugScopeProxy : public BaseProxyHandler
return false;
if (maybefp) {
RawScript script = maybefp->script().get(nogc);
UnrootedScript script = maybefp->script();
unsigned local = block.slotToLocalIndex(script->bindings, shape->slot());
if (action == GET)
*vp = maybefp->unaliasedLocal(local);

View File

@ -71,7 +71,7 @@ class StaticScopeIter
Type type() const;
StaticBlockObject &block() const;
JSScript *funScript() const;
UnrootedScript funScript() const;
};
/*****************************************************************************/

View File

@ -579,7 +579,7 @@ ContextStack::currentScript(jsbytecode **ppc,
mjit::JITChunk *chunk = fp->jit()->chunk(regs.pc);
JS_ASSERT(inlined->inlineIndex < chunk->nInlineFrames);
mjit::InlineFrame *frame = &chunk->inlineFrames()[inlined->inlineIndex];
RawScript script = frame->fun->nonLazyScript().get(nogc);
UnrootedScript script = frame->fun->nonLazyScript();
if (!allowCrossCompartment && script->compartment() != cx_->compartment)
return NULL;
if (ppc)
@ -588,7 +588,7 @@ ContextStack::currentScript(jsbytecode **ppc,
}
#endif
RawScript script = fp->script().get(nogc);
UnrootedScript script = fp->script();
if (!allowCrossCompartment && script->compartment() != cx_->compartment)
return NULL;

View File

@ -9,6 +9,7 @@
#define Stack_h__
#include "jsfun.h"
#include "jsscript.h"
#ifdef JS_ION
#include "ion/IonFrameIterator.h"
#endif
@ -609,11 +610,11 @@ class StackFrame
* the same VMFrame. Other calls force expansion of the inlined frames.
*/
js::Return<JSScript*> script() const {
UnrootedScript script() const {
return isFunctionFrame()
? isEvalFrame()
? u.evalScript
: (JSScript*)fun()->nonLazyScript().unsafeGet()
: (RawScript)fun()->nonLazyScript()
: exec.script;
}
@ -1199,8 +1200,7 @@ class FrameRegs
}
void setToEndOfScript() {
AutoAssertNoGC nogc;
RawScript script = fp()->script().get(nogc);
UnrootedScript script = fp()->script();
sp = fp()->base();
pc = script->code + script->length - JSOP_STOP_LENGTH;
JS_ASSERT(*pc == JSOP_STOP);
@ -1800,7 +1800,7 @@ class StackIter
StackFrame *interpFrame() const { JS_ASSERT(isScript() && !isIon()); return fp_; }
jsbytecode *pc() const { JS_ASSERT(isScript()); return pc_; }
js::Return<JSScript*> script() const { JS_ASSERT(isScript()); return script_; }
UnrootedScript script() const { JS_ASSERT(isScript()); return script_; }
JSFunction *callee() const;
Value calleev() const;
unsigned numActualArgs() const;