mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-04-02 12:32:55 +00:00
Bug 929151 - Disable GGC when object metadata is used, r=terrence
This commit is contained in:
parent
28eb8d7130
commit
e059de18e1
@ -639,7 +639,7 @@ MacroAssembler::newGCThing(const Register &result, gc::AllocKind allocKind, Labe
|
||||
|
||||
// Don't execute the inline path if the compartment has an object metadata callback,
|
||||
// as the metadata to use for the object may vary between executions of the op.
|
||||
if (GetIonContext()->compartment->objectMetadataCallback)
|
||||
if (GetIonContext()->compartment->hasObjectMetadataCallback())
|
||||
jump(fail);
|
||||
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
|
@ -3125,7 +3125,7 @@ NewArray(ExclusiveContext *cxArg, uint32_t length,
|
||||
if (JSContext *cx = cxArg->maybeJSContext()) {
|
||||
NewObjectCache &cache = cx->runtime()->newObjectCache;
|
||||
if (newKind == GenericObject &&
|
||||
!cx->compartment()->objectMetadataCallback &&
|
||||
!cx->compartment()->hasObjectMetadataCallback() &&
|
||||
cache.lookupGlobal(&ArrayObject::class_, cx->global(), allocKind, &entry))
|
||||
{
|
||||
RootedObject obj(cx, cache.newObjectFromHit(cx, entry,
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
|
||||
#include "jscntxt.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "jsgc.h"
|
||||
#include "jsiter.h"
|
||||
#include "jsproxy.h"
|
||||
@ -622,6 +623,24 @@ JSCompartment::clearTables()
|
||||
lazyTypeObjects.clear();
|
||||
}
|
||||
|
||||
void
|
||||
JSCompartment::setObjectMetadataCallback(js::ObjectMetadataCallback callback)
|
||||
{
|
||||
// Clear any jitcode in the runtime, which behaves differently depending on
|
||||
// whether there is a creation callback.
|
||||
ReleaseAllJITCode(runtime_->defaultFreeOp());
|
||||
|
||||
// Turn off GGC while the metadata hook is present, to prevent
|
||||
// nursery-allocated metadata from being used as a lookup key in
|
||||
// InitialShapeTable entries.
|
||||
if (callback)
|
||||
JS::DisableGenerationalGC(runtime_);
|
||||
else
|
||||
JS::EnableGenerationalGC(runtime_);
|
||||
|
||||
objectMetadataCallback = callback;
|
||||
}
|
||||
|
||||
bool
|
||||
JSCompartment::hasScriptsOnStack()
|
||||
{
|
||||
|
@ -196,9 +196,9 @@ struct JSCompartment
|
||||
|
||||
void *data;
|
||||
|
||||
private:
|
||||
js::ObjectMetadataCallback objectMetadataCallback;
|
||||
|
||||
private:
|
||||
js::WrapperMap crossCompartmentWrappers;
|
||||
|
||||
public:
|
||||
@ -326,6 +326,12 @@ struct JSCompartment
|
||||
void purge();
|
||||
void clearTables();
|
||||
|
||||
bool hasObjectMetadataCallback() const { return objectMetadataCallback; }
|
||||
void setObjectMetadataCallback(js::ObjectMetadataCallback callback);
|
||||
bool callObjectMetadataCallback(JSContext *cx, JSObject **obj) const {
|
||||
return objectMetadataCallback(cx, obj);
|
||||
}
|
||||
|
||||
void findOutgoingEdges(js::gc::ComponentFinder<JS::Zone> &finder);
|
||||
|
||||
js::DtoaCache dtoaCache;
|
||||
|
@ -1120,11 +1120,7 @@ js::AutoCTypesActivityCallback::AutoCTypesActivityCallback(JSContext *cx,
|
||||
JS_FRIEND_API(void)
|
||||
js::SetObjectMetadataCallback(JSContext *cx, ObjectMetadataCallback callback)
|
||||
{
|
||||
// Clear any jitcode in the runtime, which behaves differently depending on
|
||||
// whether there is a creation callback.
|
||||
ReleaseAllJITCode(cx->runtime()->defaultFreeOp());
|
||||
|
||||
cx->compartment()->objectMetadataCallback = callback;
|
||||
cx->compartment()->setObjectMetadataCallback(callback);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
|
@ -1338,7 +1338,7 @@ js::NewObjectWithGivenProto(ExclusiveContext *cxArg, const js::Class *clasp,
|
||||
NewObjectCache &cache = cx->runtime()->newObjectCache;
|
||||
if (proto.isObject() &&
|
||||
newKind == GenericObject &&
|
||||
!cx->compartment()->objectMetadataCallback &&
|
||||
!cx->compartment()->hasObjectMetadataCallback() &&
|
||||
(!parent || parent == proto.toObject()->getParent()) &&
|
||||
!proto.toObject()->is<GlobalObject>())
|
||||
{
|
||||
@ -1404,7 +1404,7 @@ js::NewObjectWithClassProtoCommon(ExclusiveContext *cxArg,
|
||||
if (parentArg->is<GlobalObject>() &&
|
||||
protoKey != JSProto_Null &&
|
||||
newKind == GenericObject &&
|
||||
!cx->compartment()->objectMetadataCallback)
|
||||
!cx->compartment()->hasObjectMetadataCallback())
|
||||
{
|
||||
if (cache.lookupGlobal(clasp, &parentArg->as<GlobalObject>(), allocKind, &entry)) {
|
||||
JSObject *obj = cache.newObjectFromHit(cx, entry, GetInitialHeap(newKind, clasp));
|
||||
@ -1457,7 +1457,7 @@ NewObjectWithType(JSContext *cx, HandleTypeObject type, JSObject *parent, gc::Al
|
||||
NewObjectCache::EntryIndex entry = -1;
|
||||
if (parent == type->proto->getParent() &&
|
||||
newKind == GenericObject &&
|
||||
!cx->compartment()->objectMetadataCallback)
|
||||
!cx->compartment()->hasObjectMetadataCallback())
|
||||
{
|
||||
if (cache.lookupType(&JSObject::class_, type, allocKind, &entry)) {
|
||||
JSObject *obj = cache.newObjectFromHit(cx, entry, GetInitialHeap(newKind, &JSObject::class_));
|
||||
|
@ -1008,12 +1008,12 @@ NewObjectMetadata(ExclusiveContext *cxArg, JSObject **pmetadata)
|
||||
// analysis/compilation/parsing is active as the callback may reenter JS.
|
||||
JS_ASSERT(!*pmetadata);
|
||||
if (JSContext *cx = cxArg->maybeJSContext()) {
|
||||
if (JS_UNLIKELY((size_t)cx->compartment()->objectMetadataCallback) &&
|
||||
if (JS_UNLIKELY((size_t)cx->compartment()->hasObjectMetadataCallback()) &&
|
||||
!cx->compartment()->activeAnalysis &&
|
||||
!cx->runtime()->mainThread.activeCompilations)
|
||||
{
|
||||
gc::AutoSuppressGC suppress(cx);
|
||||
return cx->compartment()->objectMetadataCallback(cx, pmetadata);
|
||||
return cx->compartment()->callObjectMetadataCallback(cx, pmetadata);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
@ -41,7 +41,7 @@ inline JSObject *
|
||||
NewObjectCache::newObjectFromHit(JSContext *cx, EntryIndex entry_, js::gc::InitialHeap heap)
|
||||
{
|
||||
// The new object cache does not account for metadata attached via callbacks.
|
||||
JS_ASSERT(!cx->compartment()->objectMetadataCallback);
|
||||
JS_ASSERT(!cx->compartment()->hasObjectMetadataCallback());
|
||||
|
||||
JS_ASSERT(unsigned(entry_) < mozilla::ArrayLength(entries));
|
||||
Entry *entry = &entries[entry_];
|
||||
|
@ -1618,6 +1618,10 @@ EmptyShape::insertInitialShape(ExclusiveContext *cx, HandleShape shape, HandleOb
|
||||
shape->getObjectParent(), shape->getObjectMetadata(),
|
||||
shape->numFixedSlots(), shape->getObjectFlags());
|
||||
|
||||
/* Bug 929547 - we do not rekey based on metadata object moves */
|
||||
JSObject *metadata = shape->getObjectMetadata();
|
||||
JS_ASSERT_IF(metadata, gc::IsInsideNursery(cx->compartment()->runtimeFromAnyThread(), metadata));
|
||||
|
||||
InitialShapeSet::Ptr p = cx->compartment()->initialShapes.lookup(lookup);
|
||||
JS_ASSERT(p);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user