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 # changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more. # 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_OWNER, NullValue());
obj->initReservedSlot(JS_BUFVIEW_SLOT_NEXT_VIEW, PrivateValue(nullptr)); 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); return static_cast<TypedObject*>(&*obj);
} }

View File

@ -1284,8 +1284,6 @@ ScanTypeObject(GCMarker *gcmarker, types::TypeObject *type)
if (type->hasNewScript()) { if (type->hasNewScript()) {
PushMarkStack(gcmarker, type->newScript()->fun); PushMarkStack(gcmarker, type->newScript()->fun);
PushMarkStack(gcmarker, type->newScript()->templateObject); PushMarkStack(gcmarker, type->newScript()->templateObject);
} else if (type->hasTypedObject()) {
PushMarkStack(gcmarker, type->typedObject()->descrHeapPtr());
} }
if (type->interpretedFunction) if (type->interpretedFunction)
@ -1311,8 +1309,6 @@ gc::MarkChildren(JSTracer *trc, types::TypeObject *type)
if (type->hasNewScript()) { if (type->hasNewScript()) {
MarkObject(trc, &type->newScript()->fun, "type_new_function"); MarkObject(trc, &type->newScript()->fun, "type_new_function");
MarkObject(trc, &type->newScript()->templateObject, "type_new_template"); MarkObject(trc, &type->newScript()->templateObject, "type_new_template");
} else if (type->hasTypedObject()) {
MarkObject(trc, &type->typedObject()->descrHeapPtr(), "type_heap_ptr");
} }
if (type->interpretedFunction) 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 void
TypeObject::clearAddendum(ExclusiveContext *cx) TypeObject::clearAddendum(ExclusiveContext *cx)
{ {
@ -3064,10 +3087,6 @@ TypeObject::clearAddendum(ExclusiveContext *cx)
case TypeObjectAddendum::NewScript: case TypeObjectAddendum::NewScript:
clearNewScriptAddendum(cx); clearNewScriptAddendum(cx);
break; break;
case TypeObjectAddendum::TypedObject:
clearTypedObjectAddendum(cx);
break;
} }
/* We nullptr out addendum *before* freeing it so the write barrier works. */ /* 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 void
TypeObject::print() TypeObject::print()
{ {
@ -4562,47 +4553,12 @@ TypeScript::printTypes(JSContext *cx, HandleScript script) const
} }
#endif /* DEBUG */ #endif /* DEBUG */
/////////////////////////////////////////////////////////////////////
// Binary data
/////////////////////////////////////////////////////////////////////
void void
TypeObject::setAddendum(TypeObjectAddendum *addendum) TypeObject::setAddendum(TypeObjectAddendum *addendum)
{ {
this->addendum = 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) TypeObjectAddendum::TypeObjectAddendum(Kind kind)
: kind(kind) : kind(kind)
{} {}
@ -4611,13 +4567,3 @@ TypeNewScript::TypeNewScript()
: TypeObjectAddendum(NewScript) : 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 TypeNewScript;
struct TypeTypedObject;
struct TypeObjectAddendum struct TypeObjectAddendum
{ {
enum Kind { enum Kind {
NewScript, NewScript
TypedObject
}; };
explicit TypeObjectAddendum(Kind kind); explicit TypeObjectAddendum(Kind kind);
@ -834,15 +832,6 @@ struct TypeObjectAddendum
return (TypeNewScript*) this; return (TypeNewScript*) this;
} }
bool isTypedObject() {
return kind == TypedObject;
}
TypeTypedObject *asTypedObject() {
JS_ASSERT(isTypedObject());
return (TypeTypedObject*) this;
}
static inline void writeBarrierPre(TypeObjectAddendum *type); static inline void writeBarrierPre(TypeObjectAddendum *type);
static void writeBarrierPost(TypeObjectAddendum *newScript, void *addr) {} static void writeBarrierPost(TypeObjectAddendum *newScript, void *addr) {}
@ -899,21 +888,6 @@ struct TypeNewScript : public TypeObjectAddendum
static inline void writeBarrierPre(TypeNewScript *newScript); 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. * Lazy type objects overview.
* *
@ -1027,25 +1001,8 @@ struct TypeObject : gc::BarrieredCell<TypeObject>
return addendum->asNewScript(); return addendum->asNewScript();
} }
bool hasTypedObject() {
return addendum && addendum->isTypedObject();
}
TypeTypedObject *typedObject() {
return addendum->asTypedObject();
}
void setAddendum(TypeObjectAddendum *addendum); 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: private:
/* /*
* Properties of this object. This may contain JSID_VOID, representing the * 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 markStateChange(ExclusiveContext *cx);
void setFlags(ExclusiveContext *cx, TypeObjectFlags flags); void setFlags(ExclusiveContext *cx, TypeObjectFlags flags);
void markUnknown(ExclusiveContext *cx); void markUnknown(ExclusiveContext *cx);
void maybeClearNewScriptAddendumOnOOM();
void clearAddendum(ExclusiveContext *cx); void clearAddendum(ExclusiveContext *cx);
void clearNewScriptAddendum(ExclusiveContext *cx); void clearNewScriptAddendum(ExclusiveContext *cx);
void clearTypedObjectAddendum(ExclusiveContext *cx);
void maybeClearNewScriptAddendumOnOOM();
bool isPropertyNonData(jsid id); bool isPropertyNonData(jsid id);
bool isPropertyNonWritable(jsid id); bool isPropertyNonWritable(jsid id);

View File

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