Bug 1175511 - Use template objects for arguments object allocation. r=bhackett

--HG--
extra : rebase_source : f78979baa09c4c5b307d838632c4767e02d87c2f
This commit is contained in:
Jan de Mooij 2015-07-03 20:41:52 +02:00
Родитель 69ce2d9220
Коммит 6b7e6dcbe1
5 изменённых файлов: 82 добавлений и 28 удалений

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

@ -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!