зеркало из https://github.com/mozilla/pjs.git
Avoid needless prototype-shape purges (454035, r=igor).
This commit is contained in:
Родитель
4a06cffaf6
Коммит
3489dce8c9
|
@ -1171,9 +1171,9 @@ js_MakeArraySlow(JSContext *cx, JSObject *obj)
|
|||
? INT_TO_JSVAL(length)
|
||||
: JSVAL_VOID;
|
||||
|
||||
/* Make sure we preserve any flags borrowing bits in JSSLOT_CLASS. */
|
||||
obj->fslots[JSSLOT_CLASS] ^= (jsval) &js_ArrayClass;
|
||||
obj->fslots[JSSLOT_CLASS] |= (jsval) &js_SlowArrayClass;
|
||||
/* Make sure we preserve any flags borrowing bits in classword. */
|
||||
obj->classword ^= (jsuword) &js_ArrayClass;
|
||||
obj->classword |= (jsuword) &js_SlowArrayClass;
|
||||
|
||||
/* Swap in our new map. */
|
||||
oldmap = obj->map;
|
||||
|
|
|
@ -469,12 +469,12 @@ js_FastNewArray(JSContext* cx, JSObject* proto)
|
|||
if (!obj)
|
||||
return NULL;
|
||||
|
||||
JSClass* clasp = &js_ArrayClass;
|
||||
obj->classword = jsuword(clasp);
|
||||
|
||||
obj->fslots[JSSLOT_PROTO] = OBJECT_TO_JSVAL(proto);
|
||||
obj->fslots[JSSLOT_PARENT] = proto->fslots[JSSLOT_PARENT];
|
||||
|
||||
JSClass* clasp = &js_ArrayClass;
|
||||
obj->fslots[JSSLOT_CLASS] = PRIVATE_TO_JSVAL(clasp);
|
||||
|
||||
obj->fslots[JSSLOT_ARRAY_LENGTH] = 0;
|
||||
obj->fslots[JSSLOT_ARRAY_COUNT] = 0;
|
||||
for (unsigned i = JSSLOT_ARRAY_COUNT + 1; i != JS_INITIAL_NSLOTS; ++i)
|
||||
|
@ -514,9 +514,9 @@ js_FastNewObject(JSContext* cx, JSObject* ctor)
|
|||
JS_ASSERT(!JSVAL_IS_PRIMITIVE(v));
|
||||
JSObject* proto = JSVAL_TO_OBJECT(v);
|
||||
|
||||
obj->classword = jsuword(clasp);
|
||||
obj->fslots[JSSLOT_PROTO] = OBJECT_TO_JSVAL(proto);
|
||||
obj->fslots[JSSLOT_PARENT] = ctor->fslots[JSSLOT_PARENT];
|
||||
obj->fslots[JSSLOT_CLASS] = PRIVATE_TO_JSVAL(clasp);
|
||||
for (unsigned i = JSSLOT_PRIVATE; i != JS_INITIAL_NSLOTS; ++i)
|
||||
obj->fslots[i] = JSVAL_VOID;
|
||||
|
||||
|
|
|
@ -332,8 +332,7 @@ js_FullTestPropertyCache(JSContext *cx, jsbytecode *pc,
|
|||
PCMETER(JS_PROPERTY_CACHE(cx).idmisses++);
|
||||
|
||||
#ifdef DEBUG_notme
|
||||
entry = &JS_PROPERTY_CACHE(cx)
|
||||
.table[PROPERTY_CACHE_HASH_PC(pc, OBJ_SCOPE(obj)->shape)];
|
||||
entry = &JS_PROPERTY_CACHE(cx).table[PROPERTY_CACHE_HASH_PC(pc, OBJ_SHAPE(obj))];
|
||||
fprintf(stderr,
|
||||
"id miss for %s from %s:%u"
|
||||
" (pc %u, kpc %u, kshape %u, shape %u)\n",
|
||||
|
@ -343,10 +342,10 @@ js_FullTestPropertyCache(JSContext *cx, jsbytecode *pc,
|
|||
pc - cx->fp->script->code,
|
||||
entry->kpc - cx->fp->script->code,
|
||||
entry->kshape,
|
||||
OBJ_SCOPE(obj)->shape);
|
||||
OBJ_SHAPE(obj));
|
||||
js_Disassemble1(cx, cx->fp->script, pc,
|
||||
PTRDIFF(pc, cx->fp->script->code, jsbytecode),
|
||||
JS_FALSE, stderr);
|
||||
PTRDIFF(pc, cx->fp->script->code, jsbytecode),
|
||||
JS_FALSE, stderr);
|
||||
#endif
|
||||
|
||||
return atom;
|
||||
|
@ -384,7 +383,7 @@ js_FullTestPropertyCache(JSContext *cx, jsbytecode *pc,
|
|||
--vcap;
|
||||
}
|
||||
|
||||
if (PCVCAP_SHAPE(vcap) == OBJ_SCOPE(pobj)->shape) {
|
||||
if (PCVCAP_SHAPE(vcap) == OBJ_SHAPE(pobj)) {
|
||||
#ifdef DEBUG
|
||||
jsid id = ATOM_TO_JSID(atom);
|
||||
|
||||
|
@ -4420,7 +4419,7 @@ js_Interpret(JSContext *cx)
|
|||
atom = NULL;
|
||||
if (JS_LIKELY(obj->map->ops->setProperty == js_SetProperty)) {
|
||||
JSPropertyCache *cache = &JS_PROPERTY_CACHE(cx);
|
||||
uint32 kshape = OBJ_SCOPE(obj)->shape;
|
||||
uint32 kshape = OBJ_SHAPE(obj);
|
||||
|
||||
/*
|
||||
* Open-code JS_PROPERTY_CACHE_TEST, specializing for two
|
||||
|
|
|
@ -162,7 +162,7 @@ typedef struct JSInlineFrame {
|
|||
PROPERTY_CACHE_HASH(pc, kshape)
|
||||
|
||||
#define PROPERTY_CACHE_HASH_ATOM(atom,obj,pobj) \
|
||||
PROPERTY_CACHE_HASH((jsuword)(atom) >> 2, OBJ_SCOPE(obj)->shape)
|
||||
PROPERTY_CACHE_HASH((jsuword)(atom) >> 2, OBJ_SHAPE(obj))
|
||||
|
||||
/*
|
||||
* Property cache value capability macros.
|
||||
|
@ -276,8 +276,8 @@ typedef struct JSPropertyCache {
|
|||
|
||||
/*
|
||||
* Fill property cache entry for key cx->fp->pc, optimized value word computed
|
||||
* from obj and sprop, and entry capability forged from OBJ_SCOPE(obj)->shape,
|
||||
* scopeIndex, and protoIndex.
|
||||
* from obj and sprop, and entry capability forged from 24-bit OBJ_SHAPE(obj),
|
||||
* 4-bit scopeIndex, and 4-bit protoIndex.
|
||||
*/
|
||||
extern void
|
||||
js_FillPropertyCache(JSContext *cx, JSObject *obj, jsuword kshape,
|
||||
|
@ -304,8 +304,7 @@ js_FillPropertyCache(JSContext *cx, JSObject *obj, jsuword kshape,
|
|||
#define PROPERTY_CACHE_TEST(cx, pc, obj, pobj, entry, atom) \
|
||||
do { \
|
||||
JSPropertyCache *cache_ = &JS_PROPERTY_CACHE(cx); \
|
||||
uint32 kshape_ = (JS_ASSERT(OBJ_IS_NATIVE(obj)), \
|
||||
OBJ_SCOPE(obj)->shape); \
|
||||
uint32 kshape_ = (JS_ASSERT(OBJ_IS_NATIVE(obj)), OBJ_SHAPE(obj)); \
|
||||
entry = &cache_->table[PROPERTY_CACHE_HASH_PC(pc, kshape_)]; \
|
||||
PCMETER(cache_->tests++); \
|
||||
JS_ASSERT(&obj != &pobj); \
|
||||
|
@ -321,7 +320,7 @@ js_FillPropertyCache(JSContext *cx, JSObject *obj, jsuword kshape,
|
|||
pobj = tmp_; \
|
||||
JS_LOCK_OBJ(cx, pobj); \
|
||||
} \
|
||||
if (PCVCAP_SHAPE(entry->vcap) == OBJ_SCOPE(pobj)->shape) { \
|
||||
if (PCVCAP_SHAPE(entry->vcap) == OBJ_SHAPE(pobj)) { \
|
||||
PCMETER(cache_->pchits++); \
|
||||
PCMETER(!PCVCAP_TAG(entry->vcap) || cache_->protopchits++); \
|
||||
pobj = OBJ_SCOPE(pobj)->object; \
|
||||
|
|
|
@ -2559,18 +2559,19 @@ js_NewObjectWithGivenProto(JSContext *cx, JSClass *clasp, JSObject *proto,
|
|||
obj->map = NULL;
|
||||
obj->dslots = NULL;
|
||||
|
||||
/*
|
||||
* Set the class slot with the initial value of the system and delegate
|
||||
* flags set to false.
|
||||
*/
|
||||
JS_ASSERT(((jsuword) clasp & 3) == 0);
|
||||
obj->classword = jsuword(clasp);
|
||||
JS_ASSERT(!STOBJ_IS_DELEGATE(obj));
|
||||
JS_ASSERT(!STOBJ_IS_SYSTEM(obj));
|
||||
|
||||
/* Set the proto and parent properties. */
|
||||
STOBJ_SET_PROTO(obj, proto);
|
||||
STOBJ_SET_PARENT(obj, parent);
|
||||
|
||||
/*
|
||||
* Set the class slot with the initial value of the system flag set to
|
||||
* false.
|
||||
*/
|
||||
JS_ASSERT(((jsuword) clasp & 3) == 0);
|
||||
STOBJ_SET_SLOT(obj, JSSLOT_CLASS, PRIVATE_TO_JSVAL(clasp));
|
||||
JS_ASSERT(!STOBJ_IS_SYSTEM(obj));
|
||||
|
||||
/* Initialize the remaining fixed slots. */
|
||||
for (i = JSSLOT_PRIVATE; i != JS_INITIAL_NSLOTS; ++i)
|
||||
obj->fslots[i] = JSVAL_VOID;
|
||||
|
@ -3026,6 +3027,9 @@ PurgeProtoChain(JSContext *cx, JSObject *obj, jsid id)
|
|||
static void
|
||||
PurgeScopeChain(JSContext *cx, JSObject *obj, jsid id)
|
||||
{
|
||||
if (!OBJ_IS_DELEGATE(cx, obj))
|
||||
return;
|
||||
|
||||
PurgeProtoChain(cx, OBJ_GET_PROTO(cx, obj), id);
|
||||
while ((obj = OBJ_GET_PARENT(cx, obj)) != NULL) {
|
||||
if (PurgeProtoChain(cx, obj, id))
|
||||
|
@ -3491,13 +3495,13 @@ js_FindPropertyHelper(JSContext *cx, jsid id, JSObject **objp,
|
|||
JSPropCacheEntry **entryp)
|
||||
{
|
||||
JSObject *obj, *pobj, *lastobj;
|
||||
uint32 type;
|
||||
uint32 shape;
|
||||
int scopeIndex, protoIndex;
|
||||
JSProperty *prop;
|
||||
JSScopeProperty *sprop;
|
||||
|
||||
obj = cx->fp->scopeChain;
|
||||
type = OBJ_SCOPE(obj)->shape;
|
||||
shape = OBJ_SHAPE(obj);
|
||||
for (scopeIndex = 0; ; scopeIndex++) {
|
||||
if (obj->map->ops->lookupProperty == js_LookupProperty) {
|
||||
protoIndex =
|
||||
|
@ -3512,7 +3516,7 @@ js_FindPropertyHelper(JSContext *cx, jsid id, JSObject **objp,
|
|||
if (entryp) {
|
||||
if (protoIndex >= 0 && OBJ_IS_NATIVE(pobj)) {
|
||||
sprop = (JSScopeProperty *) prop;
|
||||
js_FillPropertyCache(cx, cx->fp->scopeChain, type,
|
||||
js_FillPropertyCache(cx, cx->fp->scopeChain, shape,
|
||||
scopeIndex, protoIndex, pobj, sprop,
|
||||
entryp);
|
||||
} else {
|
||||
|
@ -3687,7 +3691,7 @@ JSBool
|
|||
js_GetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, jsval *vp,
|
||||
JSPropCacheEntry **entryp)
|
||||
{
|
||||
uint32 type;
|
||||
uint32 shape;
|
||||
int protoIndex;
|
||||
JSObject *obj2;
|
||||
JSProperty *prop;
|
||||
|
@ -3697,7 +3701,7 @@ js_GetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, jsval *vp,
|
|||
CHECK_FOR_STRING_INDEX(id);
|
||||
JS_COUNT_OPERATION(cx, JSOW_GET_PROPERTY);
|
||||
|
||||
type = OBJ_SCOPE(obj)->shape;
|
||||
shape = OBJ_SHAPE(obj);
|
||||
protoIndex = js_LookupPropertyWithFlags(cx, obj, id, 0, &obj2, &prop);
|
||||
if (protoIndex < 0)
|
||||
return JS_FALSE;
|
||||
|
@ -3767,10 +3771,8 @@ js_GetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, jsval *vp,
|
|||
if (!js_NativeGet(cx, obj, obj2, sprop, vp))
|
||||
return JS_FALSE;
|
||||
|
||||
if (entryp) {
|
||||
js_FillPropertyCache(cx, obj, type, 0, protoIndex, obj2, sprop,
|
||||
entryp);
|
||||
}
|
||||
if (entryp)
|
||||
js_FillPropertyCache(cx, obj, shape, 0, protoIndex, obj2, sprop, entryp);
|
||||
JS_UNLOCK_OBJ(cx, obj2);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
@ -3785,7 +3787,7 @@ JSBool
|
|||
js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, jsval *vp,
|
||||
JSPropCacheEntry **entryp)
|
||||
{
|
||||
uint32 type;
|
||||
uint32 shape;
|
||||
int protoIndex;
|
||||
JSObject *pobj;
|
||||
JSProperty *prop;
|
||||
|
@ -3800,7 +3802,7 @@ js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, jsval *vp,
|
|||
CHECK_FOR_STRING_INDEX(id);
|
||||
JS_COUNT_OPERATION(cx, JSOW_SET_PROPERTY);
|
||||
|
||||
type = OBJ_SCOPE(obj)->shape;
|
||||
shape = OBJ_SHAPE(obj);
|
||||
protoIndex = js_LookupPropertyWithFlags(cx, obj, id, 0, &pobj, &prop);
|
||||
if (protoIndex < 0)
|
||||
return JS_FALSE;
|
||||
|
@ -3868,16 +3870,7 @@ js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, jsval *vp,
|
|||
* NB: Thanks to the immutable, garbage-collected property tree
|
||||
* maintained by jsscope.c in cx->runtime, we needn't worry about
|
||||
* sprop going away behind our back after we've unlocked scope.
|
||||
*
|
||||
* But if we are shadowing (not sharing) the proto-property, then
|
||||
* we need to regenerate the property cache shape id for scope, in
|
||||
* case the cache contains the old type in an entry value that was
|
||||
* filled by a get on obj that delegated up the prototype chain to
|
||||
* pobj. Once we've shadowed the proto-property, that cache entry
|
||||
* must not be hit.
|
||||
*/
|
||||
if (!(attrs & JSPROP_SHARED))
|
||||
SCOPE_MAKE_UNIQUE_SHAPE(cx, scope);
|
||||
JS_UNLOCK_SCOPE(cx, scope);
|
||||
|
||||
/*
|
||||
|
@ -3979,7 +3972,7 @@ js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, jsval *vp,
|
|||
|
||||
if (entryp) {
|
||||
if (!(attrs & JSPROP_SHARED))
|
||||
js_FillPropertyCache(cx, obj, type, 0, 0, obj, sprop, entryp);
|
||||
js_FillPropertyCache(cx, obj, shape, 0, 0, obj, sprop, entryp);
|
||||
else
|
||||
PCMETER(JS_PROPERTY_CACHE(cx).nofills++);
|
||||
}
|
||||
|
|
|
@ -120,7 +120,7 @@ struct JSObjectMap {
|
|||
} \
|
||||
JS_END_MACRO
|
||||
|
||||
#define JS_INITIAL_NSLOTS 6
|
||||
#define JS_INITIAL_NSLOTS 5
|
||||
|
||||
/*
|
||||
* When JSObject.dslots is not null, JSObject.dslots[-1] records the number of
|
||||
|
@ -128,17 +128,17 @@ struct JSObjectMap {
|
|||
*/
|
||||
struct JSObject {
|
||||
JSObjectMap *map;
|
||||
jsuword classword;
|
||||
jsval fslots[JS_INITIAL_NSLOTS];
|
||||
jsval *dslots; /* dynamically allocated slots */
|
||||
};
|
||||
|
||||
#define JSSLOT_PROTO 0
|
||||
#define JSSLOT_PARENT 1
|
||||
#define JSSLOT_CLASS 2
|
||||
#define JSSLOT_PRIVATE 3
|
||||
#define JSSLOT_PRIVATE 2
|
||||
#define JSSLOT_START(clasp) (((clasp)->flags & JSCLASS_HAS_PRIVATE) \
|
||||
? JSSLOT_PRIVATE + 1 \
|
||||
: JSSLOT_CLASS + 1)
|
||||
: JSSLOT_PARENT + 1)
|
||||
|
||||
#define JSSLOT_FREE(clasp) (JSSLOT_START(clasp) \
|
||||
+ JSCLASS_RESERVED_SLOTS(clasp))
|
||||
|
@ -167,26 +167,29 @@ struct JSObject {
|
|||
#define STOBJ_GET_PROTO(obj) \
|
||||
JSVAL_TO_OBJECT((obj)->fslots[JSSLOT_PROTO])
|
||||
#define STOBJ_SET_PROTO(obj,proto) \
|
||||
((obj)->fslots[JSSLOT_PROTO] = OBJECT_TO_JSVAL(proto))
|
||||
(void)((!(proto) || STOBJ_SET_DELEGATE(proto)), \
|
||||
(obj)->fslots[JSSLOT_PROTO] = OBJECT_TO_JSVAL(proto))
|
||||
#define STOBJ_CLEAR_PROTO(obj) \
|
||||
((obj)->fslots[JSSLOT_PROTO] = JSVAL_NULL)
|
||||
|
||||
#define STOBJ_GET_PARENT(obj) \
|
||||
JSVAL_TO_OBJECT((obj)->fslots[JSSLOT_PARENT])
|
||||
#define STOBJ_SET_PARENT(obj,parent) \
|
||||
((obj)->fslots[JSSLOT_PARENT] = OBJECT_TO_JSVAL(parent))
|
||||
(void)((!(parent) || STOBJ_SET_DELEGATE(parent)), \
|
||||
(obj)->fslots[JSSLOT_PARENT] = OBJECT_TO_JSVAL(parent))
|
||||
#define STOBJ_CLEAR_PARENT(obj) \
|
||||
((obj)->fslots[JSSLOT_PARENT] = JSVAL_NULL)
|
||||
|
||||
/*
|
||||
* We use JSSLOT_CLASS to store both JSClass* and the system flag as an int-
|
||||
* tagged value (see jsapi.h for details) with the system flag stored in the
|
||||
* second lowest bit.
|
||||
* We use JSObject.classword to store both JSClass* and the delegate and system
|
||||
* flags in the two least significant bits. We do *not* synchronize updates of
|
||||
* obj->classword -- API clients must take care.
|
||||
*/
|
||||
#define STOBJ_GET_CLASS(obj) ((JSClass *)((obj)->fslots[JSSLOT_CLASS] & ~3))
|
||||
#define STOBJ_IS_SYSTEM(obj) (((obj)->fslots[JSSLOT_CLASS] & 2) != 0)
|
||||
|
||||
#define STOBJ_SET_SYSTEM(obj) ((void)((obj)->fslots[JSSLOT_CLASS] |= 2))
|
||||
#define STOBJ_GET_CLASS(obj) ((JSClass *)((obj)->classword & ~3))
|
||||
#define STOBJ_IS_DELEGATE(obj) (((obj)->classword & 1) != 0)
|
||||
#define STOBJ_SET_DELEGATE(obj) ((obj)->classword |= 1)
|
||||
#define STOBJ_IS_SYSTEM(obj) (((obj)->classword & 2) != 0)
|
||||
#define STOBJ_SET_SYSTEM(obj) ((obj)->classword |= 2)
|
||||
|
||||
#define STOBJ_GET_PRIVATE(obj) \
|
||||
(JS_ASSERT(JSVAL_IS_INT(STOBJ_GET_SLOT(obj, JSSLOT_PRIVATE))), \
|
||||
|
@ -227,7 +230,7 @@ struct JSObject {
|
|||
(OBJ_CHECK_SLOT(obj, JSSLOT_PARENT), STOBJ_SET_PARENT(obj, parent))
|
||||
|
||||
#define LOCKED_OBJ_GET_CLASS(obj) \
|
||||
(OBJ_CHECK_SLOT(obj, JSSLOT_CLASS), STOBJ_GET_CLASS(obj))
|
||||
STOBJ_GET_CLASS(obj)
|
||||
|
||||
#define LOCKED_OBJ_GET_PRIVATE(obj) \
|
||||
(OBJ_CHECK_SLOT(obj, JSSLOT_PRIVATE), STOBJ_GET_PRIVATE(obj))
|
||||
|
@ -276,7 +279,10 @@ struct JSObject {
|
|||
|
||||
#endif /* !JS_THREADSAFE */
|
||||
|
||||
/* Thread-safe proto, parent, and class access macros. */
|
||||
/* Thread-safe delegate, proto, parent, and class access macros. */
|
||||
#define OBJ_IS_DELEGATE(cx,obj) STOBJ_IS_DELEGATE(obj)
|
||||
#define OBJ_SET_DELEGATE(cx,obj) STOBJ_SET_DELEGATE(obj)
|
||||
|
||||
#define OBJ_GET_PROTO(cx,obj) STOBJ_GET_PROTO(obj)
|
||||
#define OBJ_SET_PROTO(cx,obj,proto) STOBJ_SET_PROTO(obj, proto)
|
||||
#define OBJ_CLEAR_PROTO(cx,obj) STOBJ_CLEAR_PROTO(obj)
|
||||
|
@ -286,7 +292,7 @@ struct JSObject {
|
|||
#define OBJ_CLEAR_PARENT(cx,obj) STOBJ_CLEAR_PARENT(obj)
|
||||
|
||||
/*
|
||||
* Class is invariant and comes from the fixed JSSLOT_CLASS. Thus no locking
|
||||
* Class is invariant and comes from the fixed clasp member. Thus no locking
|
||||
* is necessary to read it. Same for the private slot.
|
||||
*/
|
||||
#define OBJ_GET_CLASS(cx,obj) STOBJ_GET_CLASS(obj)
|
||||
|
|
|
@ -218,6 +218,7 @@ JS_STATIC_ASSERT(offsetof(JSScope, title) == sizeof(JSObjectMap));
|
|||
#define JS_IS_SCOPE_LOCKED(cx, scope) JS_IS_TITLE_LOCKED(cx, &(scope)->title)
|
||||
|
||||
#define OBJ_SCOPE(obj) ((JSScope *)(obj)->map)
|
||||
#define OBJ_SHAPE(obj) (OBJ_SCOPE(obj)->shape)
|
||||
|
||||
#define SCOPE_MAKE_UNIQUE_SHAPE(cx,scope) \
|
||||
((scope)->shape = js_GenerateShape((cx), JS_FALSE))
|
||||
|
|
|
@ -1314,7 +1314,7 @@ TraceRecorder::lazilyImportGlobalSlot(unsigned slot)
|
|||
unsigned index = traceMonitor->globalSlots->length();
|
||||
/* If this the first global we are adding, remember the shape of the global object. */
|
||||
if (index == 0)
|
||||
traceMonitor->globalShape = OBJ_SCOPE(JS_GetGlobalForObject(cx, cx->fp->scopeChain))->shape;
|
||||
traceMonitor->globalShape = OBJ_SHAPE(JS_GetGlobalForObject(cx, cx->fp->scopeChain));
|
||||
/* Add the slot to the list of interned global slots. */
|
||||
traceMonitor->globalSlots->add(slot);
|
||||
uint8 type = getCoercedType(*vp);
|
||||
|
@ -2008,7 +2008,7 @@ bool
|
|||
js_RecordTree(JSContext* cx, JSTraceMonitor* tm, Fragment* f)
|
||||
{
|
||||
/* Make sure the global type map didn't change on us. */
|
||||
uint32 globalShape = OBJ_SCOPE(JS_GetGlobalForObject(cx, cx->fp->scopeChain))->shape;
|
||||
uint32 globalShape = OBJ_SHAPE(JS_GetGlobalForObject(cx, cx->fp->scopeChain));
|
||||
if (tm->globalShape != globalShape) {
|
||||
debug_only_v(printf("Global shape mismatch (%u vs. %u) in RecordTree, flushing cache.\n",
|
||||
globalShape, tm->globalShape);)
|
||||
|
@ -2233,11 +2233,11 @@ js_ExecuteTree(JSContext* cx, Fragment** treep, uintN& inlineCallCount,
|
|||
the global type map must remain applicable at all times (we expect absolute type
|
||||
stability for globals). */
|
||||
if (ngslots &&
|
||||
(OBJ_SCOPE(globalObj)->shape != tm->globalShape ||
|
||||
(OBJ_SHAPE(globalObj) != tm->globalShape ||
|
||||
!BuildNativeGlobalFrame(cx, ngslots, gslots, tm->globalTypeMap->data(), global))) {
|
||||
AUDIT(globalShapeMismatchAtEntry);
|
||||
debug_only_v(printf("Global shape mismatch (%u vs. %u), flushing cache.\n",
|
||||
OBJ_SCOPE(globalObj)->shape, tm->globalShape);)
|
||||
OBJ_SHAPE(globalObj), tm->globalShape);)
|
||||
const void* ip = f->ip;
|
||||
js_FlushJITCache(cx);
|
||||
*treep = tm->fragmento->newLoop(ip);
|
||||
|
@ -2625,7 +2625,7 @@ js_FlushJITCache(JSContext* cx)
|
|||
}
|
||||
memset(&tm->fcache, 0, sizeof(tm->fcache));
|
||||
if (cx->fp) {
|
||||
tm->globalShape = OBJ_SCOPE(JS_GetGlobalForObject(cx, cx->fp->scopeChain))->shape;
|
||||
tm->globalShape = OBJ_SHAPE(JS_GetGlobalForObject(cx, cx->fp->scopeChain));
|
||||
tm->globalSlots->clear();
|
||||
tm->globalTypeMap->clear();
|
||||
}
|
||||
|
@ -3249,7 +3249,7 @@ TraceRecorder::test_property_cache(JSObject* obj, LIns* obj_ins, JSObject*& obj2
|
|||
ABORT_TRACE("failed to lookup property");
|
||||
|
||||
if (prop) {
|
||||
js_FillPropertyCache(cx, aobj, OBJ_SCOPE(aobj)->shape, 0, protoIndex, obj2,
|
||||
js_FillPropertyCache(cx, aobj, OBJ_SHAPE(aobj), 0, protoIndex, obj2,
|
||||
(JSScopeProperty*) prop, &entry);
|
||||
}
|
||||
}
|
||||
|
@ -3319,7 +3319,7 @@ TraceRecorder::test_property_cache(JSObject* obj, LIns* obj_ins, JSObject*& obj2
|
|||
if (PCVCAP_TAG(entry->vcap) >= 1) {
|
||||
jsuword vcap = entry->vcap;
|
||||
uint32 vshape = PCVCAP_SHAPE(vcap);
|
||||
JS_ASSERT(OBJ_SCOPE(obj2)->shape == vshape);
|
||||
JS_ASSERT(OBJ_SHAPE(obj2) == vshape);
|
||||
|
||||
LIns* obj2_ins = INS_CONSTPTR(obj2);
|
||||
map_ins = lir->insLoad(LIR_ldp, obj2_ins, (int)offsetof(JSObject, map));
|
||||
|
@ -3530,7 +3530,7 @@ TraceRecorder::guardClass(JSObject* obj, LIns* obj_ins, JSClass* clasp)
|
|||
if (STOBJ_GET_CLASS(obj) != clasp)
|
||||
return false;
|
||||
|
||||
LIns* class_ins = stobj_get_fslot(obj_ins, JSSLOT_CLASS);
|
||||
LIns* class_ins = lir->insLoad(LIR_ldp, obj_ins, offsetof(JSObject, classword));
|
||||
class_ins = lir->ins2(LIR_piand, class_ins, lir->insImm(~3));
|
||||
|
||||
char namebuf[32];
|
||||
|
@ -4263,7 +4263,7 @@ TraceRecorder::record_JSOP_SETPROP()
|
|||
LIns* obj_ins = get(&l);
|
||||
|
||||
JSPropertyCache* cache = &JS_PROPERTY_CACHE(cx);
|
||||
uint32 kshape = OBJ_SCOPE(obj)->shape;
|
||||
uint32 kshape = OBJ_SHAPE(obj);
|
||||
jsbytecode* pc = cx->fp->regs->pc;
|
||||
|
||||
JSPropCacheEntry* entry = &cache->table[PROPERTY_CACHE_HASH_PC(pc, kshape)];
|
||||
|
|
Загрузка…
Ссылка в новой задаче