mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 906060 - Allow ExclusiveContext zones to have TI enabled, r=billm.
This commit is contained in:
parent
36d43a2d51
commit
3ea6fd69a7
@ -4497,8 +4497,7 @@ EmitFunc(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
*/
|
||||
if (fun->isInterpreted()) {
|
||||
bool singleton =
|
||||
cx->isJSContext() &&
|
||||
cx->asJSContext()->typeInferenceEnabled() &&
|
||||
cx->typeInferenceEnabled() &&
|
||||
bce->script->compileAndGo &&
|
||||
fun->isInterpreted() &&
|
||||
(bce->checkSingletonContext() ||
|
||||
|
@ -820,7 +820,7 @@ IonBuilder::initParameters()
|
||||
|
||||
types::StackTypeSet *thisTypes = types::TypeScript::ThisTypes(script());
|
||||
if (thisTypes->empty() && baselineFrame_)
|
||||
thisTypes->addType(cx, types::GetValueType(cx, baselineFrame_->thisValue()));
|
||||
thisTypes->addType(cx, types::GetValueType(baselineFrame_->thisValue()));
|
||||
|
||||
MParameter *param = MParameter::New(MParameter::THIS_SLOT, cloneTypeSet(thisTypes));
|
||||
current->add(param);
|
||||
@ -831,7 +831,7 @@ IonBuilder::initParameters()
|
||||
if (argTypes->empty() && baselineFrame_ &&
|
||||
!script_->baselineScript()->modifiesArguments())
|
||||
{
|
||||
argTypes->addType(cx, types::GetValueType(cx, baselineFrame_->argv()[i]));
|
||||
argTypes->addType(cx, types::GetValueType(baselineFrame_->argv()[i]));
|
||||
}
|
||||
|
||||
param = MParameter::New(i, cloneTypeSet(argTypes));
|
||||
@ -5773,7 +5773,7 @@ IonBuilder::newPendingLoopHeader(MBasicBlock *predecessor, jsbytecode *pc, bool
|
||||
MIRType type = existingValue.isDouble()
|
||||
? MIRType_Double
|
||||
: MIRTypeFromValueType(existingValue.extractNonDoubleType());
|
||||
types::Type ntype = types::GetValueType(cx, existingValue);
|
||||
types::Type ntype = types::GetValueType(existingValue);
|
||||
types::StackTypeSet *typeSet =
|
||||
GetIonContext()->temp->lifoAlloc()->new_<types::StackTypeSet>(ntype);
|
||||
phi->addBackedgeType(type, typeSet);
|
||||
@ -6363,7 +6363,7 @@ IonBuilder::jsop_intrinsic(HandlePropertyName name)
|
||||
if (!cx->global()->getIntrinsicValue(cx, name, &vp))
|
||||
return false;
|
||||
|
||||
JS_ASSERT(types->hasType(types::GetValueType(cx, vp)));
|
||||
JS_ASSERT(types->hasType(types::GetValueType(vp)));
|
||||
|
||||
MConstant *ins = MConstant::New(vp);
|
||||
current->add(ins);
|
||||
|
@ -2546,7 +2546,7 @@ ion::PropertyReadNeedsTypeBarrier(JSContext *cx, types::TypeObject *object, Prop
|
||||
if (HasDataProperty(cx, obj, id, &v)) {
|
||||
if (v.isUndefined())
|
||||
break;
|
||||
observed->addType(cx, types::GetValueType(cx, v));
|
||||
observed->addType(cx, types::GetValueType(v));
|
||||
}
|
||||
|
||||
obj = obj->getProto();
|
||||
|
@ -1075,7 +1075,7 @@ InitArrayTypes(JSContext *cx, TypeObject *type, const Value *vector, unsigned co
|
||||
for (unsigned i = 0; i < count; i++) {
|
||||
if (vector[i].isMagic(JS_ELEMENTS_HOLE))
|
||||
continue;
|
||||
Type valtype = GetValueType(cx, vector[i]);
|
||||
Type valtype = GetValueType(vector[i]);
|
||||
types->addType(cx, valtype);
|
||||
}
|
||||
}
|
||||
|
@ -259,10 +259,11 @@ struct ThreadSafeContext : ContextFriendFields,
|
||||
js_ReportAllocationOverflow(this);
|
||||
}
|
||||
|
||||
// Builtin atoms are immutable and may be accessed freely from any thread.
|
||||
// Accessors for immutable runtime data.
|
||||
JSAtomState &names() { return runtime_->atomState; }
|
||||
StaticStrings &staticStrings() { return runtime_->staticStrings; }
|
||||
PropertyName *emptyString() { return runtime_->emptyString; }
|
||||
FreeOp *defaultFreeOp() { return runtime_->defaultFreeOp(); }
|
||||
|
||||
// GCs cannot happen while non-main threads are running.
|
||||
uint64_t gcNumber() { return runtime_->gcNumber; }
|
||||
@ -351,6 +352,7 @@ class ExclusiveContext : public ThreadSafeContext
|
||||
// Zone local methods that can be used freely from an ExclusiveContext.
|
||||
inline bool typeInferenceEnabled() const;
|
||||
types::TypeObject *getNewType(Class *clasp, TaggedProto proto, JSFunction *fun = NULL);
|
||||
inline js::LifoAlloc &typeLifoAlloc();
|
||||
|
||||
// Current global. This is only safe to use within the scope of the
|
||||
// AutoCompartment from which it's called.
|
||||
@ -483,7 +485,6 @@ struct JSContext : public js::ExclusiveContext,
|
||||
|
||||
js::LifoAlloc &tempLifoAlloc() { return runtime()->tempLifoAlloc; }
|
||||
inline js::LifoAlloc &analysisLifoAlloc();
|
||||
inline js::LifoAlloc &typeLifoAlloc();
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
unsigned outstandingRequests;/* number of JS_BeginRequest calls
|
||||
|
@ -406,6 +406,12 @@ class AutoLockForExclusiveAccess
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
};
|
||||
|
||||
inline LifoAlloc &
|
||||
ExclusiveContext::typeLifoAlloc()
|
||||
{
|
||||
return zone()->types.typeLifoAlloc;
|
||||
}
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
inline js::LifoAlloc &
|
||||
@ -414,12 +420,6 @@ JSContext::analysisLifoAlloc()
|
||||
return compartment()->analysisLifoAlloc;
|
||||
}
|
||||
|
||||
inline js::LifoAlloc &
|
||||
JSContext::typeLifoAlloc()
|
||||
{
|
||||
return zone()->types.typeLifoAlloc;
|
||||
}
|
||||
|
||||
inline void
|
||||
JSContext::setPendingException(js::Value v) {
|
||||
JS_ASSERT(!IsPoisonedValue(v));
|
||||
|
@ -433,10 +433,6 @@ namespace js {
|
||||
inline bool
|
||||
ExclusiveContext::typeInferenceEnabled() const
|
||||
{
|
||||
// Type inference cannot be enabled in compartments which are accessed off
|
||||
// the main thread by an ExclusiveContext. TI data is stored in per-zone
|
||||
// allocators which could otherwise race with main thread operations.
|
||||
JS_ASSERT_IF(!isJSContext(), !compartment_->zone()->types.inferenceEnabled);
|
||||
return compartment_->zone()->types.inferenceEnabled;
|
||||
}
|
||||
|
||||
|
@ -4055,6 +4055,13 @@ AutoGCSession::AutoGCSession(JSRuntime *rt)
|
||||
runtime->gcInterFrameGC = true;
|
||||
|
||||
runtime->gcNumber++;
|
||||
|
||||
#ifdef DEBUG
|
||||
// Threads with an exclusive context should never pause while they are in
|
||||
// the middle of a suppressGC.
|
||||
for (ThreadDataIter iter(rt); !iter.done(); iter.next())
|
||||
JS_ASSERT(!iter->suppressGC);
|
||||
#endif
|
||||
}
|
||||
|
||||
AutoGCSession::~AutoGCSession()
|
||||
@ -4816,6 +4823,9 @@ gc::MergeCompartments(JSCompartment *source, JSCompartment *target)
|
||||
target->zone()->allocator.arenas.adoptArenas(rt, &source->zone()->allocator.arenas);
|
||||
target->zone()->gcBytes += source->zone()->gcBytes;
|
||||
source->zone()->gcBytes = 0;
|
||||
|
||||
// Merge other info in source's zone into target's zone.
|
||||
target->zone()->types.typeLifoAlloc.transferFrom(&source->zone()->types.typeLifoAlloc);
|
||||
}
|
||||
|
||||
void
|
||||
@ -5140,8 +5150,8 @@ AutoMaybeTouchDeadZones::~AutoMaybeTouchDeadZones()
|
||||
runtime->gcManipulatingDeadZones = manipulatingDeadZones;
|
||||
}
|
||||
|
||||
AutoSuppressGC::AutoSuppressGC(JSContext *cx)
|
||||
: suppressGC_(cx->runtime()->mainThread.suppressGC)
|
||||
AutoSuppressGC::AutoSuppressGC(ExclusiveContext *cx)
|
||||
: suppressGC_(cx->perThreadData->suppressGC)
|
||||
{
|
||||
suppressGC_++;
|
||||
}
|
||||
|
@ -1400,7 +1400,7 @@ class AutoSuppressGC
|
||||
int32_t &suppressGC_;
|
||||
|
||||
public:
|
||||
AutoSuppressGC(JSContext *cx);
|
||||
AutoSuppressGC(ExclusiveContext *cx);
|
||||
AutoSuppressGC(JSCompartment *comp);
|
||||
|
||||
~AutoSuppressGC()
|
||||
|
@ -47,6 +47,7 @@ using namespace js::types;
|
||||
using namespace js::analyze;
|
||||
|
||||
using mozilla::DebugOnly;
|
||||
using mozilla::Maybe;
|
||||
using mozilla::PodArrayZero;
|
||||
using mozilla::PodCopy;
|
||||
using mozilla::PodZero;
|
||||
@ -259,7 +260,7 @@ types::TypeHasProperty(JSContext *cx, TypeObject *obj, jsid id, const Value &val
|
||||
if (cx->compartment()->types.pendingCount)
|
||||
return true;
|
||||
|
||||
Type type = GetValueType(cx, value);
|
||||
Type type = GetValueType(value);
|
||||
|
||||
AutoEnterAnalysis enter(cx);
|
||||
|
||||
@ -268,7 +269,7 @@ types::TypeHasProperty(JSContext *cx, TypeObject *obj, jsid id, const Value &val
|
||||
* haven't yet been accessed during analysis of the inheriting object.
|
||||
* Don't do the property instantiation now.
|
||||
*/
|
||||
TypeSet *types = obj->maybeGetProperty(id, cx);
|
||||
TypeSet *types = obj->maybeGetProperty(cx, id);
|
||||
if (!types)
|
||||
return true;
|
||||
|
||||
@ -1127,7 +1128,7 @@ GetSingletonPropertyType(JSContext *cx, JSObject *rawObjArg, HandleId id)
|
||||
if (HasDataProperty(cx, obj, id, v.address())) {
|
||||
if (v.isUndefined())
|
||||
return Type::UnknownType();
|
||||
return GetValueType(cx, v);
|
||||
return GetValueType(v);
|
||||
}
|
||||
|
||||
obj = obj->getProto();
|
||||
@ -1838,23 +1839,27 @@ HeapTypeSet::HasObjectFlags(JSContext *cx, TypeObject *object, TypeObjectFlags f
|
||||
}
|
||||
|
||||
static inline void
|
||||
ObjectStateChange(JSContext *cx, TypeObject *object, bool markingUnknown, bool force)
|
||||
ObjectStateChange(ExclusiveContext *cxArg, TypeObject *object, bool markingUnknown, bool force)
|
||||
{
|
||||
if (object->unknownProperties())
|
||||
return;
|
||||
|
||||
/* All constraints listening to state changes are on the empty id. */
|
||||
TypeSet *types = object->maybeGetProperty(JSID_EMPTY, cx);
|
||||
TypeSet *types = object->maybeGetProperty(cxArg, JSID_EMPTY);
|
||||
|
||||
/* Mark as unknown after getting the types, to avoid assertion. */
|
||||
if (markingUnknown)
|
||||
object->flags |= OBJECT_FLAG_DYNAMIC_MASK | OBJECT_FLAG_UNKNOWN_PROPERTIES;
|
||||
|
||||
if (types) {
|
||||
TypeConstraint *constraint = types->constraintList;
|
||||
while (constraint) {
|
||||
constraint->newObjectState(cx, object, force);
|
||||
constraint = constraint->next;
|
||||
if (JSContext *cx = cxArg->maybeJSContext()) {
|
||||
TypeConstraint *constraint = types->constraintList;
|
||||
while (constraint) {
|
||||
constraint->newObjectState(cx, object, force);
|
||||
constraint = constraint->next;
|
||||
}
|
||||
} else {
|
||||
JS_ASSERT(!types->constraintList);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2192,7 +2197,7 @@ StackTypeSet::propertyNeedsBarrier(JSContext *cx, jsid id)
|
||||
if (otype->unknownProperties())
|
||||
return true;
|
||||
|
||||
if (types::HeapTypeSet *propTypes = otype->maybeGetProperty(typeId, cx)) {
|
||||
if (types::HeapTypeSet *propTypes = otype->maybeGetProperty(cx, typeId)) {
|
||||
if (propTypes->needsBarrier(cx))
|
||||
return true;
|
||||
}
|
||||
@ -2612,7 +2617,7 @@ TypeCompartment::processPendingRecompiles(FreeOp *fop)
|
||||
}
|
||||
|
||||
void
|
||||
TypeCompartment::setPendingNukeTypes(JSContext *cx)
|
||||
TypeCompartment::setPendingNukeTypes(ExclusiveContext *cx)
|
||||
{
|
||||
TypeZone *zone = &compartment()->zone()->types;
|
||||
if (!zone->pendingNukeTypes) {
|
||||
@ -3030,9 +3035,9 @@ NumberTypes(Type a, Type b)
|
||||
* arrays and objects whose type can be fixed.
|
||||
*/
|
||||
static inline Type
|
||||
GetValueTypeForTable(JSContext *cx, const Value &v)
|
||||
GetValueTypeForTable(const Value &v)
|
||||
{
|
||||
Type type = GetValueType(cx, v);
|
||||
Type type = GetValueType(v);
|
||||
JS_ASSERT(!type.isSingleObject());
|
||||
return type;
|
||||
}
|
||||
@ -3058,7 +3063,8 @@ struct types::ArrayTableKey
|
||||
};
|
||||
|
||||
void
|
||||
TypeCompartment::setTypeToHomogenousArray(JSContext *cx, JSObject *obj, Type elementType)
|
||||
TypeCompartment::setTypeToHomogenousArray(ExclusiveContext *cx,
|
||||
JSObject *obj, Type elementType)
|
||||
{
|
||||
if (!arrayTypeTable) {
|
||||
arrayTypeTable = cx->new_<ArrayTypeTable>();
|
||||
@ -3097,7 +3103,7 @@ TypeCompartment::setTypeToHomogenousArray(JSContext *cx, JSObject *obj, Type ele
|
||||
}
|
||||
|
||||
void
|
||||
TypeCompartment::fixArrayType(JSContext *cx, JSObject *obj)
|
||||
TypeCompartment::fixArrayType(ExclusiveContext *cx, JSObject *obj)
|
||||
{
|
||||
AutoEnterAnalysis enter(cx);
|
||||
|
||||
@ -3113,10 +3119,10 @@ TypeCompartment::fixArrayType(JSContext *cx, JSObject *obj)
|
||||
if (len == 0)
|
||||
return;
|
||||
|
||||
Type type = GetValueTypeForTable(cx, obj->getDenseElement(0));
|
||||
Type type = GetValueTypeForTable(obj->getDenseElement(0));
|
||||
|
||||
for (unsigned i = 1; i < len; i++) {
|
||||
Type ntype = GetValueTypeForTable(cx, obj->getDenseElement(i));
|
||||
Type ntype = GetValueTypeForTable(obj->getDenseElement(i));
|
||||
if (ntype != type) {
|
||||
if (NumberTypes(type, ntype))
|
||||
type = Type::DoubleType();
|
||||
@ -3129,17 +3135,14 @@ TypeCompartment::fixArrayType(JSContext *cx, JSObject *obj)
|
||||
}
|
||||
|
||||
void
|
||||
types::FixRestArgumentsType(ExclusiveContext *cxArg, JSObject *obj)
|
||||
types::FixRestArgumentsType(ExclusiveContext *cx, JSObject *obj)
|
||||
{
|
||||
if (cxArg->isJSContext()) {
|
||||
JSContext *cx = cxArg->asJSContext();
|
||||
if (cx->typeInferenceEnabled())
|
||||
cx->compartment()->types.fixRestArgumentsType(cx, obj);
|
||||
}
|
||||
if (cx->typeInferenceEnabled())
|
||||
cx->compartment()->types.fixRestArgumentsType(cx, obj);
|
||||
}
|
||||
|
||||
void
|
||||
TypeCompartment::fixRestArgumentsType(JSContext *cx, JSObject *obj)
|
||||
TypeCompartment::fixRestArgumentsType(ExclusiveContext *cx, JSObject *obj)
|
||||
{
|
||||
AutoEnterAnalysis enter(cx);
|
||||
|
||||
@ -3199,14 +3202,14 @@ struct types::ObjectTableEntry
|
||||
};
|
||||
|
||||
static inline void
|
||||
UpdateObjectTableEntryTypes(JSContext *cx, ObjectTableEntry &entry,
|
||||
UpdateObjectTableEntryTypes(ExclusiveContext *cx, ObjectTableEntry &entry,
|
||||
IdValuePair *properties, size_t nproperties)
|
||||
{
|
||||
if (entry.object->unknownProperties())
|
||||
return;
|
||||
for (size_t i = 0; i < nproperties; i++) {
|
||||
Type type = entry.types[i];
|
||||
Type ntype = GetValueTypeForTable(cx, properties[i].value);
|
||||
Type ntype = GetValueTypeForTable(properties[i].value);
|
||||
if (ntype == type)
|
||||
continue;
|
||||
if (ntype.isPrimitive(JSVAL_TYPE_INT32) &&
|
||||
@ -3226,7 +3229,7 @@ UpdateObjectTableEntryTypes(JSContext *cx, ObjectTableEntry &entry,
|
||||
}
|
||||
|
||||
void
|
||||
TypeCompartment::fixObjectType(JSContext *cx, JSObject *obj)
|
||||
TypeCompartment::fixObjectType(ExclusiveContext *cx, JSObject *obj)
|
||||
{
|
||||
AutoEnterAnalysis enter(cx);
|
||||
|
||||
@ -3299,7 +3302,7 @@ TypeCompartment::fixObjectType(JSContext *cx, JSObject *obj)
|
||||
|
||||
for (size_t i = 0; i < properties.length(); i++) {
|
||||
ids[i] = properties[i].id;
|
||||
types[i] = GetValueTypeForTable(cx, obj->getSlot(i));
|
||||
types[i] = GetValueTypeForTable(obj->getSlot(i));
|
||||
if (!objType->unknownProperties())
|
||||
objType->addPropertyType(cx, IdToTypeId(ids[i]), types[i]);
|
||||
}
|
||||
@ -3427,7 +3430,7 @@ TypeObject::getFromPrototypes(JSContext *cx, jsid id, TypeSet *types, bool force
|
||||
}
|
||||
|
||||
static inline void
|
||||
UpdatePropertyType(JSContext *cx, TypeSet *types, JSObject *obj, Shape *shape,
|
||||
UpdatePropertyType(ExclusiveContext *cx, TypeSet *types, JSObject *obj, Shape *shape,
|
||||
bool force)
|
||||
{
|
||||
types->setOwnProperty(cx, false);
|
||||
@ -3445,14 +3448,14 @@ UpdatePropertyType(JSContext *cx, TypeSet *types, JSObject *obj, Shape *shape,
|
||||
* not collated into the JSID_VOID property (see propertySet comment).
|
||||
*/
|
||||
if (force || !value.isUndefined()) {
|
||||
Type type = GetValueType(cx, value);
|
||||
Type type = GetValueType(value);
|
||||
types->addType(cx, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
TypeObject::addProperty(JSContext *cx, jsid id, Property **pprop)
|
||||
TypeObject::addProperty(ExclusiveContext *cx, jsid id, Property **pprop)
|
||||
{
|
||||
JS_ASSERT(!*pprop);
|
||||
Property *base = cx->typeLifoAlloc().new_<Property>(id);
|
||||
@ -3483,7 +3486,7 @@ TypeObject::addProperty(JSContext *cx, jsid id, Property **pprop)
|
||||
for (size_t i = 0; i < singleton->getDenseInitializedLength(); i++) {
|
||||
const Value &value = singleton->getDenseElement(i);
|
||||
if (!value.isMagic(JS_ELEMENTS_HOLE)) {
|
||||
Type type = GetValueType(cx, value);
|
||||
Type type = GetValueType(value);
|
||||
base->types.setOwnProperty(cx, false);
|
||||
base->types.addType(cx, type);
|
||||
}
|
||||
@ -3514,7 +3517,7 @@ TypeObject::addProperty(JSContext *cx, jsid id, Property **pprop)
|
||||
}
|
||||
|
||||
bool
|
||||
TypeObject::addDefiniteProperties(JSContext *cx, JSObject *obj)
|
||||
TypeObject::addDefiniteProperties(ExclusiveContext *cx, JSObject *obj)
|
||||
{
|
||||
if (unknownProperties())
|
||||
return true;
|
||||
@ -3567,7 +3570,7 @@ TypeObject::matchDefiniteProperties(HandleObject obj)
|
||||
}
|
||||
|
||||
inline void
|
||||
InlineAddTypeProperty(JSContext *cx, TypeObject *obj, jsid id, Type type)
|
||||
InlineAddTypeProperty(ExclusiveContext *cx, TypeObject *obj, jsid id, Type type)
|
||||
{
|
||||
JS_ASSERT(id == IdToTypeId(id));
|
||||
|
||||
@ -3583,19 +3586,19 @@ InlineAddTypeProperty(JSContext *cx, TypeObject *obj, jsid id, Type type)
|
||||
}
|
||||
|
||||
void
|
||||
TypeObject::addPropertyType(JSContext *cx, jsid id, Type type)
|
||||
TypeObject::addPropertyType(ExclusiveContext *cx, jsid id, Type type)
|
||||
{
|
||||
InlineAddTypeProperty(cx, this, id, type);
|
||||
}
|
||||
|
||||
void
|
||||
TypeObject::addPropertyType(JSContext *cx, jsid id, const Value &value)
|
||||
TypeObject::addPropertyType(ExclusiveContext *cx, jsid id, const Value &value)
|
||||
{
|
||||
InlineAddTypeProperty(cx, this, id, GetValueType(cx, value));
|
||||
InlineAddTypeProperty(cx, this, id, GetValueType(value));
|
||||
}
|
||||
|
||||
void
|
||||
TypeObject::addPropertyType(JSContext *cx, const char *name, Type type)
|
||||
TypeObject::addPropertyType(ExclusiveContext *cx, const char *name, Type type)
|
||||
{
|
||||
jsid id = JSID_VOID;
|
||||
if (name) {
|
||||
@ -3611,13 +3614,13 @@ TypeObject::addPropertyType(JSContext *cx, const char *name, Type type)
|
||||
}
|
||||
|
||||
void
|
||||
TypeObject::addPropertyType(JSContext *cx, const char *name, const Value &value)
|
||||
TypeObject::addPropertyType(ExclusiveContext *cx, const char *name, const Value &value)
|
||||
{
|
||||
addPropertyType(cx, name, GetValueType(cx, value));
|
||||
addPropertyType(cx, name, GetValueType(value));
|
||||
}
|
||||
|
||||
void
|
||||
TypeObject::markPropertyConfigured(JSContext *cx, jsid id)
|
||||
TypeObject::markPropertyConfigured(ExclusiveContext *cx, jsid id)
|
||||
{
|
||||
AutoEnterAnalysis enter(cx);
|
||||
|
||||
@ -3629,24 +3632,28 @@ TypeObject::markPropertyConfigured(JSContext *cx, jsid id)
|
||||
}
|
||||
|
||||
void
|
||||
TypeObject::markStateChange(JSContext *cx)
|
||||
TypeObject::markStateChange(ExclusiveContext *cxArg)
|
||||
{
|
||||
if (unknownProperties())
|
||||
return;
|
||||
|
||||
AutoEnterAnalysis enter(cx);
|
||||
TypeSet *types = maybeGetProperty(JSID_EMPTY, cx);
|
||||
AutoEnterAnalysis enter(cxArg);
|
||||
TypeSet *types = maybeGetProperty(cxArg, JSID_EMPTY);
|
||||
if (types) {
|
||||
TypeConstraint *constraint = types->constraintList;
|
||||
while (constraint) {
|
||||
constraint->newObjectState(cx, this, true);
|
||||
constraint = constraint->next;
|
||||
if (JSContext *cx = cxArg->maybeJSContext()) {
|
||||
TypeConstraint *constraint = types->constraintList;
|
||||
while (constraint) {
|
||||
constraint->newObjectState(cx, this, true);
|
||||
constraint = constraint->next;
|
||||
}
|
||||
} else {
|
||||
JS_ASSERT(!types->constraintList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TypeObject::setFlags(JSContext *cx, TypeObjectFlags flags)
|
||||
TypeObject::setFlags(ExclusiveContext *cx, TypeObjectFlags flags)
|
||||
{
|
||||
if ((this->flags & flags) == flags)
|
||||
return;
|
||||
@ -3667,7 +3674,7 @@ TypeObject::setFlags(JSContext *cx, TypeObjectFlags flags)
|
||||
}
|
||||
|
||||
void
|
||||
TypeObject::markUnknown(JSContext *cx)
|
||||
TypeObject::markUnknown(ExclusiveContext *cx)
|
||||
{
|
||||
AutoEnterAnalysis enter(cx);
|
||||
|
||||
@ -3701,7 +3708,7 @@ TypeObject::markUnknown(JSContext *cx)
|
||||
}
|
||||
|
||||
void
|
||||
TypeObject::clearNewScript(JSContext *cx)
|
||||
TypeObject::clearNewScript(ExclusiveContext *cx)
|
||||
{
|
||||
JS_ASSERT(!(flags & OBJECT_FLAG_NEW_SCRIPT_CLEARED));
|
||||
flags |= OBJECT_FLAG_NEW_SCRIPT_CLEARED;
|
||||
@ -3744,69 +3751,74 @@ TypeObject::clearNewScript(JSContext *cx)
|
||||
* script keeps track of where each property is initialized so we can walk
|
||||
* the stack and fix up any such objects.
|
||||
*/
|
||||
Vector<uint32_t, 32> pcOffsets(cx);
|
||||
for (ScriptFrameIter iter(cx); !iter.done(); ++iter) {
|
||||
pcOffsets.append(uint32_t(iter.pc() - iter.script()->code));
|
||||
if (iter.isConstructing() &&
|
||||
iter.callee() == newScript->fun &&
|
||||
iter.thisv().isObject() &&
|
||||
!iter.thisv().toObject().hasLazyType() &&
|
||||
iter.thisv().toObject().type() == this)
|
||||
{
|
||||
RootedObject obj(cx, &iter.thisv().toObject());
|
||||
if (cx->isJSContext()) {
|
||||
Vector<uint32_t, 32> pcOffsets(cx);
|
||||
for (ScriptFrameIter iter(cx->asJSContext()); !iter.done(); ++iter) {
|
||||
pcOffsets.append(uint32_t(iter.pc() - iter.script()->code));
|
||||
if (iter.isConstructing() &&
|
||||
iter.callee() == newScript->fun &&
|
||||
iter.thisv().isObject() &&
|
||||
!iter.thisv().toObject().hasLazyType() &&
|
||||
iter.thisv().toObject().type() == this)
|
||||
{
|
||||
RootedObject obj(cx, &iter.thisv().toObject());
|
||||
|
||||
/* Whether all identified 'new' properties have been initialized. */
|
||||
bool finished = false;
|
||||
/* Whether all identified 'new' properties have been initialized. */
|
||||
bool finished = false;
|
||||
|
||||
/* If not finished, number of properties that have been added. */
|
||||
uint32_t numProperties = 0;
|
||||
/* If not finished, number of properties that have been added. */
|
||||
uint32_t numProperties = 0;
|
||||
|
||||
/*
|
||||
* If non-zero, we are scanning initializers in a call which has
|
||||
* already finished.
|
||||
*/
|
||||
size_t depth = 0;
|
||||
size_t callDepth = pcOffsets.length() - 1;
|
||||
uint32_t offset = pcOffsets[callDepth];
|
||||
/*
|
||||
* If non-zero, we are scanning initializers in a call which has
|
||||
* already finished.
|
||||
*/
|
||||
size_t depth = 0;
|
||||
size_t callDepth = pcOffsets.length() - 1;
|
||||
uint32_t offset = pcOffsets[callDepth];
|
||||
|
||||
for (TypeNewScript::Initializer *init = newScript->initializerList;; init++) {
|
||||
if (init->kind == TypeNewScript::Initializer::SETPROP) {
|
||||
if (!depth && init->offset > offset) {
|
||||
/* Advanced past all properties which have been initialized. */
|
||||
break;
|
||||
}
|
||||
numProperties++;
|
||||
} else if (init->kind == TypeNewScript::Initializer::FRAME_PUSH) {
|
||||
if (depth) {
|
||||
depth++;
|
||||
} else if (init->offset > offset) {
|
||||
/* Advanced past all properties which have been initialized. */
|
||||
break;
|
||||
} else if (init->offset == offset) {
|
||||
if (!callDepth)
|
||||
for (TypeNewScript::Initializer *init = newScript->initializerList;; init++) {
|
||||
if (init->kind == TypeNewScript::Initializer::SETPROP) {
|
||||
if (!depth && init->offset > offset) {
|
||||
/* Advanced past all properties which have been initialized. */
|
||||
break;
|
||||
offset = pcOffsets[--callDepth];
|
||||
}
|
||||
numProperties++;
|
||||
} else if (init->kind == TypeNewScript::Initializer::FRAME_PUSH) {
|
||||
if (depth) {
|
||||
depth++;
|
||||
} else if (init->offset > offset) {
|
||||
/* Advanced past all properties which have been initialized. */
|
||||
break;
|
||||
} else if (init->offset == offset) {
|
||||
if (!callDepth)
|
||||
break;
|
||||
offset = pcOffsets[--callDepth];
|
||||
} else {
|
||||
/* This call has already finished. */
|
||||
depth = 1;
|
||||
}
|
||||
} else if (init->kind == TypeNewScript::Initializer::FRAME_POP) {
|
||||
if (depth) {
|
||||
depth--;
|
||||
} else {
|
||||
/* This call has not finished yet. */
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* This call has already finished. */
|
||||
depth = 1;
|
||||
}
|
||||
} else if (init->kind == TypeNewScript::Initializer::FRAME_POP) {
|
||||
if (depth) {
|
||||
depth--;
|
||||
} else {
|
||||
/* This call has not finished yet. */
|
||||
JS_ASSERT(init->kind == TypeNewScript::Initializer::DONE);
|
||||
finished = true;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
JS_ASSERT(init->kind == TypeNewScript::Initializer::DONE);
|
||||
finished = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!finished)
|
||||
obj->rollbackProperties(cx, numProperties);
|
||||
if (!finished)
|
||||
obj->rollbackProperties(cx, numProperties);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Threads with an ExclusiveContext are not allowed to run scripts.
|
||||
JS_ASSERT(!cx->perThreadData->activation());
|
||||
}
|
||||
|
||||
/* We NULL out newScript *before* freeing it so the write barrier works. */
|
||||
@ -5029,7 +5041,7 @@ AnalyzePoppedThis(JSContext *cx, SSAUseChain *use,
|
||||
if (shape && shape->hasSlot()) {
|
||||
Value protov = type->proto->getSlot(shape->slot());
|
||||
TypeSet *types = TypeScript::BytecodeTypes(script, pc);
|
||||
types->addType(cx, GetValueType(cx, protov));
|
||||
types->addType(cx, GetValueType(protov));
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -5530,7 +5542,7 @@ types::TypeMonitorResult(JSContext *cx, JSScript *script, jsbytecode *pc, const
|
||||
return;
|
||||
}
|
||||
|
||||
Type type = GetValueType(cx, rval);
|
||||
Type type = GetValueType(rval);
|
||||
TypeSet *types = TypeScript::BytecodeTypes(script, pc);
|
||||
if (types->hasType(type))
|
||||
return;
|
||||
@ -5804,14 +5816,12 @@ JSScript::makeAnalysis(JSContext *cx)
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
JSFunction::setTypeForScriptedFunction(ExclusiveContext *cxArg, HandleFunction fun,
|
||||
JSFunction::setTypeForScriptedFunction(ExclusiveContext *cx, HandleFunction fun,
|
||||
bool singleton /* = false */)
|
||||
{
|
||||
if (!cxArg->typeInferenceEnabled())
|
||||
if (!cx->typeInferenceEnabled())
|
||||
return true;
|
||||
|
||||
JSContext *cx = cxArg->asJSContext();
|
||||
|
||||
if (singleton) {
|
||||
if (!setSingletonType(cx, fun))
|
||||
return false;
|
||||
@ -6051,7 +6061,7 @@ ExclusiveContext::getNewType(Class *clasp, TaggedProto proto_, JSFunction *fun_)
|
||||
* 'prototype' property of some scripted function.
|
||||
*/
|
||||
if (type->newScript && type->newScript->fun != fun_)
|
||||
type->clearNewScript(asJSContext());
|
||||
type->clearNewScript(this);
|
||||
|
||||
return type;
|
||||
}
|
||||
@ -6077,8 +6087,7 @@ ExclusiveContext::getNewType(Class *clasp, TaggedProto proto_, JSFunction *fun_)
|
||||
if (!typeInferenceEnabled())
|
||||
return type;
|
||||
|
||||
JSContext *cx = asJSContext();
|
||||
AutoEnterAnalysis enter(cx);
|
||||
AutoEnterAnalysis enter(this);
|
||||
|
||||
/*
|
||||
* Set the special equality flag for types whose prototype also has the
|
||||
@ -6086,22 +6095,22 @@ ExclusiveContext::getNewType(Class *clasp, TaggedProto proto_, JSFunction *fun_)
|
||||
* types and the possible js::Class of objects with that type.
|
||||
*/
|
||||
if (proto.isObject()) {
|
||||
RootedObject obj(cx, proto.toObject());
|
||||
RootedObject obj(this, proto.toObject());
|
||||
|
||||
if (fun)
|
||||
CheckNewScriptProperties(cx, type, fun);
|
||||
CheckNewScriptProperties(asJSContext(), type, fun);
|
||||
|
||||
if (obj->is<RegExpObject>()) {
|
||||
AddTypeProperty(cx, type, "source", types::Type::StringType());
|
||||
AddTypeProperty(cx, type, "global", types::Type::BooleanType());
|
||||
AddTypeProperty(cx, type, "ignoreCase", types::Type::BooleanType());
|
||||
AddTypeProperty(cx, type, "multiline", types::Type::BooleanType());
|
||||
AddTypeProperty(cx, type, "sticky", types::Type::BooleanType());
|
||||
AddTypeProperty(cx, type, "lastIndex", types::Type::Int32Type());
|
||||
AddTypeProperty(this, type, "source", types::Type::StringType());
|
||||
AddTypeProperty(this, type, "global", types::Type::BooleanType());
|
||||
AddTypeProperty(this, type, "ignoreCase", types::Type::BooleanType());
|
||||
AddTypeProperty(this, type, "multiline", types::Type::BooleanType());
|
||||
AddTypeProperty(this, type, "sticky", types::Type::BooleanType());
|
||||
AddTypeProperty(this, type, "lastIndex", types::Type::Int32Type());
|
||||
}
|
||||
|
||||
if (obj->is<StringObject>())
|
||||
AddTypeProperty(cx, type, "length", Type::Int32Type());
|
||||
AddTypeProperty(this, type, "length", Type::Int32Type());
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -204,7 +204,7 @@ class Type
|
||||
};
|
||||
|
||||
/* Get the type of a jsval, or zero for an unknown special value. */
|
||||
inline Type GetValueType(JSContext *cx, const Value &val);
|
||||
inline Type GetValueType(const Value &val);
|
||||
|
||||
/*
|
||||
* Type inference memory management overview.
|
||||
@ -489,10 +489,10 @@ class TypeSet
|
||||
* Add a type to this set, calling any constraint handlers if this is a new
|
||||
* possible type.
|
||||
*/
|
||||
inline void addType(JSContext *cx, Type type);
|
||||
inline void addType(ExclusiveContext *cx, Type type);
|
||||
|
||||
/* Mark this type set as representing an own property or configured property. */
|
||||
inline void setOwnProperty(JSContext *cx, bool configured);
|
||||
inline void setOwnProperty(ExclusiveContext *cx, bool configured);
|
||||
|
||||
/*
|
||||
* Add an object to this set using the specified allocator, without
|
||||
@ -1040,10 +1040,10 @@ struct TypeObject : gc::Cell
|
||||
* assignment, and the own types of the property will be used instead of
|
||||
* aggregate types.
|
||||
*/
|
||||
inline HeapTypeSet *getProperty(JSContext *cx, jsid id, bool own);
|
||||
inline HeapTypeSet *getProperty(ExclusiveContext *cx, jsid id, bool own);
|
||||
|
||||
/* Get a property only if it already exists. */
|
||||
inline HeapTypeSet *maybeGetProperty(jsid id, JSContext *cx);
|
||||
inline HeapTypeSet *maybeGetProperty(ExclusiveContext *cx, jsid id);
|
||||
|
||||
inline unsigned getPropertyCount();
|
||||
inline Property *getProperty(unsigned i);
|
||||
@ -1056,19 +1056,19 @@ struct TypeObject : gc::Cell
|
||||
|
||||
/* Helpers */
|
||||
|
||||
bool addProperty(JSContext *cx, jsid id, Property **pprop);
|
||||
bool addDefiniteProperties(JSContext *cx, JSObject *obj);
|
||||
bool addProperty(ExclusiveContext *cx, jsid id, Property **pprop);
|
||||
bool addDefiniteProperties(ExclusiveContext *cx, JSObject *obj);
|
||||
bool matchDefiniteProperties(HandleObject obj);
|
||||
void addPrototype(JSContext *cx, TypeObject *proto);
|
||||
void addPropertyType(JSContext *cx, jsid id, Type type);
|
||||
void addPropertyType(JSContext *cx, jsid id, const Value &value);
|
||||
void addPropertyType(JSContext *cx, const char *name, Type type);
|
||||
void addPropertyType(JSContext *cx, const char *name, const Value &value);
|
||||
void markPropertyConfigured(JSContext *cx, jsid id);
|
||||
void markStateChange(JSContext *cx);
|
||||
void setFlags(JSContext *cx, TypeObjectFlags flags);
|
||||
void markUnknown(JSContext *cx);
|
||||
void clearNewScript(JSContext *cx);
|
||||
void addPropertyType(ExclusiveContext *cx, jsid id, Type type);
|
||||
void addPropertyType(ExclusiveContext *cx, jsid id, const Value &value);
|
||||
void addPropertyType(ExclusiveContext *cx, const char *name, Type type);
|
||||
void addPropertyType(ExclusiveContext *cx, const char *name, const Value &value);
|
||||
void markPropertyConfigured(ExclusiveContext *cx, jsid id);
|
||||
void markStateChange(ExclusiveContext *cx);
|
||||
void setFlags(ExclusiveContext *cx, TypeObjectFlags flags);
|
||||
void markUnknown(ExclusiveContext *cx);
|
||||
void clearNewScript(ExclusiveContext *cx);
|
||||
void getFromPrototypes(JSContext *cx, jsid id, TypeSet *types, bool force = false);
|
||||
|
||||
void print();
|
||||
@ -1368,12 +1368,12 @@ struct TypeCompartment
|
||||
ObjectTypeTable *objectTypeTable;
|
||||
|
||||
private:
|
||||
void setTypeToHomogenousArray(JSContext *cx, JSObject *obj, Type type);
|
||||
void setTypeToHomogenousArray(ExclusiveContext *cx, JSObject *obj, Type type);
|
||||
|
||||
public:
|
||||
void fixArrayType(JSContext *cx, JSObject *obj);
|
||||
void fixObjectType(JSContext *cx, JSObject *obj);
|
||||
void fixRestArgumentsType(JSContext *cx, JSObject *obj);
|
||||
void fixArrayType(ExclusiveContext *cx, JSObject *obj);
|
||||
void fixObjectType(ExclusiveContext *cx, JSObject *obj);
|
||||
void fixRestArgumentsType(ExclusiveContext *cx, JSObject *obj);
|
||||
|
||||
JSObject *newTypedObject(JSContext *cx, IdValuePair *properties, size_t nproperties);
|
||||
|
||||
@ -1414,7 +1414,7 @@ struct TypeCompartment
|
||||
void processPendingRecompiles(FreeOp *fop);
|
||||
|
||||
/* Mark all types as needing destruction once inference has 'finished'. */
|
||||
void setPendingNukeTypes(JSContext *cx);
|
||||
void setPendingNukeTypes(ExclusiveContext *cx);
|
||||
|
||||
/* Mark a script as needing recompilation once inference has finished. */
|
||||
void addPendingRecompile(JSContext *cx, const RecompileInfo &info);
|
||||
|
@ -185,9 +185,8 @@ Type::ObjectType(TypeObjectKey *obj)
|
||||
}
|
||||
|
||||
inline Type
|
||||
GetValueType(JSContext *cx, const Value &val)
|
||||
GetValueType(const Value &val)
|
||||
{
|
||||
JS_ASSERT(cx->typeInferenceEnabled());
|
||||
if (val.isDouble())
|
||||
return Type::DoubleType();
|
||||
if (val.isObject())
|
||||
@ -310,10 +309,10 @@ struct AutoEnterAnalysis
|
||||
JSCompartment *compartment;
|
||||
bool oldActiveAnalysis;
|
||||
|
||||
AutoEnterAnalysis(JSContext *cx)
|
||||
AutoEnterAnalysis(ExclusiveContext *cx)
|
||||
: suppressGC(cx)
|
||||
{
|
||||
init(cx->runtime()->defaultFreeOp(), cx->compartment());
|
||||
init(cx->defaultFreeOp(), cx->compartment());
|
||||
}
|
||||
|
||||
AutoEnterAnalysis(FreeOp *fop, JSCompartment *comp)
|
||||
@ -535,7 +534,7 @@ TrackPropertyTypes(ExclusiveContext *cx, JSObject *obj, jsid id)
|
||||
if (!cx->typeInferenceEnabled() || obj->hasLazyType() || obj->type()->unknownProperties())
|
||||
return false;
|
||||
|
||||
if (obj->hasSingletonType() && !obj->type()->maybeGetProperty(id, cx->asJSContext()))
|
||||
if (obj->hasSingletonType() && !obj->type()->maybeGetProperty(cx, id))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@ -566,7 +565,7 @@ AddTypePropertyId(ExclusiveContext *cx, JSObject *obj, jsid id, Type type)
|
||||
if (cx->typeInferenceEnabled()) {
|
||||
id = IdToTypeId(id);
|
||||
if (TrackPropertyTypes(cx, obj, id))
|
||||
obj->type()->addPropertyType(cx->asJSContext(), id, type);
|
||||
obj->type()->addPropertyType(cx, id, type);
|
||||
}
|
||||
}
|
||||
|
||||
@ -576,19 +575,19 @@ AddTypePropertyId(ExclusiveContext *cx, JSObject *obj, jsid id, const Value &val
|
||||
if (cx->typeInferenceEnabled()) {
|
||||
id = IdToTypeId(id);
|
||||
if (TrackPropertyTypes(cx, obj, id))
|
||||
obj->type()->addPropertyType(cx->asJSContext(), id, value);
|
||||
obj->type()->addPropertyType(cx, id, value);
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
AddTypeProperty(JSContext *cx, TypeObject *obj, const char *name, Type type)
|
||||
AddTypeProperty(ExclusiveContext *cx, TypeObject *obj, const char *name, Type type)
|
||||
{
|
||||
if (cx->typeInferenceEnabled() && !obj->unknownProperties())
|
||||
obj->addPropertyType(cx, name, type);
|
||||
}
|
||||
|
||||
inline void
|
||||
AddTypeProperty(JSContext *cx, TypeObject *obj, const char *name, const Value &value)
|
||||
AddTypeProperty(ExclusiveContext *cx, TypeObject *obj, const char *name, const Value &value)
|
||||
{
|
||||
if (cx->typeInferenceEnabled() && !obj->unknownProperties())
|
||||
obj->addPropertyType(cx, name, value);
|
||||
@ -599,7 +598,7 @@ inline void
|
||||
MarkTypeObjectFlags(ExclusiveContext *cx, JSObject *obj, TypeObjectFlags flags)
|
||||
{
|
||||
if (cx->typeInferenceEnabled() && !obj->hasLazyType() && !obj->type()->hasAllFlags(flags))
|
||||
obj->type()->setFlags(cx->asJSContext(), flags);
|
||||
obj->type()->setFlags(cx, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -630,7 +629,7 @@ MarkTypePropertyConfigured(ExclusiveContext *cx, HandleObject obj, jsid id)
|
||||
if (cx->typeInferenceEnabled()) {
|
||||
id = IdToTypeId(id);
|
||||
if (TrackPropertyTypes(cx, obj, id))
|
||||
obj->type()->markPropertyConfigured(cx->asJSContext(), id);
|
||||
obj->type()->markPropertyConfigured(cx, id);
|
||||
}
|
||||
}
|
||||
|
||||
@ -639,7 +638,7 @@ inline void
|
||||
MarkObjectStateChange(ExclusiveContext *cx, JSObject *obj)
|
||||
{
|
||||
if (cx->typeInferenceEnabled() && !obj->hasLazyType() && !obj->type()->unknownProperties())
|
||||
obj->type()->markStateChange(cx->asJSContext());
|
||||
obj->type()->markStateChange(cx);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -648,23 +647,17 @@ MarkObjectStateChange(ExclusiveContext *cx, JSObject *obj)
|
||||
*/
|
||||
|
||||
inline void
|
||||
FixArrayType(ExclusiveContext *cxArg, HandleObject obj)
|
||||
FixArrayType(ExclusiveContext *cx, HandleObject obj)
|
||||
{
|
||||
if (cxArg->isJSContext()) {
|
||||
JSContext *cx = cxArg->asJSContext();
|
||||
if (cx->typeInferenceEnabled())
|
||||
cx->compartment()->types.fixArrayType(cx, obj);
|
||||
}
|
||||
if (cx->typeInferenceEnabled())
|
||||
cx->compartment()->types.fixArrayType(cx, obj);
|
||||
}
|
||||
|
||||
inline void
|
||||
FixObjectType(ExclusiveContext *cxArg, HandleObject obj)
|
||||
FixObjectType(ExclusiveContext *cx, HandleObject obj)
|
||||
{
|
||||
if (cxArg->isJSContext()) {
|
||||
JSContext *cx = cxArg->asJSContext();
|
||||
if (cx->typeInferenceEnabled())
|
||||
cx->compartment()->types.fixObjectType(cx, obj);
|
||||
}
|
||||
if (cx->typeInferenceEnabled())
|
||||
cx->compartment()->types.fixObjectType(cx, obj);
|
||||
}
|
||||
|
||||
/* Interface helpers for JSScript*. */
|
||||
@ -970,7 +963,7 @@ TypeScript::SetThis(JSContext *cx, JSScript *script, Type type)
|
||||
TypeScript::SetThis(JSContext *cx, JSScript *script, const js::Value &value)
|
||||
{
|
||||
if (cx->typeInferenceEnabled())
|
||||
SetThis(cx, script, GetValueType(cx, value));
|
||||
SetThis(cx, script, GetValueType(value));
|
||||
}
|
||||
|
||||
/* static */ inline void
|
||||
@ -992,7 +985,7 @@ TypeScript::SetArgument(JSContext *cx, JSScript *script, unsigned arg, Type type
|
||||
TypeScript::SetArgument(JSContext *cx, JSScript *script, unsigned arg, const js::Value &value)
|
||||
{
|
||||
if (cx->typeInferenceEnabled()) {
|
||||
Type type = GetValueType(cx, value);
|
||||
Type type = GetValueType(value);
|
||||
SetArgument(cx, script, arg, type);
|
||||
}
|
||||
}
|
||||
@ -1280,9 +1273,9 @@ TypeSet::clearObjects()
|
||||
}
|
||||
|
||||
inline void
|
||||
TypeSet::addType(JSContext *cx, Type type)
|
||||
TypeSet::addType(ExclusiveContext *cxArg, Type type)
|
||||
{
|
||||
JS_ASSERT(cx->compartment()->activeAnalysis);
|
||||
JS_ASSERT(cxArg->compartment()->activeAnalysis);
|
||||
|
||||
if (unknown())
|
||||
return;
|
||||
@ -1308,14 +1301,14 @@ TypeSet::addType(JSContext *cx, Type type)
|
||||
goto unknownObject;
|
||||
|
||||
LifoAlloc &alloc =
|
||||
purged() ? cx->compartment()->analysisLifoAlloc : cx->typeLifoAlloc();
|
||||
purged() ? cxArg->compartment()->analysisLifoAlloc : cxArg->typeLifoAlloc();
|
||||
|
||||
uint32_t objectCount = baseObjectCount();
|
||||
TypeObjectKey *object = type.objectKey();
|
||||
TypeObjectKey **pentry = HashSetInsert<TypeObjectKey *,TypeObjectKey,TypeObjectKey>
|
||||
(alloc, objectSet, objectCount, object);
|
||||
if (!pentry) {
|
||||
cx->compartment()->types.setPendingNukeTypes(cx);
|
||||
cxArg->compartment()->types.setPendingNukeTypes(cxArg);
|
||||
return;
|
||||
}
|
||||
if (*pentry)
|
||||
@ -1347,17 +1340,20 @@ TypeSet::addType(JSContext *cx, Type type)
|
||||
TypeString(type));
|
||||
|
||||
/* Propagate the type to all constraints. */
|
||||
TypeConstraint *constraint = constraintList;
|
||||
while (constraint) {
|
||||
cx->compartment()->types.addPending(cx, constraint, this, type);
|
||||
constraint = constraint->next;
|
||||
if (JSContext *cx = cxArg->maybeJSContext()) {
|
||||
TypeConstraint *constraint = constraintList;
|
||||
while (constraint) {
|
||||
cx->compartment()->types.addPending(cx, constraint, this, type);
|
||||
constraint = constraint->next;
|
||||
}
|
||||
cx->compartment()->types.resolvePending(cx);
|
||||
} else {
|
||||
JS_ASSERT(!constraintList);
|
||||
}
|
||||
|
||||
cx->compartment()->types.resolvePending(cx);
|
||||
}
|
||||
|
||||
inline void
|
||||
TypeSet::setOwnProperty(JSContext *cx, bool configured)
|
||||
TypeSet::setOwnProperty(ExclusiveContext *cxArg, bool configured)
|
||||
{
|
||||
TypeFlags nflags = TYPE_FLAG_OWN_PROPERTY | (configured ? TYPE_FLAG_CONFIGURED_PROPERTY : 0);
|
||||
|
||||
@ -1367,10 +1363,14 @@ TypeSet::setOwnProperty(JSContext *cx, bool configured)
|
||||
flags |= nflags;
|
||||
|
||||
/* Propagate the change to all constraints. */
|
||||
TypeConstraint *constraint = constraintList;
|
||||
while (constraint) {
|
||||
constraint->newPropertyState(cx, this);
|
||||
constraint = constraint->next;
|
||||
if (JSContext *cx = cxArg->maybeJSContext()) {
|
||||
TypeConstraint *constraint = constraintList;
|
||||
while (constraint) {
|
||||
constraint->newPropertyState(cx, this);
|
||||
constraint = constraint->next;
|
||||
}
|
||||
} else {
|
||||
JS_ASSERT(!constraintList);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1476,7 +1476,7 @@ TypeObject::setBasePropertyCount(uint32_t count)
|
||||
}
|
||||
|
||||
inline HeapTypeSet *
|
||||
TypeObject::getProperty(JSContext *cx, jsid id, bool own)
|
||||
TypeObject::getProperty(ExclusiveContext *cx, jsid id, bool own)
|
||||
{
|
||||
JS_ASSERT(cx->compartment()->activeAnalysis);
|
||||
|
||||
@ -1524,7 +1524,7 @@ TypeObject::getProperty(JSContext *cx, jsid id, bool own)
|
||||
}
|
||||
|
||||
inline HeapTypeSet *
|
||||
TypeObject::maybeGetProperty(jsid id, JSContext *cx)
|
||||
TypeObject::maybeGetProperty(ExclusiveContext *cx, jsid id)
|
||||
{
|
||||
JS_ASSERT(JSID_IS_VOID(id) || JSID_IS_EMPTY(id) || JSID_IS_STRING(id));
|
||||
JS_ASSERT_IF(!JSID_IS_EMPTY(id), id == IdToTypeId(id));
|
||||
|
@ -377,7 +377,7 @@ class JSObject : public js::ObjectImpl
|
||||
inline void prepareSlotRangeForOverwrite(size_t start, size_t end);
|
||||
inline void prepareElementRangeForOverwrite(size_t start, size_t end);
|
||||
|
||||
void rollbackProperties(JSContext *cx, uint32_t slotSpan);
|
||||
void rollbackProperties(js::ExclusiveContext *cx, uint32_t slotSpan);
|
||||
|
||||
inline void nativeSetSlot(uint32_t slot, const js::Value &value);
|
||||
static inline void nativeSetSlotWithType(js::ExclusiveContext *cx,
|
||||
|
@ -226,12 +226,7 @@ js::StartOffThreadParseScript(JSContext *cx, const CompileOptions &options,
|
||||
if (!global)
|
||||
return false;
|
||||
|
||||
// For now, type inference is always disabled in exclusive zones, as type
|
||||
// inference data is not merged between zones when finishing the off thread
|
||||
// parse. This restriction would be fairly easy to lift.
|
||||
JS_ASSERT(!cx->typeInferenceEnabled());
|
||||
global->zone()->types.inferenceEnabled = false;
|
||||
|
||||
global->zone()->types.inferenceEnabled = cx->typeInferenceEnabled();
|
||||
JS_SetCompartmentPrincipals(global->compartment(), cx->compartment()->principals);
|
||||
|
||||
RootedObject obj(cx);
|
||||
|
@ -407,7 +407,9 @@ JSRuntime::~JSRuntime()
|
||||
PR_DestroyLock(exclusiveAccessLock);
|
||||
|
||||
JS_ASSERT(!numExclusiveThreads);
|
||||
exclusiveThreadsPaused = true; // Avoid bogus asserts during teardown.
|
||||
|
||||
// Avoid bogus asserts during teardown.
|
||||
exclusiveThreadsPaused = true;
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -938,7 +938,7 @@ JSObject::clear(JSContext *cx, HandleObject obj)
|
||||
}
|
||||
|
||||
void
|
||||
JSObject::rollbackProperties(JSContext *cx, uint32_t slotSpan)
|
||||
JSObject::rollbackProperties(ExclusiveContext *cx, uint32_t slotSpan)
|
||||
{
|
||||
/*
|
||||
* Remove properties from this object until it has a matching slot span.
|
||||
|
Loading…
Reference in New Issue
Block a user