зеркало из https://github.com/mozilla/gecko-dev.git
bug 538463 - caching only single-threaded objects. r=jorendorff
This commit is contained in:
Родитель
d7f5b53e87
Коммит
9d7785e018
|
@ -75,6 +75,7 @@
|
|||
#include "jsvector.h"
|
||||
|
||||
#include "jsatominlines.h"
|
||||
#include "jsinterpinlines.h"
|
||||
#include "jsobjinlines.h"
|
||||
#include "jsscopeinlines.h"
|
||||
#include "jsscriptinlines.h"
|
||||
|
@ -460,7 +461,7 @@ js_FullTestPropertyCache(JSContext *cx, jsbytecode *pc,
|
|||
--vcap;
|
||||
}
|
||||
|
||||
if (JS_LOCK_OBJ_IF_SHAPE(cx, pobj, PCVCAP_SHAPE(vcap))) {
|
||||
if (js_MatchPropertyCacheShape(cx, pobj, PCVCAP_SHAPE(vcap))) {
|
||||
#ifdef DEBUG
|
||||
jsid id = ATOM_TO_JSID(atom);
|
||||
|
||||
|
|
|
@ -368,6 +368,9 @@ typedef struct JSPropertyCache {
|
|||
#define PCVAL_TO_SPROP(v) ((JSScopeProperty *) PCVAL_CLRTAG(v))
|
||||
#define SPROP_TO_PCVAL(sprop) PCVAL_SETTAG(sprop, PCVAL_SPROP)
|
||||
|
||||
inline bool
|
||||
js_MatchPropertyCacheShape(JSContext *cx, JSObject *obj, uint32 shape);
|
||||
|
||||
/*
|
||||
* Fill property cache entry for key cx->fp->pc, optimized value word computed
|
||||
* from obj and sprop, and entry capability forged from 24-bit OBJ_SHAPE(obj),
|
||||
|
@ -414,7 +417,7 @@ js_FillPropertyCache(JSContext *cx, JSObject *obj,
|
|||
pobj = tmp_; \
|
||||
} \
|
||||
\
|
||||
if (JS_LOCK_OBJ_IF_SHAPE(cx, pobj, PCVCAP_SHAPE(entry->vcap))) { \
|
||||
if (js_MatchPropertyCacheShape(cx,pobj,PCVCAP_SHAPE(entry->vcap))){\
|
||||
PCMETER(cache_->pchits++); \
|
||||
PCMETER(!PCVCAP_TAG(entry->vcap) || cache_->protopchits++); \
|
||||
atom = NULL; \
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sw=4 et tw=99:
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code, released
|
||||
* March 31, 1998.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Igor Bukanov <igor@mir2.org>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef jsinterpinlines_h___
|
||||
#define jsinterpinlines_h___
|
||||
|
||||
#include "jsinterp.h"
|
||||
#include "jslock.h"
|
||||
#include "jsscope.h"
|
||||
|
||||
inline bool
|
||||
js_MatchPropertyCacheShape(JSContext *cx, JSObject *obj, uint32 shape)
|
||||
{
|
||||
return CX_OWNS_OBJECT_TITLE(cx, obj) && OBJ_SHAPE(obj) == shape;
|
||||
}
|
||||
|
||||
|
||||
#endif /* jsinterpinlines_h___ */
|
|
@ -1337,17 +1337,6 @@ js_UnlockObj(JSContext *cx, JSObject *obj)
|
|||
js_UnlockTitle(cx, &OBJ_SCOPE(obj)->title);
|
||||
}
|
||||
|
||||
bool
|
||||
js_LockObjIfShape(JSContext *cx, JSObject *obj, uint32 shape)
|
||||
{
|
||||
JS_ASSERT(OBJ_SCOPE(obj)->title.ownercx != cx);
|
||||
js_LockObj(cx, obj);
|
||||
if (OBJ_SHAPE(obj) == shape)
|
||||
return true;
|
||||
js_UnlockObj(cx, obj);
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
js_InitTitle(JSContext *cx, JSTitle *title)
|
||||
{
|
||||
|
|
|
@ -163,16 +163,6 @@ struct JSTitle {
|
|||
#define JS_UNLOCK_OBJ(cx,obj) (CX_OWNS_SCOPE_TITLE(cx, OBJ_SCOPE(obj)) \
|
||||
? (void)0 : js_UnlockObj(cx, obj))
|
||||
|
||||
/*
|
||||
* Lock object only if its scope has the given shape.
|
||||
*/
|
||||
#define JS_LOCK_OBJ_IF_SHAPE(cx,obj,shape) \
|
||||
(OBJ_SHAPE(obj) == (shape) \
|
||||
? (OBJ_SCOPE(obj)->title.ownercx == (cx) \
|
||||
? true \
|
||||
: js_LockObjIfShape(cx, obj, shape)) \
|
||||
: false)
|
||||
|
||||
#define JS_LOCK_TITLE(cx,title) \
|
||||
((title)->ownercx == (cx) ? (void)0 \
|
||||
: (js_LockTitle(cx, (title)), \
|
||||
|
@ -197,7 +187,6 @@ extern void js_LockRuntime(JSRuntime *rt);
|
|||
extern void js_UnlockRuntime(JSRuntime *rt);
|
||||
extern void js_LockObj(JSContext *cx, JSObject *obj);
|
||||
extern void js_UnlockObj(JSContext *cx, JSObject *obj);
|
||||
extern bool js_LockObjIfShape(JSContext *cx, JSObject *obj, uint32 shape);
|
||||
extern void js_InitTitle(JSContext *cx, JSTitle *title);
|
||||
extern void js_FinishTitle(JSContext *cx, JSTitle *title);
|
||||
extern void js_LockTitle(JSContext *cx, JSTitle *title);
|
||||
|
@ -267,9 +256,7 @@ extern void js_SetScopeInfo(JSScope *scope, const char *file, int line);
|
|||
#define CX_OWNS_SCOPE_TITLE(cx,obj) true
|
||||
#define JS_LOCK_OBJ(cx,obj) ((void)0)
|
||||
#define JS_UNLOCK_OBJ(cx,obj) ((void)0)
|
||||
#define JS_LOCK_OBJ_IF_SHAPE(cx,obj,shape) (OBJ_SHAPE(obj) == (shape))
|
||||
|
||||
#define JS_LOCK_OBJ_VOID(cx,obj,e) (e)
|
||||
#define JS_LOCK_SCOPE(cx,scope) ((void)0)
|
||||
#define JS_UNLOCK_SCOPE(cx,scope) ((void)0)
|
||||
#define JS_DROP_ALL_EMPTY_SCOPE_LOCKS(cx,scope) ((void)0)
|
||||
|
@ -295,6 +282,8 @@ extern void js_SetScopeInfo(JSScope *scope, const char *file, int line);
|
|||
JS_NO_TIMEOUT)
|
||||
#define JS_NOTIFY_REQUEST_DONE(rt) JS_NOTIFY_CONDVAR((rt)->requestDone)
|
||||
|
||||
#define CX_OWNS_OBJECT_TITLE(cx,obj) CX_OWNS_SCOPE_TITLE(cx, OBJ_SCOPE(obj))
|
||||
|
||||
#ifndef JS_SET_OBJ_INFO
|
||||
#define JS_SET_OBJ_INFO(obj,f,l) ((void)0)
|
||||
#endif
|
||||
|
|
|
@ -2868,7 +2868,7 @@ AllocSlots(JSContext *cx, JSObject *obj, size_t nslots);
|
|||
static inline bool
|
||||
InitScopeForObject(JSContext* cx, JSObject* obj, JSObject* proto, JSObjectOps* ops)
|
||||
{
|
||||
JS_ASSERT(OPS_IS_NATIVE(ops));
|
||||
JS_ASSERT(ops->isNative());
|
||||
JS_ASSERT(proto == OBJ_GET_PROTO(cx, obj));
|
||||
|
||||
/* Share proto's emptyScope only if obj is similar to proto. */
|
||||
|
@ -2959,7 +2959,7 @@ js_NewObjectWithGivenProto(JSContext *cx, JSClass *clasp, JSObject *proto,
|
|||
(!parent && proto) ? proto->getParent() : parent,
|
||||
JSObject::defaultPrivate(clasp));
|
||||
|
||||
if (OPS_IS_NATIVE(ops)) {
|
||||
if (ops->isNative()) {
|
||||
if (!InitScopeForObject(cx, obj, proto, ops)) {
|
||||
obj = NULL;
|
||||
goto out;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sw=4 et tw=78:
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
|
@ -163,8 +163,23 @@ struct JSObjectOps {
|
|||
JSHasInstanceOp hasInstance;
|
||||
JSTraceOp trace;
|
||||
JSFinalizeOp clear;
|
||||
|
||||
bool inline isNative() const;
|
||||
};
|
||||
|
||||
extern JS_FRIEND_DATA(JSObjectOps) js_ObjectOps;
|
||||
extern JS_FRIEND_DATA(JSObjectOps) js_WithObjectOps;
|
||||
|
||||
/*
|
||||
* Test whether the ops is native. FIXME bug 492938: consider how it would
|
||||
* affect the performance to do just the !objectMap check.
|
||||
*/
|
||||
inline bool
|
||||
JSObjectOps::isNative() const
|
||||
{
|
||||
return JS_LIKELY(this == &js_ObjectOps) || !objectMap;
|
||||
}
|
||||
|
||||
struct JSObjectMap {
|
||||
const JSObjectOps * const ops; /* high level object operation vtable */
|
||||
uint32 shape; /* shape identifier */
|
||||
|
@ -230,6 +245,8 @@ struct JSObject {
|
|||
jsval fslots[JS_INITIAL_NSLOTS]; /* small number of fixed slots */
|
||||
jsval *dslots; /* dynamically allocated slots */
|
||||
|
||||
bool isNative() const { return map->ops->isNative(); }
|
||||
|
||||
JSClass *getClass() const {
|
||||
return (JSClass *) (classword & ~JSSLOT_CLASS_MASK_BITS);
|
||||
}
|
||||
|
@ -415,6 +432,8 @@ struct JSObject {
|
|||
};
|
||||
|
||||
/* Compatibility macros. */
|
||||
#define OBJ_IS_NATIVE(obj) ((obj)->isNative())
|
||||
|
||||
#define STOBJ_GET_PROTO(obj) ((obj)->getProto())
|
||||
#define STOBJ_SET_PROTO(obj,proto) ((obj)->setProto(proto))
|
||||
#define STOBJ_CLEAR_PROTO(obj) ((obj)->clearProto())
|
||||
|
@ -482,7 +501,7 @@ STOBJ_GET_CLASS(const JSObject* obj)
|
|||
}
|
||||
|
||||
#define OBJ_CHECK_SLOT(obj,slot) \
|
||||
(JS_ASSERT(OBJ_IS_NATIVE(obj)), JS_ASSERT(slot < OBJ_SCOPE(obj)->freeslot))
|
||||
(JS_ASSERT(obj->isNative()), JS_ASSERT(slot < OBJ_SCOPE(obj)->freeslot))
|
||||
|
||||
#define LOCKED_OBJ_GET_SLOT(obj,slot) \
|
||||
(OBJ_CHECK_SLOT(obj, slot), STOBJ_GET_SLOT(obj, slot))
|
||||
|
@ -538,15 +557,6 @@ STOBJ_GET_CLASS(const JSObject* obj)
|
|||
*/
|
||||
#define OBJ_GET_CLASS(cx,obj) STOBJ_GET_CLASS(obj)
|
||||
|
||||
/*
|
||||
* Test whether the object is native. FIXME bug 492938: consider how it would
|
||||
* affect the performance to do just the !ops->objectMap check.
|
||||
*/
|
||||
#define OPS_IS_NATIVE(ops) \
|
||||
JS_LIKELY((ops) == &js_ObjectOps || !(ops)->objectMap)
|
||||
|
||||
#define OBJ_IS_NATIVE(obj) OPS_IS_NATIVE((obj)->map->ops)
|
||||
|
||||
#ifdef __cplusplus
|
||||
inline void
|
||||
OBJ_TO_INNER_OBJECT(JSContext *cx, JSObject *&obj)
|
||||
|
@ -575,8 +585,6 @@ OBJ_TO_OUTER_OBJECT(JSContext *cx, JSObject *&obj)
|
|||
}
|
||||
#endif
|
||||
|
||||
extern JS_FRIEND_DATA(JSObjectOps) js_ObjectOps;
|
||||
extern JS_FRIEND_DATA(JSObjectOps) js_WithObjectOps;
|
||||
extern JSClass js_ObjectClass;
|
||||
extern JSClass js_WithClass;
|
||||
extern JSClass js_BlockClass;
|
||||
|
|
|
@ -720,7 +720,6 @@ BEGIN_CASE(JSOP_BINDNAME)
|
|||
PROPERTY_CACHE_TEST(cx, regs.pc, obj, obj2, entry, atom);
|
||||
if (!atom) {
|
||||
ASSERT_VALID_PROPERTY_CACHE_HIT(0, obj, obj2, entry);
|
||||
JS_UNLOCK_OBJ(cx, obj2);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
|
@ -1268,13 +1267,11 @@ BEGIN_CASE(JSOP_NAMEDEC)
|
|||
if (!(js_CodeSpec[op].format & JOF_POST))
|
||||
rtmp = rval;
|
||||
LOCKED_OBJ_SET_SLOT(obj, slot, rval);
|
||||
JS_UNLOCK_OBJ(cx, obj);
|
||||
PUSH_OPND(rtmp);
|
||||
len = JSOP_INCNAME_LENGTH;
|
||||
DO_NEXT_OP(len);
|
||||
}
|
||||
}
|
||||
JS_UNLOCK_OBJ(cx, obj2);
|
||||
LOAD_ATOM(0);
|
||||
}
|
||||
} else {
|
||||
|
@ -1531,7 +1528,6 @@ BEGIN_CASE(JSOP_GETXPROP)
|
|||
fp->imacpc ? JSGET_NO_METHOD_BARRIER : JSGET_METHOD_BARRIER,
|
||||
&rval);
|
||||
}
|
||||
JS_UNLOCK_OBJ(cx, obj2);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
|
@ -1626,7 +1622,6 @@ BEGIN_CASE(JSOP_CALLPROP)
|
|||
sprop = PCVAL_TO_SPROP(entry->vword);
|
||||
NATIVE_GET(cx, obj, obj2, sprop, JSGET_NO_METHOD_BARRIER, &rval);
|
||||
}
|
||||
JS_UNLOCK_OBJ(cx, obj2);
|
||||
STORE_OPND(-1, rval);
|
||||
PUSH_OPND(lval);
|
||||
goto end_callprop;
|
||||
|
@ -1737,7 +1732,7 @@ BEGIN_CASE(JSOP_SETMETHOD)
|
|||
PCMETER(cache->settests++);
|
||||
if (entry->kpc == regs.pc && entry->kshape == kshape) {
|
||||
JS_ASSERT(PCVCAP_TAG(entry->vcap) <= 1);
|
||||
if (JS_LOCK_OBJ_IF_SHAPE(cx, obj, kshape)) {
|
||||
if (js_MatchPropertyCacheShape(cx, obj, kshape)) {
|
||||
JS_ASSERT(PCVAL_IS_SPROP(entry->vword));
|
||||
sprop = PCVAL_TO_SPROP(entry->vword);
|
||||
JS_ASSERT(!(sprop->attrs & JSPROP_READONLY));
|
||||
|
@ -1770,18 +1765,22 @@ BEGIN_CASE(JSOP_SETMETHOD)
|
|||
PCMETER(cache->pchits++);
|
||||
PCMETER(cache->setpchits++);
|
||||
NATIVE_SET(cx, obj, sprop, entry, &rval);
|
||||
JS_UNLOCK_SCOPE(cx, scope);
|
||||
break;
|
||||
}
|
||||
checkForAdd =
|
||||
!(sprop->attrs & JSPROP_SHARED) &&
|
||||
sprop->parent == scope->lastProperty();
|
||||
} else {
|
||||
/*
|
||||
* We check that cx own obj here and will continue to
|
||||
* own it after js_GetMutableScope returns so we can
|
||||
* continue to skip JS_UNLOCK_OBJ calls.
|
||||
*/
|
||||
JS_ASSERT(CX_OWNS_OBJECT_TITLE(cx, obj));
|
||||
scope = js_GetMutableScope(cx, obj);
|
||||
if (!scope) {
|
||||
JS_UNLOCK_OBJ(cx, obj);
|
||||
JS_ASSERT(CX_OWNS_OBJECT_TITLE(cx, obj));
|
||||
if (!scope)
|
||||
goto error;
|
||||
}
|
||||
checkForAdd = !sprop->parent;
|
||||
}
|
||||
|
||||
|
@ -1813,10 +1812,8 @@ BEGIN_CASE(JSOP_SETMETHOD)
|
|||
!OBJ_GET_CLASS(cx, obj)->reserveSlots) {
|
||||
++scope->freeslot;
|
||||
} else {
|
||||
if (!js_AllocSlot(cx, obj, &slot)) {
|
||||
JS_UNLOCK_SCOPE(cx, scope);
|
||||
if (!js_AllocSlot(cx, obj, &slot))
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1837,7 +1834,6 @@ BEGIN_CASE(JSOP_SETMETHOD)
|
|||
sprop->flags, sprop->shortid);
|
||||
if (!sprop2) {
|
||||
js_FreeSlot(cx, obj, slot);
|
||||
JS_UNLOCK_SCOPE(cx, scope);
|
||||
goto error;
|
||||
}
|
||||
sprop = sprop2;
|
||||
|
@ -1853,7 +1849,6 @@ BEGIN_CASE(JSOP_SETMETHOD)
|
|||
*/
|
||||
TRACE_2(SetPropHit, entry, sprop);
|
||||
LOCKED_OBJ_SET_SLOT(obj, slot, rval);
|
||||
JS_UNLOCK_SCOPE(cx, scope);
|
||||
|
||||
/*
|
||||
* Purge the property cache of the id we may have just
|
||||
|
@ -1863,7 +1858,6 @@ BEGIN_CASE(JSOP_SETMETHOD)
|
|||
js_PurgeScopeChain(cx, obj, sprop->id);
|
||||
break;
|
||||
}
|
||||
JS_UNLOCK_SCOPE(cx, scope);
|
||||
PCMETER(cache->setpcmisses++);
|
||||
}
|
||||
}
|
||||
|
@ -1883,7 +1877,6 @@ BEGIN_CASE(JSOP_SETMETHOD)
|
|||
JS_ASSERT(!OBJ_SCOPE(obj2)->sealed());
|
||||
NATIVE_SET(cx, obj, sprop, entry, &rval);
|
||||
}
|
||||
JS_UNLOCK_OBJ(cx, obj2);
|
||||
if (sprop)
|
||||
break;
|
||||
}
|
||||
|
@ -2332,7 +2325,6 @@ BEGIN_CASE(JSOP_CALLNAME)
|
|||
ASSERT_VALID_PROPERTY_CACHE_HIT(0, obj, obj2, entry);
|
||||
if (PCVAL_IS_OBJECT(entry->vword)) {
|
||||
rval = PCVAL_OBJECT_TO_JSVAL(entry->vword);
|
||||
JS_UNLOCK_OBJ(cx, obj2);
|
||||
goto do_push_rval;
|
||||
}
|
||||
|
||||
|
@ -2340,7 +2332,6 @@ BEGIN_CASE(JSOP_CALLNAME)
|
|||
slot = PCVAL_TO_SLOT(entry->vword);
|
||||
JS_ASSERT(slot < OBJ_SCOPE(obj2)->freeslot);
|
||||
rval = LOCKED_OBJ_GET_SLOT(obj2, slot);
|
||||
JS_UNLOCK_OBJ(cx, obj2);
|
||||
goto do_push_rval;
|
||||
}
|
||||
|
||||
|
@ -3367,6 +3358,13 @@ BEGIN_CASE(JSOP_NEWINIT)
|
|||
JS_UNLOCK_OBJ(cx, obj);
|
||||
goto error;
|
||||
}
|
||||
|
||||
/*
|
||||
* We cannot assume that js_GetMutableScope above creates a scope
|
||||
* owned by cx and skip JS_UNLOCK_SCOPE. A new object debugger
|
||||
* hook may add properties to the newly created object, suspend
|
||||
* the current request and share the object with other threads.
|
||||
*/
|
||||
JS_UNLOCK_SCOPE(cx, scope);
|
||||
}
|
||||
}
|
||||
|
@ -3395,14 +3393,19 @@ BEGIN_CASE(JSOP_INITMETHOD)
|
|||
JS_ASSERT(OBJ_IS_NATIVE(obj));
|
||||
JS_ASSERT(!OBJ_GET_CLASS(cx, obj)->reserveSlots);
|
||||
JS_ASSERT(!(obj->getClass()->flags & JSCLASS_SHARE_ALL_PROPERTIES));
|
||||
|
||||
do {
|
||||
JSScope *scope;
|
||||
uint32 kshape;
|
||||
JSPropertyCache *cache;
|
||||
JSPropCacheEntry *entry;
|
||||
|
||||
JS_LOCK_OBJ(cx, obj);
|
||||
/*
|
||||
* We can not assume that the object created by JSOP_NEWINIT is still
|
||||
* single-threaded as the debugger can access it from other threads.
|
||||
*/
|
||||
if (!CX_OWNS_OBJECT_TITLE(cx, obj))
|
||||
goto do_initprop_miss;
|
||||
|
||||
scope = OBJ_SCOPE(obj);
|
||||
JS_ASSERT(scope->object == obj);
|
||||
JS_ASSERT(!scope->sealed());
|
||||
|
@ -3455,10 +3458,8 @@ BEGIN_CASE(JSOP_INITMETHOD)
|
|||
if (slot < STOBJ_NSLOTS(obj)) {
|
||||
++scope->freeslot;
|
||||
} else {
|
||||
if (!js_AllocSlot(cx, obj, &slot)) {
|
||||
JS_UNLOCK_SCOPE(cx, scope);
|
||||
if (!js_AllocSlot(cx, obj, &slot))
|
||||
goto error;
|
||||
}
|
||||
JS_ASSERT(slot == sprop->slot);
|
||||
}
|
||||
|
||||
|
@ -3470,7 +3471,6 @@ BEGIN_CASE(JSOP_INITMETHOD)
|
|||
sprop->attrs, sprop->flags, sprop->shortid);
|
||||
if (!sprop2) {
|
||||
js_FreeSlot(cx, obj, slot);
|
||||
JS_UNLOCK_SCOPE(cx, scope);
|
||||
goto error;
|
||||
}
|
||||
JS_ASSERT(sprop2 == sprop);
|
||||
|
@ -3486,13 +3486,11 @@ BEGIN_CASE(JSOP_INITMETHOD)
|
|||
*/
|
||||
TRACE_2(SetPropHit, entry, sprop);
|
||||
LOCKED_OBJ_SET_SLOT(obj, slot, rval);
|
||||
JS_UNLOCK_SCOPE(cx, scope);
|
||||
break;
|
||||
}
|
||||
|
||||
do_initprop_miss:
|
||||
PCMETER(cache->inipcmisses++);
|
||||
JS_UNLOCK_SCOPE(cx, scope);
|
||||
|
||||
/* Get the immediate property name into id. */
|
||||
LOAD_ATOM(0);
|
||||
|
|
|
@ -208,7 +208,7 @@ JSScope *
|
|||
JSScope::create(JSContext *cx, const JSObjectOps *ops, JSClass *clasp,
|
||||
JSObject *obj, uint32 shape)
|
||||
{
|
||||
JS_ASSERT(OPS_IS_NATIVE(ops));
|
||||
JS_ASSERT(ops->isNative());
|
||||
JS_ASSERT(obj);
|
||||
|
||||
JSScope *scope = cx->create<JSScope>(ops, obj);
|
||||
|
|
|
@ -521,7 +521,7 @@ JS_IS_SCOPE_LOCKED(JSContext *cx, JSScope *scope)
|
|||
inline JSScope *
|
||||
OBJ_SCOPE(JSObject *obj)
|
||||
{
|
||||
JS_ASSERT(OBJ_IS_NATIVE(obj));
|
||||
JS_ASSERT(obj->isNative());
|
||||
return (JSScope *) obj->map;
|
||||
}
|
||||
|
||||
|
|
|
@ -78,6 +78,7 @@
|
|||
#include "jstypedarray.h"
|
||||
|
||||
#include "jsatominlines.h"
|
||||
#include "jsinterpinlines.h"
|
||||
#include "jsobjinlines.h"
|
||||
#include "jsscopeinlines.h"
|
||||
#include "jsscriptinlines.h"
|
||||
|
@ -9415,10 +9416,7 @@ TraceRecorder::test_property_cache(JSObject* obj, LIns* obj_ins, JSObject*& obj2
|
|||
JSAtom* atom;
|
||||
JSPropCacheEntry* entry;
|
||||
PROPERTY_CACHE_TEST(cx, pc, aobj, obj2, entry, atom);
|
||||
if (!atom) {
|
||||
// Null atom means that obj2 is locked and must now be unlocked.
|
||||
JS_UNLOCK_OBJ(cx, obj2);
|
||||
} else {
|
||||
if (atom) {
|
||||
// Miss: pre-fill the cache for the interpreter, as well as for our needs.
|
||||
jsid id = ATOM_TO_JSID(atom);
|
||||
JSProperty* prop;
|
||||
|
|
Загрузка…
Ссылка в новой задаче