1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * vim: set ts=8 sw=4 et tw=99:
4 * ***** BEGIN LICENSE BLOCK *****
5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
7 * The contents of this file are subject to the Mozilla Public License Version
8 * 1.1 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 * for the specific language governing rights and limitations under the
17 * The Original Code is Mozilla Communicator client code, released
20 * The Initial Developer of the Original Code is
21 * Mozilla Corporation.
22 * Portions created by the Initial Developer are Copyright (C) 2010
23 * the Initial Developer. All Rights Reserved.
26 * Igor Bukanov <igor@mir2.org>
28 * Alternatively, the contents of this file may be used under the terms of
29 * either of the GNU General Public License Version 2 or later (the "GPL"),
30 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
31 * in which case the provisions of the GPL or the LGPL are applicable instead
32 * of those above. If you wish to allow use of your version of this file only
33 * under the terms of either the GPL or the LGPL, and not to allow others to
34 * use your version of this file under the terms of the MPL, indicate your
35 * decision by deleting the provisions above and replace them with the notice
36 * and other provisions required by the GPL or the LGPL. If you do not delete
37 * the provisions above, a recipient may use your version of this file under
38 * the terms of any one of the MPL, the GPL or the LGPL.
40 * ***** END LICENSE BLOCK ***** */
42 #ifndef jspropertycacheinlines_h___
43 #define jspropertycacheinlines_h___
45 #include "jspropertycache.h"
50 /* static */ inline bool
51 PropertyCache::matchShape(JSContext
*cx
, JSObject
*obj
, uint32 shape
)
53 return CX_OWNS_OBJECT_TITLE(cx
, obj
) && obj
->shape() == shape
;
57 * This method is designed to inline the fast path in js_Interpret, so it makes
58 * "just-so" restrictions on parameters, e.g. pobj and obj should not be the
59 * same variable, since for JOF_PROP-mode opcodes, obj must not be changed
60 * because of a cache miss.
62 * On return, if atom is null then obj points to the scope chain element in
63 * which the property was found, pobj is locked, and entry is valid. If atom is
64 * non-null then no object is locked but entry is still set correctly for use,
65 * e.g., by PropertyCache::fill and atom should be used as the id to find.
67 * We must lock pobj on a hit in order to close races with threads that might
68 * be deleting a property from its scope, or otherwise invalidating property
69 * caches (on all threads) by re-generating scope->shape.
72 PropertyCache::test(JSContext
*cx
, jsbytecode
*pc
, JSObject
*&obj
,
73 JSObject
*&pobj
, PropertyCacheEntry
*&entry
, JSAtom
*&atom
)
75 JS_ASSERT(this == &JS_PROPERTY_CACHE(cx
));
77 uint32 kshape
= obj
->map
->shape
;
78 entry
= &table
[hash(pc
, kshape
)];
79 PCMETER(pctestentry
= entry
);
81 JS_ASSERT(&obj
!= &pobj
);
82 JS_ASSERT(entry
->kshape
< SHAPE_OVERFLOW_BIT
);
83 if (entry
->kpc
== pc
&& entry
->kshape
== kshape
) {
86 if (entry
->vcapTag() == 1 &&
87 (tmp
= pobj
->getProto()) != NULL
) {
91 if (matchShape(cx
, pobj
, entry
->vshape())) {
93 PCMETER(!entry
->vcapTag() || protopchits
++);
98 atom
= fullTest(cx
, pc
, &obj
, &pobj
, entry
);
103 JS_ALWAYS_INLINE
bool
104 PropertyCache::testForSet(JSContext
*cx
, jsbytecode
*pc
, JSObject
*obj
,
105 PropertyCacheEntry
**entryp
, JSObject
**obj2p
, JSAtom
**atomp
)
107 uint32 shape
= obj
->map
->shape
;
108 PropertyCacheEntry
*entry
= &table
[hash(pc
, shape
)];
110 PCMETER(pctestentry
= entry
);
113 JS_ASSERT(entry
->kshape
< SHAPE_OVERFLOW_BIT
);
114 if (entry
->kpc
== pc
&& entry
->kshape
== shape
&& matchShape(cx
, obj
, shape
))
118 JSObject
*orig
= obj
;
120 JSAtom
*atom
= fullTest(cx
, pc
, &obj
, obj2p
, entry
);
123 PCMETER(setmisses
++);
125 JS_ASSERT(obj
== orig
);
131 JS_ALWAYS_INLINE
bool
132 PropertyCache::testForInit(JSRuntime
*rt
, jsbytecode
*pc
, JSObject
*obj
, JSScope
*scope
,
133 JSScopeProperty
**spropp
, PropertyCacheEntry
**entryp
)
135 JS_ASSERT(scope
->object
== obj
);
136 JS_ASSERT(!scope
->sealed());
137 uint32 kshape
= scope
->shape
;
138 PropertyCacheEntry
*entry
= &table
[hash(pc
, kshape
)];
140 PCMETER(pctestentry
= entry
);
143 JS_ASSERT(entry
->kshape
< SHAPE_OVERFLOW_BIT
);
145 if (entry
->kpc
== pc
&&
146 entry
->kshape
== kshape
&&
147 entry
->vshape() == rt
->protoHazardShape
) {
149 PCMETER(inipchits
++);
150 JS_ASSERT(entry
->vcapTag() == 0);
151 *spropp
= entry
->vword
.toSprop();
152 JS_ASSERT((*spropp
)->writable());
158 #endif /* jspropertycacheinlines_h___ */