Bug 1111363 - Allow trace list slots in type descriptors to retain their initial undefined value, r=sfink.

This commit is contained in:
Brian Hackett 2014-12-17 17:31:31 -07:00
parent a5e98f5a25
commit 235b9c9cff
4 changed files with 13 additions and 12 deletions

View File

@ -264,7 +264,6 @@ CreateSimdClass(JSContext *cx,
typeDescr->initReservedSlot(JS_DESCR_SLOT_SIZE, Int32Value(SimdTypeDescr::size(type)));
typeDescr->initReservedSlot(JS_DESCR_SLOT_OPAQUE, BooleanValue(false));
typeDescr->initReservedSlot(JS_DESCR_SLOT_TYPE, Int32Value(T::type));
typeDescr->initReservedSlot(JS_DESCR_SLOT_TRACE_LIST, PrivateValue(nullptr));
if (!CreateUserSizeAndAlignmentProperties(cx, typeDescr))
return nullptr;

View File

@ -3184,10 +3184,8 @@ CreateTraceList(JSContext *cx, HandleTypeDescr descr)
// for larger objects, both to limit the size of the trace lists and
// because tracing outline typed objects is considerably more complicated
// than inline ones.
if ((size_t) descr->size() > InlineTypedObject::MaximumSize || descr->transparent()) {
descr->initReservedSlot(JS_DESCR_SLOT_TRACE_LIST, PrivateValue(nullptr));
if ((size_t) descr->size() > InlineTypedObject::MaximumSize || descr->transparent())
return true;
}
TraceListVisitor visitor;
visitReferences(*descr, nullptr, visitor);
@ -3198,10 +3196,8 @@ CreateTraceList(JSContext *cx, HandleTypeDescr descr)
// Trace lists aren't necessary for descriptors with no references.
MOZ_ASSERT(entries.length() >= 3);
if (entries.length() == 3) {
descr->initReservedSlot(JS_DESCR_SLOT_TRACE_LIST, PrivateValue(nullptr));
if (entries.length() == 3)
return true;
}
int32_t *list = cx->pod_malloc<int32_t>(entries.length());
if (!list)
@ -3216,5 +3212,6 @@ CreateTraceList(JSContext *cx, HandleTypeDescr descr)
/* static */ void
TypeDescr::finalize(FreeOp *fop, JSObject *obj)
{
js_free(const_cast<int32_t *>(obj->as<TypeDescr>().traceList()));
if (obj->as<TypeDescr>().hasTraceList())
js_free(const_cast<int32_t *>(obj->as<TypeDescr>().traceList()));
}

View File

@ -178,13 +178,17 @@ class TypeDescr : public NativeObject
// typed objects, rather than the slower trace hook. This list is only
// specified when (a) the descriptor is short enough that it can fit in an
// InlineTypedObject, and (b) the descriptor contains at least one
// reference. Otherwise it is null.
// reference. Otherwise its value is undefined.
//
// The list is three consecutive arrays of int32_t offsets, with each array
// terminated by -1. The arrays store offsets of string, object, and value
// references in the descriptor, in that order.
bool hasTraceList() const {
return !getFixedSlot(JS_DESCR_SLOT_TRACE_LIST).isUndefined();
}
const int32_t *traceList() const {
return reinterpret_cast<int32_t *>(getReservedSlot(JS_DESCR_SLOT_TRACE_LIST).toPrivate());
MOZ_ASSERT(hasTraceList());
return reinterpret_cast<int32_t *>(getFixedSlot(JS_DESCR_SLOT_TRACE_LIST).toPrivate());
}
void initInstances(const JSRuntime *rt, uint8_t *mem, size_t length);

View File

@ -1786,9 +1786,10 @@ GCMarker::processMarkStackTop(SliceBudget &budget)
scan_typed_obj:
{
const int32_t *list = obj->as<InlineOpaqueTypedObject>().typeDescr().traceList();
if (!list)
TypeDescr *descr = &obj->as<InlineOpaqueTypedObject>().typeDescr();
if (!descr->hasTraceList())
return;
const int32_t *list = descr->traceList();
uint8_t *memory = obj->as<InlineOpaqueTypedObject>().inlineTypedMem();
while (*list != -1) {
JSString *str = *reinterpret_cast<JSString **>(memory + *list);