Commit 96c7b4f2 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Merge pull request #554 from kmod/fast_attrwrapper_clear

Faster version of attrwrapper.clear()
parents fec260af 7025806b
...@@ -454,9 +454,6 @@ struct _typeobject { ...@@ -454,9 +454,6 @@ struct _typeobject {
void* _hcls; void* _hcls;
void* _hcattrs; void* _hcattrs;
// FIXME: this is hardcoding the size of this particular implementation of std::unordered_map
char _dep_getattrs[56]; // gcc 4.8
// char _dep_getattrs[64]; // gcc 4.9
char _ics[32]; char _ics[32];
void* _gcvisit_func; void* _gcvisit_func;
void* _dtor; void* _dtor;
......
...@@ -2964,7 +2964,6 @@ extern "C" int PyType_Ready(PyTypeObject* cls) noexcept { ...@@ -2964,7 +2964,6 @@ extern "C" int PyType_Ready(PyTypeObject* cls) noexcept {
assert(cls->attrs.hcls == NULL); assert(cls->attrs.hcls == NULL);
new (&cls->attrs) HCAttrs(HiddenClass::makeSingleton()); new (&cls->attrs) HCAttrs(HiddenClass::makeSingleton());
#define INITIALIZE(a) new (&(a)) decltype(a) #define INITIALIZE(a) new (&(a)) decltype(a)
INITIALIZE(cls->dependent_icgetattrs);
#undef INITIALIZE #undef INITIALIZE
BoxedClass* base = cls->tp_base; BoxedClass* base = cls->tp_base;
......
...@@ -500,6 +500,8 @@ public: ...@@ -500,6 +500,8 @@ public:
bool nonzeroIC(); bool nonzeroIC();
Box* hasnextOrNullIC(); Box* hasnextOrNullIC();
Box* nextIC(); Box* nextIC();
friend class AttrWrapper;
}; };
static_assert(offsetof(Box, cls) == offsetof(struct _object, ob_type), ""); static_assert(offsetof(Box, cls) == offsetof(struct _object, ob_type), "");
......
...@@ -536,6 +536,8 @@ HiddenClass* HiddenClass::getOrMakeChild(const std::string& attr) { ...@@ -536,6 +536,8 @@ HiddenClass* HiddenClass::getOrMakeChild(const std::string& attr) {
HiddenClass* HiddenClass::getAttrwrapperChild() { HiddenClass* HiddenClass::getAttrwrapperChild() {
assert(type == NORMAL); assert(type == NORMAL);
assert(attrwrapper_offset == -1);
if (!attrwrapper_child) { if (!attrwrapper_child) {
attrwrapper_child = new HiddenClass(this); attrwrapper_child = new HiddenClass(this);
attrwrapper_child->attrwrapper_offset = this->attributeArraySize(); attrwrapper_child->attrwrapper_offset = this->attributeArraySize();
...@@ -1932,17 +1934,6 @@ void setattrGeneric(Box* obj, const std::string& attr, Box* val, SetattrRewriteA ...@@ -1932,17 +1934,6 @@ void setattrGeneric(Box* obj, const std::string& attr, Box* val, SetattrRewriteA
if (isSubclass(obj->cls, type_cls)) { if (isSubclass(obj->cls, type_cls)) {
BoxedClass* self = static_cast<BoxedClass*>(obj); BoxedClass* self = static_cast<BoxedClass*>(obj);
if (attr == getattr_str || attr == getattribute_str) {
if (rewrite_args)
REWRITE_ABORTED("");
// Will have to embed the clear in the IC, so just disable the patching for now:
rewrite_args = NULL;
// TODO should put this clearing behavior somewhere else, since there are probably more
// cases in which we want to do it.
self->dependent_icgetattrs.invalidateAll();
}
if (attr == "__base__" && self->getattr("__base__")) if (attr == "__base__" && self->getattr("__base__"))
raiseExcHelper(TypeError, "readonly attribute"); raiseExcHelper(TypeError, "readonly attribute");
...@@ -3995,17 +3986,6 @@ extern "C" void delattrGeneric(Box* obj, const std::string& attr, DelattrRewrite ...@@ -3995,17 +3986,6 @@ extern "C" void delattrGeneric(Box* obj, const std::string& attr, DelattrRewrite
if (isSubclass(obj->cls, type_cls)) { if (isSubclass(obj->cls, type_cls)) {
BoxedClass* self = static_cast<BoxedClass*>(obj); BoxedClass* self = static_cast<BoxedClass*>(obj);
if (attr == getattr_str || attr == getattribute_str) {
if (rewrite_args)
REWRITE_ABORTED("");
// Will have to embed the clear in the IC, so just disable the patching for now:
rewrite_args = NULL;
// TODO should put this clearing behavior somewhere else, since there are probably more
// cases in which we want to do it.
self->dependent_icgetattrs.invalidateAll();
}
if (attr == "__base__" && self->getattr("__base__")) if (attr == "__base__" && self->getattr("__base__"))
raiseExcHelper(TypeError, "readonly attribute"); raiseExcHelper(TypeError, "readonly attribute");
...@@ -4015,6 +3995,9 @@ extern "C" void delattrGeneric(Box* obj, const std::string& attr, DelattrRewrite ...@@ -4015,6 +3995,9 @@ extern "C" void delattrGeneric(Box* obj, const std::string& attr, DelattrRewrite
REWRITE_ABORTED(""); REWRITE_ABORTED("");
} }
} }
// Extra "use" of rewrite_args to make the compiler happy:
(void)rewrite_args;
} }
extern "C" void delattrInternal(Box* obj, const std::string& attr, DelattrRewriteArgs* rewrite_args) { extern "C" void delattrInternal(Box* obj, const std::string& attr, DelattrRewriteArgs* rewrite_args) {
......
...@@ -1563,12 +1563,12 @@ public: ...@@ -1563,12 +1563,12 @@ public:
HCAttrs* attrs = self->b->getHCAttrsPtr(); HCAttrs* attrs = self->b->getHCAttrsPtr();
RELEASE_ASSERT(attrs->hcls->type == HiddenClass::NORMAL || attrs->hcls->type == HiddenClass::SINGLETON, ""); RELEASE_ASSERT(attrs->hcls->type == HiddenClass::NORMAL || attrs->hcls->type == HiddenClass::SINGLETON, "");
while (true) { // Clear the attrs array:
const auto& attrMap = attrs->hcls->getStrAttrOffsets(); new ((void*)attrs) HCAttrs(root_hcls);
if (attrMap.size() == 0) // Add the existing attrwrapper object (ie self) back as the attrwrapper:
break; self->b->appendNewHCAttr(self, NULL);
self->b->delattr(attrMap.begin()->first(), NULL); attrs->hcls = attrs->hcls->getAttrwrapperChild();
}
return None; return None;
} }
......
...@@ -152,12 +152,6 @@ public: ...@@ -152,12 +152,6 @@ public:
HCAttrs attrs; HCAttrs attrs;
// If the user sets __getattribute__ or __getattr__, we will have to invalidate
// all getattr IC entries that relied on the fact that those functions didn't exist.
// Doing this via invalidation means that instance attr lookups don't have
// to guard on anything about the class.
ICInvalidator dependent_icgetattrs;
// TODO: these don't actually get deallocated right now // TODO: these don't actually get deallocated right now
std::unique_ptr<CallattrIC> hasnext_ic, next_ic, repr_ic; std::unique_ptr<CallattrIC> hasnext_ic, next_ic, repr_ic;
std::unique_ptr<NonzeroIC> nonzero_ic; std::unique_ptr<NonzeroIC> nonzero_ic;
...@@ -268,7 +262,6 @@ static_assert(offsetof(pyston::Box, cls) == offsetof(struct _object, ob_type), " ...@@ -268,7 +262,6 @@ static_assert(offsetof(pyston::Box, cls) == offsetof(struct _object, ob_type), "
static_assert(offsetof(pyston::BoxedClass, cls) == offsetof(struct _typeobject, ob_type), ""); static_assert(offsetof(pyston::BoxedClass, cls) == offsetof(struct _typeobject, ob_type), "");
static_assert(offsetof(pyston::BoxedClass, tp_name) == offsetof(struct _typeobject, tp_name), ""); static_assert(offsetof(pyston::BoxedClass, tp_name) == offsetof(struct _typeobject, tp_name), "");
static_assert(offsetof(pyston::BoxedClass, attrs) == offsetof(struct _typeobject, _hcls), ""); static_assert(offsetof(pyston::BoxedClass, attrs) == offsetof(struct _typeobject, _hcls), "");
static_assert(offsetof(pyston::BoxedClass, dependent_icgetattrs) == offsetof(struct _typeobject, _dep_getattrs), "");
static_assert(offsetof(pyston::BoxedClass, gc_visit) == offsetof(struct _typeobject, _gcvisit_func), ""); static_assert(offsetof(pyston::BoxedClass, gc_visit) == offsetof(struct _typeobject, _gcvisit_func), "");
static_assert(sizeof(pyston::BoxedClass) == sizeof(struct _typeobject), ""); static_assert(sizeof(pyston::BoxedClass) == sizeof(struct _typeobject), "");
......
...@@ -44,6 +44,8 @@ class C(object): ...@@ -44,6 +44,8 @@ class C(object):
return 0 return 0
c = C() c = C()
c.attr = "test" c.attr = "test"
c.__dict__.clear() d1 = c.__dict__
d1.clear()
print hasattr(c, "attr") print hasattr(c, "attr")
print hasattr(c, "foo") print hasattr(c, "foo")
print c.__dict__ is d1
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment