зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1175511 - Use template objects for arguments object allocation. r=bhackett
--HG-- extra : rebase_source : f78979baa09c4c5b307d838632c4767e02d87c2f
This commit is contained in:
Родитель
69ce2d9220
Коммит
6b7e6dcbe1
|
@ -77,7 +77,9 @@ JSCompartment::JSCompartment(Zone* zone, const JS::CompartmentOptions& options =
|
|||
compartmentStats(nullptr),
|
||||
scheduledForDestruction(false),
|
||||
maybeAlive(true),
|
||||
jitCompartment_(nullptr)
|
||||
jitCompartment_(nullptr),
|
||||
normalArgumentsTemplate_(nullptr),
|
||||
strictArgumentsTemplate_(nullptr)
|
||||
{
|
||||
PodArrayZero(sawDeprecatedLanguageExtension);
|
||||
runtime_->numCompartments++;
|
||||
|
@ -655,7 +657,18 @@ JSCompartment::sweepCrossCompartmentWrappers()
|
|||
}
|
||||
}
|
||||
|
||||
void JSCompartment::fixupAfterMovingGC()
|
||||
void
|
||||
JSCompartment::sweepTemplateObjects()
|
||||
{
|
||||
if (normalArgumentsTemplate_ && IsAboutToBeFinalized(&normalArgumentsTemplate_))
|
||||
normalArgumentsTemplate_.set(nullptr);
|
||||
|
||||
if (strictArgumentsTemplate_ && IsAboutToBeFinalized(&strictArgumentsTemplate_))
|
||||
strictArgumentsTemplate_.set(nullptr);
|
||||
}
|
||||
|
||||
void
|
||||
JSCompartment::fixupAfterMovingGC()
|
||||
{
|
||||
fixupGlobal();
|
||||
fixupInitialShapeTable();
|
||||
|
|
|
@ -426,6 +426,7 @@ struct JSCompartment
|
|||
void sweepDebugScopes();
|
||||
void sweepWeakMaps();
|
||||
void sweepNativeIterators();
|
||||
void sweepTemplateObjects();
|
||||
|
||||
void purge();
|
||||
void clearTables();
|
||||
|
@ -578,6 +579,9 @@ struct JSCompartment
|
|||
private:
|
||||
js::jit::JitCompartment* jitCompartment_;
|
||||
|
||||
js::ReadBarriered<js::ArgumentsObject*> normalArgumentsTemplate_;
|
||||
js::ReadBarriered<js::ArgumentsObject*> strictArgumentsTemplate_;
|
||||
|
||||
public:
|
||||
bool ensureJitCompartmentExists(JSContext* cx);
|
||||
js::jit::JitCompartment* jitCompartment() {
|
||||
|
@ -597,6 +601,8 @@ struct JSCompartment
|
|||
DeprecatedLanguageExtensionCount
|
||||
};
|
||||
|
||||
js::ArgumentsObject* getOrCreateArgumentsTemplateObject(JSContext* cx, bool strict);
|
||||
|
||||
private:
|
||||
// Used for collecting telemetry on SpiderMonkey's deprecated language extensions.
|
||||
bool sawDeprecatedLanguageExtension[DeprecatedLanguageExtensionCount];
|
||||
|
|
|
@ -2257,6 +2257,7 @@ GCRuntime::sweepZoneAfterCompacting(Zone* zone)
|
|||
c->sweepJitCompartment(fop);
|
||||
c->sweepWeakMaps();
|
||||
c->sweepNativeIterators();
|
||||
c->sweepTemplateObjects();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4927,6 +4928,7 @@ GCRuntime::beginSweepingZoneGroup()
|
|||
c->sweepDebugScopes();
|
||||
c->sweepJitCompartment(&fop);
|
||||
c->sweepWeakMaps();
|
||||
c->sweepTemplateObjects();
|
||||
}
|
||||
|
||||
// Bug 1071218: the following two methods have not yet been
|
||||
|
|
|
@ -157,18 +157,15 @@ struct CopyScriptFrameIterArgs
|
|||
}
|
||||
};
|
||||
|
||||
template <typename CopyArgs>
|
||||
/* static */ ArgumentsObject*
|
||||
ArgumentsObject::create(JSContext* cx, HandleScript script, HandleFunction callee,
|
||||
unsigned numActuals, CopyArgs& copy)
|
||||
ArgumentsObject*
|
||||
ArgumentsObject::createTemplateObject(JSContext* cx, bool strict)
|
||||
{
|
||||
RootedObject proto(cx, callee->global().getOrCreateObjectPrototype(cx));
|
||||
const Class* clasp = strict ? &StrictArgumentsObject::class_ : &NormalArgumentsObject::class_;
|
||||
|
||||
RootedObject proto(cx, cx->global()->getOrCreateObjectPrototype(cx));
|
||||
if (!proto)
|
||||
return nullptr;
|
||||
|
||||
bool strict = callee->strict();
|
||||
const Class* clasp = strict ? &StrictArgumentsObject::class_ : &NormalArgumentsObject::class_;
|
||||
|
||||
RootedObjectGroup group(cx, ObjectGroup::defaultNewGroup(cx, clasp, TaggedProto(proto.get())));
|
||||
if (!group)
|
||||
return nullptr;
|
||||
|
@ -178,6 +175,45 @@ ArgumentsObject::create(JSContext* cx, HandleScript script, HandleFunction calle
|
|||
if (!shape)
|
||||
return nullptr;
|
||||
|
||||
JSObject* base = JSObject::create(cx, FINALIZE_KIND, gc::TenuredHeap, shape, group);
|
||||
if (!base)
|
||||
return nullptr;
|
||||
|
||||
ArgumentsObject* obj = &base->as<js::ArgumentsObject>();
|
||||
obj->initFixedSlot(ArgumentsObject::DATA_SLOT, PrivateValue(nullptr));
|
||||
return obj;
|
||||
}
|
||||
|
||||
ArgumentsObject*
|
||||
JSCompartment::getOrCreateArgumentsTemplateObject(JSContext* cx, bool strict)
|
||||
{
|
||||
ReadBarriered<ArgumentsObject*>& obj =
|
||||
strict ? strictArgumentsTemplate_ : normalArgumentsTemplate_;
|
||||
|
||||
ArgumentsObject* templateObj = obj;
|
||||
if (templateObj)
|
||||
return templateObj;
|
||||
|
||||
templateObj = ArgumentsObject::createTemplateObject(cx, strict);
|
||||
if (!templateObj)
|
||||
return nullptr;
|
||||
|
||||
obj.set(templateObj);
|
||||
return templateObj;
|
||||
}
|
||||
|
||||
template <typename CopyArgs>
|
||||
/* static */ ArgumentsObject*
|
||||
ArgumentsObject::create(JSContext* cx, HandleFunction callee, unsigned numActuals, CopyArgs& copy)
|
||||
{
|
||||
bool strict = callee->strict();
|
||||
ArgumentsObject* templateObj = cx->compartment()->getOrCreateArgumentsTemplateObject(cx, strict);
|
||||
if (!templateObj)
|
||||
return nullptr;
|
||||
|
||||
RootedShape shape(cx, templateObj->lastProperty());
|
||||
RootedObjectGroup group(cx, templateObj->group());
|
||||
|
||||
unsigned numFormals = callee->nargs();
|
||||
unsigned numDeletedWords = NumWordsForBitArrayOfLength(numActuals);
|
||||
unsigned numArgs = Max(numActuals, numFormals);
|
||||
|
@ -186,9 +222,7 @@ ArgumentsObject::create(JSContext* cx, HandleScript script, HandleFunction calle
|
|||
numArgs * sizeof(Value);
|
||||
|
||||
Rooted<ArgumentsObject*> obj(cx);
|
||||
JSObject* base = JSObject::create(cx, FINALIZE_KIND,
|
||||
GetInitialHeap(GenericObject, clasp),
|
||||
shape, group);
|
||||
JSObject* base = JSObject::create(cx, FINALIZE_KIND, gc::DefaultHeap, shape, group);
|
||||
if (!base)
|
||||
return nullptr;
|
||||
obj = &base->as<ArgumentsObject>();
|
||||
|
@ -204,7 +238,7 @@ ArgumentsObject::create(JSContext* cx, HandleScript script, HandleFunction calle
|
|||
data->numArgs = numArgs;
|
||||
data->dataBytes = numBytes;
|
||||
data->callee.init(ObjectValue(*callee.get()));
|
||||
data->script = script;
|
||||
data->script = callee->nonLazyScript();
|
||||
|
||||
// Zero the argument Values. This sets each value to DoubleValue(0), which
|
||||
// is safe for GC tracing.
|
||||
|
@ -233,10 +267,9 @@ ArgumentsObject*
|
|||
ArgumentsObject::createExpected(JSContext* cx, AbstractFramePtr frame)
|
||||
{
|
||||
MOZ_ASSERT(frame.script()->needsArgsObj());
|
||||
RootedScript script(cx, frame.script());
|
||||
RootedFunction callee(cx, frame.callee());
|
||||
CopyFrameArgs copy(frame);
|
||||
ArgumentsObject* argsobj = create(cx, script, callee, frame.numActualArgs(), copy);
|
||||
ArgumentsObject* argsobj = create(cx, callee, frame.numActualArgs(), copy);
|
||||
if (!argsobj)
|
||||
return nullptr;
|
||||
|
||||
|
@ -247,19 +280,17 @@ ArgumentsObject::createExpected(JSContext* cx, AbstractFramePtr frame)
|
|||
ArgumentsObject*
|
||||
ArgumentsObject::createUnexpected(JSContext* cx, ScriptFrameIter& iter)
|
||||
{
|
||||
RootedScript script(cx, iter.script());
|
||||
RootedFunction callee(cx, iter.callee(cx));
|
||||
CopyScriptFrameIterArgs copy(iter);
|
||||
return create(cx, script, callee, iter.numActualArgs(), copy);
|
||||
return create(cx, callee, iter.numActualArgs(), copy);
|
||||
}
|
||||
|
||||
ArgumentsObject*
|
||||
ArgumentsObject::createUnexpected(JSContext* cx, AbstractFramePtr frame)
|
||||
{
|
||||
RootedScript script(cx, frame.script());
|
||||
RootedFunction callee(cx, frame.callee());
|
||||
CopyFrameArgs copy(frame);
|
||||
return create(cx, script, callee, frame.numActualArgs(), copy);
|
||||
return create(cx, callee, frame.numActualArgs(), copy);
|
||||
}
|
||||
|
||||
ArgumentsObject*
|
||||
|
@ -267,11 +298,10 @@ ArgumentsObject::createForIon(JSContext* cx, jit::JitFrameLayout* frame, HandleO
|
|||
{
|
||||
jit::CalleeToken token = frame->calleeToken();
|
||||
MOZ_ASSERT(jit::CalleeTokenIsFunction(token));
|
||||
RootedScript script(cx, jit::ScriptFromCalleeToken(token));
|
||||
RootedFunction callee(cx, jit::CalleeTokenToFunction(token));
|
||||
RootedObject callObj(cx, scopeChain->is<CallObject>() ? scopeChain.get() : nullptr);
|
||||
CopyJitFrameArgs copy(frame, callObj);
|
||||
return create(cx, script, callee, frame->numActualArgs(), copy);
|
||||
return create(cx, callee, frame->numActualArgs(), copy);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
@ -544,10 +574,11 @@ void
|
|||
ArgumentsObject::trace(JSTracer* trc, JSObject* obj)
|
||||
{
|
||||
ArgumentsObject& argsobj = obj->as<ArgumentsObject>();
|
||||
ArgumentsData* data = argsobj.data();
|
||||
TraceEdge(trc, &data->callee, js_callee_str);
|
||||
TraceRange(trc, data->numArgs, data->begin(), js_arguments_str);
|
||||
TraceManuallyBarrieredEdge(trc, &data->script, "script");
|
||||
if (ArgumentsData* data = argsobj.data()) { // Template objects have no ArgumentsData.
|
||||
TraceEdge(trc, &data->callee, js_callee_str);
|
||||
TraceRange(trc, data->numArgs, data->begin(), js_arguments_str);
|
||||
TraceManuallyBarrieredEdge(trc, &data->script, "script");
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ size_t
|
||||
|
|
|
@ -129,8 +129,8 @@ class ArgumentsObject : public NativeObject
|
|||
|
||||
protected:
|
||||
template <typename CopyArgs>
|
||||
static ArgumentsObject* create(JSContext* cx, HandleScript script, HandleFunction callee,
|
||||
unsigned numActuals, CopyArgs& copy);
|
||||
static ArgumentsObject* create(JSContext* cx, HandleFunction callee, unsigned numActuals,
|
||||
CopyArgs& copy);
|
||||
|
||||
ArgumentsData* data() const {
|
||||
return reinterpret_cast<ArgumentsData*>(getFixedSlot(DATA_SLOT).toPrivate());
|
||||
|
@ -154,6 +154,8 @@ class ArgumentsObject : public NativeObject
|
|||
static ArgumentsObject* createForIon(JSContext* cx, jit::JitFrameLayout* frame,
|
||||
HandleObject scopeChain);
|
||||
|
||||
static ArgumentsObject* createTemplateObject(JSContext* cx, bool strict);
|
||||
|
||||
/*
|
||||
* Return the initial length of the arguments. This may differ from the
|
||||
* current value of arguments.length!
|
||||
|
|
Загрузка…
Ссылка в новой задаче