зеркало из https://github.com/mozilla/gecko-dev.git
Bug 713944 -Convert PropertyCacheEntry::vindex into two separate, private fields, and add some accessors for them. r=jorendorff
--HG-- extra : rebase_source : f7efae003a443e5381900b95273370ff3baa8a62
This commit is contained in:
Родитель
c57479bcc5
Коммит
893aa677a5
|
@ -3162,16 +3162,16 @@ BEGIN_CASE(JSOP_SETMETHOD)
|
|||
*/
|
||||
const Shape *shape = entry->prop;
|
||||
JS_ASSERT_IF(shape->isDataDescriptor(), shape->writable());
|
||||
JS_ASSERT_IF(shape->hasSlot(), !entry->vindex);
|
||||
JS_ASSERT_IF(shape->hasSlot(), entry->isOwnPropertyHit());
|
||||
|
||||
if (entry->vindex == 0 ||
|
||||
if (entry->isOwnPropertyHit() ||
|
||||
((obj2 = obj->getProto()) && obj2->lastProperty() == entry->pshape)) {
|
||||
#ifdef DEBUG
|
||||
if (entry->directHit()) {
|
||||
if (entry->isOwnPropertyHit()) {
|
||||
JS_ASSERT(obj->nativeContains(cx, *shape));
|
||||
} else {
|
||||
JS_ASSERT(obj2->nativeContains(cx, *shape));
|
||||
JS_ASSERT(entry->vindex == 1);
|
||||
JS_ASSERT(entry->isPrototypePropertyHit());
|
||||
JS_ASSERT(entry->kshape != entry->pshape);
|
||||
JS_ASSERT(!shape->hasSlot());
|
||||
}
|
||||
|
@ -4466,7 +4466,8 @@ BEGIN_CASE(JSOP_INITMETHOD)
|
|||
JSAtom *atom;
|
||||
if (JS_PROPERTY_CACHE(cx).testForSet(cx, regs.pc, obj, &entry, &obj2, &atom) &&
|
||||
entry->prop->hasDefaultSetter() &&
|
||||
entry->vindex == 0) {
|
||||
entry->isOwnPropertyHit())
|
||||
{
|
||||
JS_ASSERT(obj == obj2);
|
||||
/* Fast path. Property cache hit. */
|
||||
obj->nativeSetSlotWithType(cx, entry->prop, rval);
|
||||
|
|
|
@ -80,7 +80,7 @@ PropertyCache::fill(JSContext *cx, JSObject *obj, uintN scopeIndex, JSObject *po
|
|||
JS_ASSERT_IF(obj == pobj, scopeIndex == 0);
|
||||
|
||||
JSObject *tmp = obj;
|
||||
for (uintN i = 0; i != scopeIndex; i++)
|
||||
for (uintN i = 0; i < scopeIndex; i++)
|
||||
tmp = tmp->internalScopeChain();
|
||||
|
||||
uintN protoIndex = 0;
|
||||
|
@ -109,7 +109,8 @@ PropertyCache::fill(JSContext *cx, JSObject *obj, uintN scopeIndex, JSObject *po
|
|||
++protoIndex;
|
||||
}
|
||||
|
||||
if (scopeIndex > PCINDEX_SCOPEMASK || protoIndex > PCINDEX_PROTOMASK) {
|
||||
typedef PropertyCacheEntry Entry;
|
||||
if (scopeIndex > Entry::MaxScopeIndex || protoIndex > Entry::MaxProtoIndex) {
|
||||
PCMETER(longchains++);
|
||||
return JS_NO_PROP_CACHE_FILL;
|
||||
}
|
||||
|
@ -196,7 +197,6 @@ PropertyCache::fullTest(JSContext *cx, jsbytecode *pc, JSObject **objp, JSObject
|
|||
const JSCodeSpec &cs = js_CodeSpec[op];
|
||||
|
||||
obj = *objp;
|
||||
uint32_t vindex = entry->vindex;
|
||||
|
||||
if (entry->kpc != pc) {
|
||||
PCMETER(kpcmisses++);
|
||||
|
@ -234,23 +234,25 @@ PropertyCache::fullTest(JSContext *cx, jsbytecode *pc, JSObject **objp, JSObject
|
|||
pobj = obj;
|
||||
|
||||
if (JOF_MODE(cs.format) == JOF_NAME) {
|
||||
while (vindex & (PCINDEX_SCOPEMASK << PCINDEX_PROTOBITS)) {
|
||||
uint8_t scopeIndex = entry->scopeIndex;
|
||||
while (scopeIndex > 0) {
|
||||
tmp = pobj->scopeChain();
|
||||
if (!tmp || !tmp->isNative())
|
||||
break;
|
||||
pobj = tmp;
|
||||
vindex -= PCINDEX_PROTOSIZE;
|
||||
scopeIndex--;
|
||||
}
|
||||
|
||||
*objp = pobj;
|
||||
}
|
||||
|
||||
while (vindex & PCINDEX_PROTOMASK) {
|
||||
uint8_t protoIndex = entry->protoIndex;
|
||||
while (protoIndex > 0) {
|
||||
tmp = pobj->getProto();
|
||||
if (!tmp || !tmp->isNative())
|
||||
break;
|
||||
pobj = tmp;
|
||||
--vindex;
|
||||
protoIndex--;
|
||||
}
|
||||
|
||||
if (pobj->lastProperty() == entry->pshape) {
|
||||
|
@ -279,7 +281,8 @@ PropertyCache::assertEmpty()
|
|||
JS_ASSERT(!table[i].kshape);
|
||||
JS_ASSERT(!table[i].pshape);
|
||||
JS_ASSERT(!table[i].prop);
|
||||
JS_ASSERT(!table[i].vindex);
|
||||
JS_ASSERT(!table[i].scopeIndex);
|
||||
JS_ASSERT(!table[i].protoIndex);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -52,17 +52,7 @@ namespace js {
|
|||
* polymorphic callsite method/get/set speedups. For details, see
|
||||
* <https://developer.mozilla.org/en/SpiderMonkey/Internals/Property_cache>.
|
||||
*/
|
||||
|
||||
/* Indexing for property cache entry scope and prototype chain walking. */
|
||||
enum {
|
||||
PCINDEX_PROTOBITS = 4,
|
||||
PCINDEX_PROTOSIZE = JS_BIT(PCINDEX_PROTOBITS),
|
||||
PCINDEX_PROTOMASK = JS_BITMASK(PCINDEX_PROTOBITS),
|
||||
|
||||
PCINDEX_SCOPEBITS = 4,
|
||||
PCINDEX_SCOPESIZE = JS_BIT(PCINDEX_SCOPEBITS),
|
||||
PCINDEX_SCOPEMASK = JS_BITMASK(PCINDEX_SCOPEBITS)
|
||||
};
|
||||
class PropertyCache;
|
||||
|
||||
struct PropertyCacheEntry
|
||||
{
|
||||
|
@ -70,21 +60,50 @@ struct PropertyCacheEntry
|
|||
const Shape *kshape; /* shape of direct (key) object */
|
||||
const Shape *pshape; /* shape of owning object */
|
||||
const Shape *prop; /* shape of accessed property */
|
||||
uint16_t vindex; /* scope/proto chain indexing,
|
||||
* see PCINDEX above */
|
||||
|
||||
bool directHit() const { return vindex == 0; }
|
||||
friend class PropertyCache;
|
||||
|
||||
private:
|
||||
/* Index into scope chain; inapplicable to property lookup entries. */
|
||||
uint8_t scopeIndex;
|
||||
/* Index into the prototype chain from the object for this entry. */
|
||||
uint8_t protoIndex;
|
||||
|
||||
public:
|
||||
static const size_t MaxScopeIndex = 15;
|
||||
static const size_t MaxProtoIndex = 15;
|
||||
|
||||
/*
|
||||
* True iff the property lookup will find an own property on the object if
|
||||
* the entry matches.
|
||||
*
|
||||
* This test is applicable only to property lookups, not to identifier
|
||||
* lookups. It is meaningless to ask this question of an entry for an
|
||||
* identifier lookup.
|
||||
*/
|
||||
bool isOwnPropertyHit() const { return scopeIndex == 0 && protoIndex == 0; }
|
||||
|
||||
/*
|
||||
* True iff the property lookup will find the property on the prototype of
|
||||
* the object if the entry matches.
|
||||
*
|
||||
* This test is applicable only to property lookups, not to identifier
|
||||
* lookups. It is meaningless to ask this question of an entry for an
|
||||
* identifier lookup.
|
||||
*/
|
||||
bool isPrototypePropertyHit() const { return scopeIndex == 0 && protoIndex == 1; }
|
||||
|
||||
void assign(jsbytecode *kpc, const Shape *kshape, const Shape *pshape,
|
||||
const Shape *prop, uintN scopeIndex, uintN protoIndex) {
|
||||
JS_ASSERT(scopeIndex <= PCINDEX_SCOPEMASK);
|
||||
JS_ASSERT(protoIndex <= PCINDEX_PROTOMASK);
|
||||
JS_ASSERT(scopeIndex <= MaxScopeIndex);
|
||||
JS_ASSERT(protoIndex <= MaxProtoIndex);
|
||||
|
||||
this->kpc = kpc;
|
||||
this->kshape = kshape;
|
||||
this->pshape = pshape;
|
||||
this->prop = prop;
|
||||
this->vindex = (scopeIndex << PCINDEX_PROTOBITS) | protoIndex;
|
||||
this->scopeIndex = uint8_t(scopeIndex);
|
||||
this->protoIndex = uint8_t(protoIndex);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -77,14 +77,14 @@ PropertyCache::test(JSContext *cx, jsbytecode *pc, JSObject *&obj,
|
|||
if (entry->kpc == pc && entry->kshape == kshape) {
|
||||
JSObject *tmp;
|
||||
pobj = obj;
|
||||
if (entry->vindex == 1 &&
|
||||
if (entry->isPrototypePropertyHit() &&
|
||||
(tmp = pobj->getProto()) != NULL) {
|
||||
pobj = tmp;
|
||||
}
|
||||
|
||||
if (pobj->lastProperty() == entry->pshape) {
|
||||
PCMETER(pchits++);
|
||||
PCMETER(!entry->vindex || protopchits++);
|
||||
PCMETER(entry->isOwnPropertyHit() || protopchits++);
|
||||
atom = NULL;
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -169,16 +169,16 @@ stubs::SetName(VMFrame &f, JSAtom *origAtom)
|
|||
*/
|
||||
const Shape *shape = entry->prop;
|
||||
JS_ASSERT_IF(shape->isDataDescriptor(), shape->writable());
|
||||
JS_ASSERT_IF(shape->hasSlot(), !entry->vindex);
|
||||
JS_ASSERT_IF(shape->hasSlot(), entry->isOwnPropertyHit());
|
||||
|
||||
if (entry->vindex == 0 ||
|
||||
if (entry->isOwnPropertyHit() ||
|
||||
((obj2 = obj->getProto()) && obj2->lastProperty() == entry->pshape)) {
|
||||
#ifdef DEBUG
|
||||
if (entry->directHit()) {
|
||||
if (entry->isOwnPropertyHit()) {
|
||||
JS_ASSERT(obj->nativeContains(cx, *shape));
|
||||
} else {
|
||||
JS_ASSERT(obj2->nativeContains(cx, *shape));
|
||||
JS_ASSERT(entry->vindex == 1);
|
||||
JS_ASSERT(entry->isPrototypePropertyHit());
|
||||
JS_ASSERT(entry->kshape != entry->pshape);
|
||||
JS_ASSERT(!shape->hasSlot());
|
||||
}
|
||||
|
@ -1646,7 +1646,8 @@ InitPropOrMethod(VMFrame &f, JSAtom *atom, JSOp op)
|
|||
JSAtom *atom2;
|
||||
if (JS_PROPERTY_CACHE(cx).testForSet(cx, f.pc(), obj, &entry, &obj2, &atom2) &&
|
||||
entry->prop->hasDefaultSetter() &&
|
||||
entry->vindex == 0) {
|
||||
entry->isOwnPropertyHit())
|
||||
{
|
||||
JS_ASSERT(obj == obj2);
|
||||
/* Fast path. Property cache hit. */
|
||||
obj->nativeSetSlotWithType(cx, entry->prop, rval);
|
||||
|
|
Загрузка…
Ссылка в новой задаче