Bug 1245965 - Remove the NewObjectCache. r=terrence

This commit is contained in:
Jan de Mooij 2016-08-27 19:57:34 +02:00
Родитель 02e277f76d
Коммит 6df1030632
13 изменённых файлов: 11 добавлений и 443 удалений

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

@ -42,6 +42,7 @@ ecma_5/Object/15.2.3.6-redefinition-1-of-4.js
ecma_5/Object/15.2.3.6-redefinition-2-of-4.js
ecma_5/Object/15.2.3.6-redefinition-3-of-4.js
ecma_5/Object/15.2.3.6-redefinition-4-of-4.js
ecma_6/extensions/array-isArray-proxy-recursion.js
ecma_6/String/normalize-generateddata-part0.js
ecma_6/String/normalize-generateddata-part1-not-listed.js
ecma_6/String/normalize-generateddata-part1.js
@ -50,6 +51,7 @@ ecma_6/String/normalize-generateddata-part3.js
js1_5/GC/regress-203278-2.js
js1_5/GC/regress-203278-3.js
js1_5/GC/regress-278725.js
js1_5/Regress/regress-203278-1.js
js1_5/Regress/regress-312588.js
js1_5/Regress/regress-360969-01.js
js1_5/Regress/regress-360969-02.js
@ -58,3 +60,5 @@ js1_5/Regress/regress-360969-04.js
js1_5/Regress/regress-360969-05.js
js1_5/Regress/regress-360969-06.js
js1_8_5/extensions/clone-complex-object.js
js1_8_5/extensions/clone-many-transferables.js
js1_8_5/extensions/clone-object.js

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

@ -685,10 +685,6 @@ js::Nursery::doCollection(JSRuntime* rt, JS::gcreason::Reason reason,
}
maybeEndProfile(ProfileKey::MarkDebugger);
maybeStartProfile(ProfileKey::ClearNewObjectCache);
rt->contextFromMainThread()->caches.newObjectCache.clearNurseryObjects(rt);
maybeEndProfile(ProfileKey::ClearNewObjectCache);
// Most of the work is done here. This loop iterates over objects that have
// been moved to the major heap. If these objects have any outgoing pointers
// to the nursery, then those nursery objects get moved as well, until no

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

@ -36,7 +36,6 @@
_(CheckHashTables, "ckTbls") \
_(MarkRuntime, "mkRntm") \
_(MarkDebugger, "mkDbgr") \
_(ClearNewObjectCache, "clrNOC") \
_(CollectToFP, "collct") \
_(ObjectsTenuredCallback, "tenCB") \
_(SweepArrayBufferViewList, "swpABO") \

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

@ -42,7 +42,6 @@
#include "vm/ArgumentsObject-inl.h"
#include "vm/ArrayObject-inl.h"
#include "vm/Caches-inl.h"
#include "vm/Interpreter-inl.h"
#include "vm/NativeObject-inl.h"
#include "vm/UnboxedObject-inl.h"
@ -3382,31 +3381,6 @@ NewArray(ExclusiveContext* cxArg, uint32_t length,
if (!proto && !GetBuiltinPrototype(cxArg, JSProto_Array, &proto))
return nullptr;
Rooted<TaggedProto> taggedProto(cxArg, TaggedProto(proto));
bool isCachable = NewObjectWithTaggedProtoIsCachable(cxArg, taggedProto, newKind, &ArrayObject::class_);
if (isCachable) {
JSContext* cx = cxArg->asJSContext();
NewObjectCache& cache = cx->caches.newObjectCache;
NewObjectCache::EntryIndex entry = -1;
if (cache.lookupProto(&ArrayObject::class_, proto, allocKind, &entry)) {
gc::InitialHeap heap = GetInitialHeap(newKind, &ArrayObject::class_);
AutoSetNewObjectMetadata metadata(cx);
JSObject* obj = cache.newObjectFromHit(cx, entry, heap);
if (obj) {
/* Fixup the elements pointer and length, which may be incorrect. */
ArrayObject* arr = &obj->as<ArrayObject>();
arr->setFixedElements();
arr->setLength(cx, length);
if (maxLength > 0 &&
!EnsureNewArrayElements(cx, arr, std::min(maxLength, length)))
{
return nullptr;
}
return arr;
}
}
}
RootedObjectGroup group(cxArg, ObjectGroup::defaultNewGroup(cxArg, &ArrayObject::class_,
TaggedProto(proto)));
if (!group)
@ -3439,13 +3413,6 @@ NewArray(ExclusiveContext* cxArg, uint32_t length,
if (newKind == SingletonObject && !JSObject::setSingleton(cxArg, arr))
return nullptr;
if (isCachable) {
NewObjectCache& cache = cxArg->asJSContext()->caches.newObjectCache;
NewObjectCache::EntryIndex entry = -1;
cache.lookupProto(&ArrayObject::class_, proto, allocKind, &entry);
cache.fillProto(entry, &ArrayObject::class_, taggedProto, allocKind, arr);
}
if (maxLength > 0 && !EnsureNewArrayElements(cxArg, arr, std::min(maxLength, length)))
return nullptr;

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

@ -3597,7 +3597,6 @@ GCRuntime::purgeRuntime(AutoLockForExclusiveAccess& lock)
JSContext* cx = rt->contextFromMainThread();
cx->caches.gsnCache.purge();
cx->caches.envCoordinateNameCache.purge();
cx->caches.newObjectCache.purge();
cx->caches.nativeIterCache.purge();
cx->caches.uncompressedSourceCache.purge();
if (cx->caches.evalCache.initialized())
@ -5492,7 +5491,6 @@ GCRuntime::compactPhase(JS::gcreason::Reason reason, SliceBudget& sliceBudget,
// Clear caches that can contain cell pointers.
JSContext* cx = rt->contextFromMainThread();
cx->caches.newObjectCache.purge();
cx->caches.nativeIterCache.purge();
if (cx->caches.evalCache.initialized())
cx->caches.evalCache.clear();

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

@ -62,7 +62,6 @@
#include "vm/ArrayObject-inl.h"
#include "vm/BooleanObject-inl.h"
#include "vm/Caches-inl.h"
#include "vm/Interpreter-inl.h"
#include "vm/NativeObject-inl.h"
#include "vm/NumberObject-inl.h"
@ -683,26 +682,6 @@ NewObject(ExclusiveContext* cx, HandleObjectGroup group, gc::AllocKind kind,
return obj;
}
void
NewObjectCache::fillProto(EntryIndex entry, const Class* clasp, js::TaggedProto proto,
gc::AllocKind kind, NativeObject* obj)
{
MOZ_ASSERT_IF(proto.isObject(), !proto.toObject()->is<GlobalObject>());
MOZ_ASSERT(obj->taggedProto() == proto);
return fill(entry, clasp, proto.raw(), kind, obj);
}
bool
js::NewObjectWithTaggedProtoIsCachable(ExclusiveContext* cxArg, Handle<TaggedProto> proto,
NewObjectKind newKind, const Class* clasp)
{
return cxArg->isJSContext() &&
proto.isObject() &&
newKind == GenericObject &&
clasp->isNative() &&
!proto.toObject()->is<GlobalObject>();
}
JSObject*
js::NewObjectWithGivenTaggedProto(ExclusiveContext* cxArg, const Class* clasp,
Handle<TaggedProto> proto,
@ -712,42 +691,11 @@ js::NewObjectWithGivenTaggedProto(ExclusiveContext* cxArg, const Class* clasp,
if (CanBeFinalizedInBackground(allocKind, clasp))
allocKind = GetBackgroundAllocKind(allocKind);
bool isCachable = NewObjectWithTaggedProtoIsCachable(cxArg, proto, newKind, clasp);
if (isCachable) {
JSContext* cx = cxArg->asJSContext();
NewObjectCache& cache = cx->caches.newObjectCache;
NewObjectCache::EntryIndex entry = -1;
if (cache.lookupProto(clasp, proto.toObject(), allocKind, &entry)) {
JSObject* obj = cache.newObjectFromHit(cx, entry, GetInitialHeap(newKind, clasp));
if (obj)
return obj;
}
}
RootedObjectGroup group(cxArg, ObjectGroup::defaultNewGroup(cxArg, clasp, proto, nullptr));
if (!group)
return nullptr;
RootedObject obj(cxArg, NewObject(cxArg, group, allocKind, newKind, initialShapeFlags));
if (!obj)
return nullptr;
if (isCachable && !obj->as<NativeObject>().hasDynamicSlots()) {
NewObjectCache& cache = cxArg->asJSContext()->caches.newObjectCache;
NewObjectCache::EntryIndex entry = -1;
cache.lookupProto(clasp, proto.toObject(), allocKind, &entry);
cache.fillProto(entry, clasp, proto, allocKind, &obj->as<NativeObject>());
}
return obj;
}
static bool
NewObjectIsCachable(ExclusiveContext* cxArg, NewObjectKind newKind, const Class* clasp)
{
return cxArg->isJSContext() &&
newKind == GenericObject &&
clasp->isNative();
return NewObject(cxArg, group, allocKind, newKind, initialShapeFlags);
}
JSObject*
@ -760,20 +708,6 @@ js::NewObjectWithClassProtoCommon(ExclusiveContext* cx, const Class* clasp, Hand
if (CanBeFinalizedInBackground(allocKind, clasp))
allocKind = GetBackgroundAllocKind(allocKind);
Handle<GlobalObject*> global = cx->global();
bool isCachable = NewObjectIsCachable(cx, newKind, clasp);
if (isCachable) {
NewObjectCache& cache = cx->asJSContext()->caches.newObjectCache;
NewObjectCache::EntryIndex entry = -1;
if (cache.lookupGlobal(clasp, global, allocKind, &entry)) {
gc::InitialHeap heap = GetInitialHeap(newKind, clasp);
JSObject* obj = cache.newObjectFromHit(cx->asJSContext(), entry, heap);
if (obj)
return obj;
}
}
// Find the appropriate proto for clasp. Built-in classes have a cached
// proto on cx->global(); all others get %ObjectPrototype%.
JSProtoKey protoKey = JSCLASS_CACHED_PROTO_KEY(clasp);
@ -788,30 +722,7 @@ js::NewObjectWithClassProtoCommon(ExclusiveContext* cx, const Class* clasp, Hand
if (!group)
return nullptr;
JSObject* obj = NewObject(cx, group, allocKind, newKind);
if (!obj)
return nullptr;
if (isCachable && !obj->as<NativeObject>().hasDynamicSlots()) {
NewObjectCache& cache = cx->asJSContext()->caches.newObjectCache;
NewObjectCache::EntryIndex entry = -1;
cache.lookupGlobal(clasp, global, allocKind, &entry);
cache.fillGlobal(entry, clasp, global, allocKind,
&obj->as<NativeObject>());
}
return obj;
}
static bool
NewObjectWithGroupIsCachable(ExclusiveContext* cx, HandleObjectGroup group,
NewObjectKind newKind)
{
return group->proto().isObject() &&
newKind == GenericObject &&
group->clasp()->isNative() &&
(!group->newScript() || group->newScript()->analyzed()) &&
cx->isJSContext();
return NewObject(cx, group, allocKind, newKind);
}
/*
@ -826,30 +737,7 @@ js::NewObjectWithGroupCommon(ExclusiveContext* cx, HandleObjectGroup group,
if (CanBeFinalizedInBackground(allocKind, group->clasp()))
allocKind = GetBackgroundAllocKind(allocKind);
bool isCachable = NewObjectWithGroupIsCachable(cx, group, newKind);
if (isCachable) {
NewObjectCache& cache = cx->asJSContext()->caches.newObjectCache;
NewObjectCache::EntryIndex entry = -1;
if (cache.lookupGroup(group, allocKind, &entry)) {
JSObject* obj = cache.newObjectFromHit(cx->asJSContext(), entry,
GetInitialHeap(newKind, group->clasp()));
if (obj)
return obj;
}
}
JSObject* obj = NewObject(cx, group, allocKind, newKind);
if (!obj)
return nullptr;
if (isCachable && !obj->as<NativeObject>().hasDynamicSlots()) {
NewObjectCache& cache = cx->asJSContext()->caches.newObjectCache;
NewObjectCache::EntryIndex entry = -1;
cache.lookupGroup(group, allocKind, &entry);
cache.fillGroup(entry, group, allocKind, &obj->as<NativeObject>());
}
return obj;
return NewObject(cx, group, allocKind, newKind);
}
bool

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

@ -73,7 +73,6 @@ extern const Class JSONClass;
extern const Class MathClass;
class GlobalObject;
class NewObjectCache;
// Forward declarations, required for later friend declarations.
bool PreventExtensions(JSContext* cx, JS::HandleObject obj, JS::ObjectOpResult& result);
@ -103,7 +102,6 @@ class JSObject : public js::gc::Cell
private:
friend class js::Shape;
friend class js::GCMarker;
friend class js::NewObjectCache;
friend class js::Nursery;
friend class js::gc::RelocationOverlay;
friend bool js::PreventExtensions(JSContext* cx, JS::HandleObject obj, JS::ObjectOpResult& result);
@ -1128,10 +1126,6 @@ GetInitialHeap(NewObjectKind newKind, const Class* clasp)
return gc::DefaultHeap;
}
bool
NewObjectWithTaggedProtoIsCachable(ExclusiveContext* cxArg, Handle<TaggedProto> proto,
NewObjectKind newKind, const Class* clasp);
// ES6 9.1.15 GetPrototypeFromConstructor.
extern bool
GetPrototypeFromConstructor(JSContext* cx, js::HandleObject newTarget, js::MutableHandleObject proto);

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

@ -1,82 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef vm_Caches_inl_h
#define vm_Caches_inl_h
#include "vm/Caches.h"
#include "jscompartment.h"
#include "gc/Allocator.h"
#include "gc/GCTrace.h"
#include "vm/Probes.h"
#include "jsobjinlines.h"
namespace js {
inline bool
NewObjectCache::lookupProto(const Class* clasp, JSObject* proto, gc::AllocKind kind, EntryIndex* pentry)
{
MOZ_ASSERT(!proto->is<GlobalObject>());
return lookup(clasp, proto, kind, pentry);
}
inline bool
NewObjectCache::lookupGlobal(const Class* clasp, GlobalObject* global, gc::AllocKind kind, EntryIndex* pentry)
{
return lookup(clasp, global, kind, pentry);
}
inline void
NewObjectCache::fillGlobal(EntryIndex entry, const Class* clasp, GlobalObject* global,
gc::AllocKind kind, NativeObject* obj)
{
//MOZ_ASSERT(global == obj->getGlobal());
return fill(entry, clasp, global, kind, obj);
}
inline NativeObject*
NewObjectCache::newObjectFromHit(JSContext* cx, EntryIndex entryIndex, gc::InitialHeap heap)
{
MOZ_ASSERT(unsigned(entryIndex) < mozilla::ArrayLength(entries));
Entry* entry = &entries[entryIndex];
NativeObject* templateObj = reinterpret_cast<NativeObject*>(&entry->templateObject);
// Do an end run around JSObject::group() to avoid doing AutoUnprotectCell
// on the templateObj, which is not a GC thing and can't use runtimeFromAnyThread.
ObjectGroup* group = templateObj->group_;
MOZ_ASSERT(!group->hasUnanalyzedPreliminaryObjects());
if (group->shouldPreTenure())
heap = gc::TenuredHeap;
if (cx->runtime()->gc.upcomingZealousGC())
return nullptr;
NativeObject* obj = static_cast<NativeObject*>(Allocate<JSObject, NoGC>(cx, entry->kind, 0,
heap, group->clasp()));
if (!obj)
return nullptr;
copyCachedToObject(obj, templateObj, entry->kind);
if (group->clasp()->shouldDelayMetadataBuilder())
cx->compartment()->setObjectPendingMetadata(cx, obj);
else
obj = static_cast<NativeObject*>(SetNewObjectMetadata(cx, obj));
probes::CreateObject(cx, obj);
gc::TraceCreateObject(obj);
return obj;
}
} /* namespace js */
#endif /* vm_Caches_inl_h */

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

@ -4,13 +4,14 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "vm/Caches-inl.h"
#include "vm/Caches.h"
#include "mozilla/PodOperations.h"
using namespace js;
#include "jscntxt.h"
#include "jsmath.h"
using mozilla::PodZero;
using namespace js;
MathCache*
ContextCaches::createMathCache(JSContext* cx)
@ -35,18 +36,3 @@ ContextCaches::init()
return true;
}
void
NewObjectCache::clearNurseryObjects(JSRuntime* rt)
{
for (unsigned i = 0; i < mozilla::ArrayLength(entries); ++i) {
Entry& e = entries[i];
NativeObject* obj = reinterpret_cast<NativeObject*>(&e.templateObject);
if (IsInsideNursery(e.key) ||
rt->gc.nursery.isInside(obj->slots_) ||
rt->gc.nursery.isInside(obj->elements_))
{
PodZero(&e);
}
}
}

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

@ -149,137 +149,6 @@ class NativeIterCache
}
};
/*
* Cache for speeding up repetitive creation of objects in the VM.
* When an object is created which matches the criteria in the 'key' section
* below, an entry is filled with the resulting object.
*/
class NewObjectCache
{
/* Statically asserted to be equal to sizeof(JSObject_Slots16) */
static const unsigned MAX_OBJ_SIZE = 4 * sizeof(void*) + 16 * sizeof(Value);
static void staticAsserts() {
JS_STATIC_ASSERT(NewObjectCache::MAX_OBJ_SIZE == sizeof(JSObject_Slots16));
JS_STATIC_ASSERT(gc::AllocKind::OBJECT_LAST == gc::AllocKind::OBJECT16_BACKGROUND);
}
struct Entry
{
/* Class of the constructed object. */
const Class* clasp;
/*
* Key with one of three possible values:
*
* - Global for the object. The object must have a standard class for
* which the global's prototype can be determined, and the object's
* parent will be the global.
*
* - Prototype for the object (cannot be global). The object's parent
* will be the prototype's parent.
*
* - Type for the object. The object's parent will be the type's
* prototype's parent.
*/
gc::Cell* key;
/* Allocation kind for the constructed object. */
gc::AllocKind kind;
/* Number of bytes to copy from the template object. */
uint32_t nbytes;
/*
* Template object to copy from, with the initial values of fields,
* fixed slots (undefined) and private data (nullptr).
*/
char templateObject[MAX_OBJ_SIZE];
};
Entry entries[41]; // TODO: reconsider size
public:
typedef int EntryIndex;
NewObjectCache() { mozilla::PodZero(this); }
void purge() { mozilla::PodZero(this); }
/* Remove any cached items keyed on moved objects. */
void clearNurseryObjects(JSRuntime* rt);
/*
* Get the entry index for the given lookup, return whether there was a hit
* on an existing entry.
*/
inline bool lookupProto(const Class* clasp, JSObject* proto, gc::AllocKind kind, EntryIndex* pentry);
inline bool lookupGlobal(const Class* clasp, js::GlobalObject* global, gc::AllocKind kind,
EntryIndex* pentry);
bool lookupGroup(js::ObjectGroup* group, gc::AllocKind kind, EntryIndex* pentry) {
return lookup(group->clasp(), group, kind, pentry);
}
/*
* Return a new object from a cache hit produced by a lookup method, or
* nullptr if returning the object could possibly trigger GC (does not
* indicate failure).
*/
inline NativeObject* newObjectFromHit(JSContext* cx, EntryIndex entry, js::gc::InitialHeap heap);
/* Fill an entry after a cache miss. */
void fillProto(EntryIndex entry, const Class* clasp, js::TaggedProto proto,
gc::AllocKind kind, NativeObject* obj);
inline void fillGlobal(EntryIndex entry, const Class* clasp, js::GlobalObject* global,
gc::AllocKind kind, NativeObject* obj);
void fillGroup(EntryIndex entry, js::ObjectGroup* group, gc::AllocKind kind,
NativeObject* obj)
{
MOZ_ASSERT(obj->group() == group);
return fill(entry, group->clasp(), group, kind, obj);
}
/* Invalidate any entries which might produce an object with shape/proto. */
void invalidateEntriesForShape(JSContext* cx, HandleShape shape, HandleObject proto);
private:
EntryIndex makeIndex(const Class* clasp, gc::Cell* key, gc::AllocKind kind) {
uintptr_t hash = (uintptr_t(clasp) ^ uintptr_t(key)) + size_t(kind);
return hash % mozilla::ArrayLength(entries);
}
bool lookup(const Class* clasp, gc::Cell* key, gc::AllocKind kind, EntryIndex* pentry) {
*pentry = makeIndex(clasp, key, kind);
Entry* entry = &entries[*pentry];
/* N.B. Lookups with the same clasp/key but different kinds map to different entries. */
return entry->clasp == clasp && entry->key == key;
}
void fill(EntryIndex entry_, const Class* clasp, gc::Cell* key, gc::AllocKind kind,
NativeObject* obj) {
MOZ_ASSERT(unsigned(entry_) < mozilla::ArrayLength(entries));
MOZ_ASSERT(entry_ == makeIndex(clasp, key, kind));
Entry* entry = &entries[entry_];
entry->clasp = clasp;
entry->key = key;
entry->kind = kind;
entry->nbytes = gc::Arena::thingSize(kind);
js_memcpy(&entry->templateObject, obj, entry->nbytes);
}
static void copyCachedToObject(NativeObject* dst, NativeObject* src, gc::AllocKind kind) {
js_memcpy(dst, src, gc::Arena::thingSize(kind));
Shape::writeBarrierPost(&dst->shape_, nullptr, dst->shape_);
ObjectGroup::writeBarrierPost(&dst->group_, nullptr, dst->group_);
}
};
class MathCache;
class ContextCaches
@ -291,7 +160,6 @@ class ContextCaches
public:
js::GSNCache gsnCache;
js::EnvironmentCoordinateNameCache envCoordinateNameCache;
js::NewObjectCache newObjectCache;
js::NativeIterCache nativeIterCache;
js::UncompressedSourceCache uncompressedSourceCache;
js::EvalCache evalCache;

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

@ -307,8 +307,6 @@ struct Class;
class GCMarker;
class Shape;
class NewObjectCache;
#ifdef DEBUG
static inline bool
IsObjectValueInCompartment(Value v, JSCompartment* comp);
@ -534,7 +532,6 @@ class NativeObject : public ShapedObject
protected:
friend class GCMarker;
friend class Shape;
friend class NewObjectCache;
void invalidateSlotRange(uint32_t start, uint32_t length) {
#ifdef DEBUG

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

@ -24,7 +24,6 @@
#include "jscompartmentinlines.h"
#include "jsobjinlines.h"
#include "vm/Caches-inl.h"
#include "vm/NativeObject-inl.h"
using namespace js;
@ -1530,35 +1529,6 @@ EmptyShape::getInitialShape(ExclusiveContext* cx, const Class* clasp, TaggedProt
return getInitialShape(cx, clasp, proto, GetGCKindSlots(kind, clasp), objectFlags);
}
void
NewObjectCache::invalidateEntriesForShape(JSContext* cx, HandleShape shape, HandleObject proto)
{
const Class* clasp = shape->getObjectClass();
gc::AllocKind kind = gc::GetGCObjectKind(shape->numFixedSlots());
if (CanBeFinalizedInBackground(kind, clasp))
kind = GetBackgroundAllocKind(kind);
RootedObjectGroup group(cx, ObjectGroup::defaultNewGroup(cx, clasp, TaggedProto(proto)));
if (!group) {
purge();
cx->recoverFromOutOfMemory();
return;
}
EntryIndex entry;
for (CompartmentsInZoneIter comp(shape->zone()); !comp.done(); comp.next()) {
if (GlobalObject* global = comp->unsafeUnbarrieredMaybeGlobal()) {
if (lookupGlobal(clasp, global, kind, &entry))
PodZero(&entries[entry]);
}
}
if (!proto->is<GlobalObject>() && lookupProto(clasp, proto, kind, &entry))
PodZero(&entries[entry]);
if (lookupGroup(group, kind, &entry))
PodZero(&entries[entry]);
}
/* static */ void
EmptyShape::insertInitialShape(ExclusiveContext* cx, HandleShape shape, HandleObject proto)
{
@ -1583,21 +1553,6 @@ EmptyShape::insertInitialShape(ExclusiveContext* cx, HandleShape shape, HandleOb
#endif
entry.shape = ReadBarrieredShape(shape);
/*
* This affects the shape that will be produced by the various NewObject
* methods, so clear any cache entry referring to the old shape. This is
* not required for correctness: the NewObject must always check for a
* nativeEmpty() result and generate the appropriate properties if found.
* Clearing the cache entry avoids this duplicate regeneration.
*
* Clearing is not necessary when this context is running off the main
* thread, as it will not use the new object cache for allocations.
*/
if (cx->isJSContext()) {
JSContext* ncx = cx->asJSContext();
ncx->caches.newObjectCache.invalidateEntriesForShape(ncx, shape, proto);
}
}
void

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

@ -12,8 +12,6 @@
#include "gc/Barrier.h"
#include "gc/Zone.h"
#include "vm/Caches-inl.h"
namespace js {
/* static */ void