mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1156295 - Refactor GC rooting in StructType::DefineInternal() r=terrence
This commit is contained in:
parent
43f53f7829
commit
14afe613f8
@ -4028,6 +4028,18 @@ CType::Finalize(JSFreeOp* fop, JSObject* obj)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TraceFieldInfoHash(JSTracer* trc, FieldInfoHash* fields)
|
||||||
|
{
|
||||||
|
for (FieldInfoHash::Enum e(*fields); !e.empty(); e.popFront()) {
|
||||||
|
JSString* key = e.front().key();
|
||||||
|
JS_CallUnbarrieredStringTracer(trc, &key, "fieldName");
|
||||||
|
if (key != e.front().key())
|
||||||
|
e.rekeyFront(JS_ASSERT_STRING_IS_FLAT(key));
|
||||||
|
JS_CallObjectTracer(trc, &e.front().value().mType, "fieldType");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CType::Trace(JSTracer* trc, JSObject* obj)
|
CType::Trace(JSTracer* trc, JSObject* obj)
|
||||||
{
|
{
|
||||||
@ -4044,14 +4056,7 @@ CType::Trace(JSTracer* trc, JSObject* obj)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
FieldInfoHash* fields = static_cast<FieldInfoHash*>(slot.toPrivate());
|
FieldInfoHash* fields = static_cast<FieldInfoHash*>(slot.toPrivate());
|
||||||
for (FieldInfoHash::Enum e(*fields); !e.empty(); e.popFront()) {
|
TraceFieldInfoHash(trc, fields);
|
||||||
JSString* key = e.front().key();
|
|
||||||
JS_CallUnbarrieredStringTracer(trc, &key, "fieldName");
|
|
||||||
if (key != e.front().key())
|
|
||||||
e.rekeyFront(JS_ASSERT_STRING_IS_FLAT(key));
|
|
||||||
JS_CallObjectTracer(trc, &e.front().value().mType, "fieldType");
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TYPE_function: {
|
case TYPE_function: {
|
||||||
@ -5457,6 +5462,31 @@ PostBarrierCallback(JSTracer* trc, JSString* key, void* data)
|
|||||||
table->rekeyIfMoved(JS_ASSERT_STRING_IS_FLAT(prior), JS_ASSERT_STRING_IS_FLAT(key));
|
table->rekeyIfMoved(JS_ASSERT_STRING_IS_FLAT(prior), JS_ASSERT_STRING_IS_FLAT(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Holds a pointer to a FieldInfoHash while it is being constructed, tracing it
|
||||||
|
// on GC and destroying it when it dies unless release() has been called first.
|
||||||
|
class FieldInfoHolder : public JS::CustomAutoRooter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FieldInfoHolder(JSContext* cx, FieldInfoHash* fields)
|
||||||
|
: CustomAutoRooter(cx), fields_(fields) {}
|
||||||
|
~FieldInfoHolder() {
|
||||||
|
delete fields_;
|
||||||
|
}
|
||||||
|
virtual void trace(JSTracer* trc) override {
|
||||||
|
if (fields_)
|
||||||
|
TraceFieldInfoHash(trc, fields_);
|
||||||
|
}
|
||||||
|
FieldInfoHash* operator->() { return fields_; }
|
||||||
|
operator FieldInfoHash*() { return fields_; }
|
||||||
|
FieldInfoHash* release() {
|
||||||
|
FieldInfoHash* result = fields_;
|
||||||
|
fields_ = nullptr;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
FieldInfoHash* fields_;
|
||||||
|
};
|
||||||
|
|
||||||
bool
|
bool
|
||||||
StructType::DefineInternal(JSContext* cx, JSObject* typeObj_, JSObject* fieldsObj_)
|
StructType::DefineInternal(JSContext* cx, JSObject* typeObj_, JSObject* fieldsObj_)
|
||||||
{
|
{
|
||||||
@ -5487,16 +5517,11 @@ StructType::DefineInternal(JSContext* cx, JSObject* typeObj_, JSObject* fieldsOb
|
|||||||
// its constituents. (We cannot simply stash the hash in a reserved slot now
|
// its constituents. (We cannot simply stash the hash in a reserved slot now
|
||||||
// to get GC safety for free, since if anything in this function fails we
|
// to get GC safety for free, since if anything in this function fails we
|
||||||
// do not want to mutate 'typeObj'.)
|
// do not want to mutate 'typeObj'.)
|
||||||
auto fields = cx->make_unique<FieldInfoHash>();
|
FieldInfoHolder fields(cx, cx->new_<FieldInfoHash>());
|
||||||
if (!fields || !fields->init(len)) {
|
if (!fields || !fields->init(len)) {
|
||||||
JS_ReportOutOfMemory(cx);
|
JS_ReportOutOfMemory(cx);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
JS::AutoValueVector fieldRoots(cx);
|
|
||||||
if (!fieldRoots.resize(len)) {
|
|
||||||
JS_ReportOutOfMemory(cx);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Process the field types.
|
// Process the field types.
|
||||||
size_t structSize, structAlign;
|
size_t structSize, structAlign;
|
||||||
@ -5513,7 +5538,6 @@ StructType::DefineInternal(JSContext* cx, JSObject* typeObj_, JSObject* fieldsOb
|
|||||||
Rooted<JSFlatString*> name(cx, ExtractStructField(cx, item, &fieldType));
|
Rooted<JSFlatString*> name(cx, ExtractStructField(cx, item, &fieldType));
|
||||||
if (!name)
|
if (!name)
|
||||||
return false;
|
return false;
|
||||||
fieldRoots[i].setObject(*fieldType);
|
|
||||||
|
|
||||||
// Make sure each field name is unique
|
// Make sure each field name is unique
|
||||||
FieldInfoHash::AddPtr entryPtr = fields->lookupForAdd(name);
|
FieldInfoHash::AddPtr entryPtr = fields->lookupForAdd(name);
|
||||||
@ -5563,11 +5587,11 @@ StructType::DefineInternal(JSContext* cx, JSObject* typeObj_, JSObject* fieldsOb
|
|||||||
|
|
||||||
// Add field name to the hash
|
// Add field name to the hash
|
||||||
FieldInfo info;
|
FieldInfo info;
|
||||||
info.mType = nullptr; // Value of fields are not yet traceable here.
|
info.mType = fieldType;
|
||||||
info.mIndex = i;
|
info.mIndex = i;
|
||||||
info.mOffset = fieldOffset;
|
info.mOffset = fieldOffset;
|
||||||
ASSERT_OK(fields->add(entryPtr, name, info));
|
ASSERT_OK(fields->add(entryPtr, name, info));
|
||||||
JS_StoreStringPostBarrierCallback(cx, PostBarrierCallback, name, fields.get());
|
JS_StoreStringPostBarrierCallback(cx, PostBarrierCallback, name, fields);
|
||||||
|
|
||||||
structSize = fieldOffset + fieldSize;
|
structSize = fieldOffset + fieldSize;
|
||||||
|
|
||||||
@ -5596,12 +5620,6 @@ StructType::DefineInternal(JSContext* cx, JSObject* typeObj_, JSObject* fieldsOb
|
|||||||
if (!SizeTojsval(cx, structSize, &sizeVal))
|
if (!SizeTojsval(cx, structSize, &sizeVal))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (FieldInfoHash::Range r = fields->all(); !r.empty(); r.popFront()) {
|
|
||||||
FieldInfo& field = r.front().value();
|
|
||||||
MOZ_ASSERT(field.mIndex < fieldRoots.length());
|
|
||||||
field.mType = &fieldRoots[field.mIndex].toObject();
|
|
||||||
}
|
|
||||||
|
|
||||||
JS_SetReservedSlot(typeObj, SLOT_FIELDINFO, PRIVATE_TO_JSVAL(fields.release()));
|
JS_SetReservedSlot(typeObj, SLOT_FIELDINFO, PRIVATE_TO_JSVAL(fields.release()));
|
||||||
|
|
||||||
JS_SetReservedSlot(typeObj, SLOT_SIZE, sizeVal);
|
JS_SetReservedSlot(typeObj, SLOT_SIZE, sizeVal);
|
||||||
|
@ -281,6 +281,9 @@ struct FieldHashPolicy : DefaultHasher<JSFlatString*>
|
|||||||
|
|
||||||
typedef HashMap<JSFlatString*, FieldInfo, FieldHashPolicy, SystemAllocPolicy> FieldInfoHash;
|
typedef HashMap<JSFlatString*, FieldInfo, FieldHashPolicy, SystemAllocPolicy> FieldInfoHash;
|
||||||
|
|
||||||
|
void
|
||||||
|
TraceFieldInfoHash(JSTracer* trc, FieldInfoHash* fields);
|
||||||
|
|
||||||
// Descriptor of ABI, return type, argument types, and variadicity for a
|
// Descriptor of ABI, return type, argument types, and variadicity for a
|
||||||
// FunctionType.
|
// FunctionType.
|
||||||
struct FunctionInfo
|
struct FunctionInfo
|
||||||
|
Loading…
Reference in New Issue
Block a user