Bug 973238 Part 7 -- Remove type object addendum; leave the addendum mechanism in place r=bhackett

This commit is contained in:
Nicholas D. Matsakis 2014-03-11 13:44:58 -04:00
parent dea7e3bb5f
commit 7e2d4b5559
6 changed files with 26 additions and 141 deletions

View File

@ -22,4 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
Bug 973238 part 6 needs clobber due to self-hosted code (bug 1019955).
Bug 973238 part 7 needs clobber due to self-hosted code (bug 1019955).

View File

@ -1483,16 +1483,6 @@ TypedObject::createUnattachedWithClass(JSContext *cx,
obj->initReservedSlot(JS_BUFVIEW_SLOT_OWNER, NullValue());
obj->initReservedSlot(JS_BUFVIEW_SLOT_NEXT_VIEW, PrivateValue(nullptr));
// Tag the type object for this instance with the type
// representation, if that has not been done already.
if (!type->is<SimpleTypeDescr>()) { // FIXME Bug 929651
RootedTypeObject typeObj(cx, obj->getType(cx));
if (typeObj) {
if (!typeObj->addTypedObjectAddendum(cx, type))
return nullptr;
}
}
return static_cast<TypedObject*>(&*obj);
}

View File

@ -1284,8 +1284,6 @@ ScanTypeObject(GCMarker *gcmarker, types::TypeObject *type)
if (type->hasNewScript()) {
PushMarkStack(gcmarker, type->newScript()->fun);
PushMarkStack(gcmarker, type->newScript()->templateObject);
} else if (type->hasTypedObject()) {
PushMarkStack(gcmarker, type->typedObject()->descrHeapPtr());
}
if (type->interpretedFunction)
@ -1311,8 +1309,6 @@ gc::MarkChildren(JSTracer *trc, types::TypeObject *type)
if (type->hasNewScript()) {
MarkObject(trc, &type->newScript()->fun, "type_new_function");
MarkObject(trc, &type->newScript()->templateObject, "type_new_template");
} else if (type->hasTypedObject()) {
MarkObject(trc, &type->typedObject()->descrHeapPtr(), "type_heap_ptr");
}
if (type->interpretedFunction)

View File

@ -3040,6 +3040,29 @@ TypeObject::markUnknown(ExclusiveContext *cx)
}
}
void
TypeObject::maybeClearNewScriptAddendumOnOOM()
{
if (!isMarked())
return;
if (!addendum || addendum->kind != TypeObjectAddendum::NewScript)
return;
for (unsigned i = 0; i < getPropertyCount(); i++) {
Property *prop = getProperty(i);
if (!prop)
continue;
if (prop->types.definiteProperty())
prop->types.setNonDataPropertyIgnoringConstraints();
}
// This method is called during GC sweeping, so there is no write barrier
// that needs to be triggered.
js_free(addendum);
addendum.unsafeSet(nullptr);
}
void
TypeObject::clearAddendum(ExclusiveContext *cx)
{
@ -3064,10 +3087,6 @@ TypeObject::clearAddendum(ExclusiveContext *cx)
case TypeObjectAddendum::NewScript:
clearNewScriptAddendum(cx);
break;
case TypeObjectAddendum::TypedObject:
clearTypedObjectAddendum(cx);
break;
}
/* We nullptr out addendum *before* freeing it so the write barrier works. */
@ -3182,34 +3201,6 @@ TypeObject::clearNewScriptAddendum(ExclusiveContext *cx)
}
}
void
TypeObject::maybeClearNewScriptAddendumOnOOM()
{
if (!isMarked())
return;
if (!addendum || addendum->kind != TypeObjectAddendum::NewScript)
return;
for (unsigned i = 0; i < getPropertyCount(); i++) {
Property *prop = getProperty(i);
if (!prop)
continue;
if (prop->types.definiteProperty())
prop->types.setNonDataPropertyIgnoringConstraints();
}
// This method is called during GC sweeping, so there is no write barrier
// that needs to be triggered.
js_free(addendum);
addendum.unsafeSet(nullptr);
}
void
TypeObject::clearTypedObjectAddendum(ExclusiveContext *cx)
{
}
void
TypeObject::print()
{
@ -4562,47 +4553,12 @@ TypeScript::printTypes(JSContext *cx, HandleScript script) const
}
#endif /* DEBUG */
/////////////////////////////////////////////////////////////////////
// Binary data
/////////////////////////////////////////////////////////////////////
void
TypeObject::setAddendum(TypeObjectAddendum *addendum)
{
this->addendum = addendum;
}
bool
TypeObject::addTypedObjectAddendum(JSContext *cx, Handle<TypeDescr*> descr)
{
// Type descriptors are always pre-tenured. This is both because
// we expect them to live a long time and so that they can be
// safely accessed during ion compilation.
JS_ASSERT(!IsInsideNursery(descr));
JS_ASSERT(descr);
if (flags() & OBJECT_FLAG_ADDENDUM_CLEARED)
return true;
JS_ASSERT(!unknownProperties());
if (addendum) {
JS_ASSERT(hasTypedObject());
JS_ASSERT(&typedObject()->descr() == descr);
return true;
}
TypeTypedObject *typedObject = js_new<TypeTypedObject>(descr);
if (!typedObject)
return false;
addendum = typedObject;
return true;
}
/////////////////////////////////////////////////////////////////////
// Type object addenda constructor
/////////////////////////////////////////////////////////////////////
TypeObjectAddendum::TypeObjectAddendum(Kind kind)
: kind(kind)
{}
@ -4611,13 +4567,3 @@ TypeNewScript::TypeNewScript()
: TypeObjectAddendum(NewScript)
{}
TypeTypedObject::TypeTypedObject(Handle<TypeDescr*> descr)
: TypeObjectAddendum(TypedObject),
descr_(descr)
{
}
TypeDescr &
js::types::TypeTypedObject::descr() {
return descr_->as<TypeDescr>();
}

View File

@ -812,13 +812,11 @@ struct Property
};
struct TypeNewScript;
struct TypeTypedObject;
struct TypeObjectAddendum
{
enum Kind {
NewScript,
TypedObject
NewScript
};
explicit TypeObjectAddendum(Kind kind);
@ -834,15 +832,6 @@ struct TypeObjectAddendum
return (TypeNewScript*) this;
}
bool isTypedObject() {
return kind == TypedObject;
}
TypeTypedObject *asTypedObject() {
JS_ASSERT(isTypedObject());
return (TypeTypedObject*) this;
}
static inline void writeBarrierPre(TypeObjectAddendum *type);
static void writeBarrierPost(TypeObjectAddendum *newScript, void *addr) {}
@ -899,21 +888,6 @@ struct TypeNewScript : public TypeObjectAddendum
static inline void writeBarrierPre(TypeNewScript *newScript);
};
struct TypeTypedObject : public TypeObjectAddendum
{
private:
HeapPtrObject descr_;
public:
explicit TypeTypedObject(Handle<TypeDescr*> descr);
HeapPtrObject &descrHeapPtr() {
return descr_;
}
TypeDescr &descr();
};
/*
* Lazy type objects overview.
*
@ -1027,25 +1001,8 @@ struct TypeObject : gc::BarrieredCell<TypeObject>
return addendum->asNewScript();
}
bool hasTypedObject() {
return addendum && addendum->isTypedObject();
}
TypeTypedObject *typedObject() {
return addendum->asTypedObject();
}
void setAddendum(TypeObjectAddendum *addendum);
/*
* Tag the type object for a binary data type descriptor, instance,
* or handle with the type representation of the data it points at.
* If this type object is already tagged with a binary data addendum,
* this addendum must already be associated with the same TypeRepresentation,
* and the method has no effect.
*/
bool addTypedObjectAddendum(JSContext *cx, Handle<TypeDescr*> descr);
private:
/*
* Properties of this object. This may contain JSID_VOID, representing the
@ -1157,10 +1114,9 @@ struct TypeObject : gc::BarrieredCell<TypeObject>
void markStateChange(ExclusiveContext *cx);
void setFlags(ExclusiveContext *cx, TypeObjectFlags flags);
void markUnknown(ExclusiveContext *cx);
void maybeClearNewScriptAddendumOnOOM();
void clearAddendum(ExclusiveContext *cx);
void clearNewScriptAddendum(ExclusiveContext *cx);
void clearTypedObjectAddendum(ExclusiveContext *cx);
void maybeClearNewScriptAddendumOnOOM();
bool isPropertyNonData(jsid id);
bool isPropertyNonWritable(jsid id);

View File

@ -1224,9 +1224,6 @@ TypeObjectAddendum::writeBarrierPre(TypeObjectAddendum *type)
switch (type->kind) {
case NewScript:
return TypeNewScript::writeBarrierPre(type->asNewScript());
case TypedObject:
return TypeTypedObject::writeBarrierPre(type->asTypedObject());
}
#endif
}