Commit b50ffe4b authored by Kevin Modzelewski's avatar Kevin Modzelewski

Merge pull request #705 from kmod/perf8

some misc microoptimizations
parents 0c84c153 f0c1aee1
......@@ -1393,6 +1393,23 @@ Box* getattrInternalEx(Box* obj, BoxedString* attr, GetattrRewriteArgs* rewrite_
Box* r = obj->cls->tp_getattro(obj, attr);
if (!r)
throwCAPIException();
// If attr is immortal, then we are free to write an embedded reference to it.
// Immortal are (unfortunately) common right now, so this is an easy way to get
// around the fact that we don't currently scan ICs for GC references, but eventually
// we should just add that.
if (rewrite_args && attr->interned_state == SSTATE_INTERNED_IMMORTAL) {
// In theory we could also just guard that the tp_getattro slot is non-null and then call
// into it, instead of guarding that it is the same as it is here.
rewrite_args->obj->getAttr(offsetof(Box, cls))
->addAttrGuard(offsetof(BoxedClass, tp_getattro), (uint64_t)obj->cls->tp_getattro);
auto r_box = rewrite_args->rewriter->loadConst((intptr_t)attr);
auto r_rtn = rewrite_args->rewriter->call(true, (void*)obj->cls->tp_getattro, rewrite_args->obj, r_box);
rewrite_args->rewriter->call(true, (void*)checkAndThrowCAPIException);
rewrite_args->out_rtn = r_rtn;
rewrite_args->out_success = true;
}
return r;
}
......@@ -1903,11 +1920,15 @@ extern "C" Box* getattr(Box* obj, BoxedString* attr) {
GetattrRewriteArgs rewrite_args(rewriter.get(), rewriter->getArg(0), dest);
val = getattrInternal(obj, attr, &rewrite_args);
// should make sure getattrInternal calls finishes using obj itself
// if it is successful
if (rewrite_args.out_success && val) {
if (recorder) {
if (rewrite_args.out_success) {
if (!val) {
if (attr->interned_state == SSTATE_INTERNED_IMMORTAL) {
rewriter->call(true, (void*)raiseAttributeError, rewriter->getArg(0),
rewriter->loadConst((intptr_t)attr->data(), Location::forArg(1)),
rewriter->loadConst(attr->size(), Location::forArg(2)));
rewriter->commit();
}
} else if (recorder) {
RewriterVar* record_rtn = rewriter->call(false, (void*)recordType,
rewriter->loadConst((intptr_t)recorder, Location::forArg(0)),
rewrite_args.out_rtn);
......
......@@ -126,8 +126,7 @@ int BoxedTuple::Resize(BoxedTuple** pv, size_t newsize) noexcept {
return 0;
}
BoxedTuple* resized = new (newsize)
BoxedTuple(newsize); // we want an uninitialized tuple, but this will memset it with 0.
BoxedTuple* resized = new (newsize) BoxedTuple();
memmove(resized->elts, t->elts, sizeof(Box*) * t->size());
*pv = resized;
......
......@@ -566,32 +566,36 @@ public:
class BoxedTuple : public BoxVar {
public:
static BoxedTuple* create(int64_t size) { return new (size) BoxedTuple(size); }
static BoxedTuple* create(int64_t size) {
BoxedTuple* rtn = new (size) BoxedTuple();
memset(rtn->elts, 0, size * sizeof(Box*)); // TODO not all callers want this (but some do)
return rtn;
}
static BoxedTuple* create(int64_t nelts, Box** elts) {
BoxedTuple* rtn = new (nelts) BoxedTuple(nelts);
BoxedTuple* rtn = new (nelts) BoxedTuple();
memmove(&rtn->elts[0], elts, sizeof(Box*) * nelts);
return rtn;
}
static BoxedTuple* create1(Box* elt0) {
BoxedTuple* rtn = new (1) BoxedTuple(1);
BoxedTuple* rtn = new (1) BoxedTuple();
rtn->elts[0] = elt0;
return rtn;
}
static BoxedTuple* create2(Box* elt0, Box* elt1) {
BoxedTuple* rtn = new (2) BoxedTuple(2);
BoxedTuple* rtn = new (2) BoxedTuple();
rtn->elts[0] = elt0;
rtn->elts[1] = elt1;
return rtn;
}
static BoxedTuple* create3(Box* elt0, Box* elt1, Box* elt2) {
BoxedTuple* rtn = new (3) BoxedTuple(3);
BoxedTuple* rtn = new (3) BoxedTuple();
rtn->elts[0] = elt0;
rtn->elts[1] = elt1;
rtn->elts[2] = elt2;
return rtn;
}
static BoxedTuple* create4(Box* elt0, Box* elt1, Box* elt2, Box* elt3) {
BoxedTuple* rtn = new (4) BoxedTuple(4);
BoxedTuple* rtn = new (4) BoxedTuple();
rtn->elts[0] = elt0;
rtn->elts[1] = elt1;
rtn->elts[2] = elt2;
......@@ -599,7 +603,7 @@ public:
return rtn;
}
static BoxedTuple* create5(Box* elt0, Box* elt1, Box* elt2, Box* elt3, Box* elt4) {
BoxedTuple* rtn = new (5) BoxedTuple(5);
BoxedTuple* rtn = new (5) BoxedTuple();
rtn->elts[0] = elt0;
rtn->elts[1] = elt1;
rtn->elts[2] = elt2;
......@@ -610,17 +614,20 @@ public:
static BoxedTuple* create(std::initializer_list<Box*> members) { return new (members.size()) BoxedTuple(members); }
static BoxedTuple* create(int64_t size, BoxedClass* cls) {
BoxedTuple* rtn;
if (cls == tuple_cls)
return new (size) BoxedTuple(size);
rtn = new (size) BoxedTuple();
else
return new (cls, size) BoxedTuple(size);
rtn = new (cls, size) BoxedTuple();
memset(rtn->elts, 0, size * sizeof(Box*)); // TODO not all callers want this (but some do)
return rtn;
}
static BoxedTuple* create(int64_t nelts, Box** elts, BoxedClass* cls) {
BoxedTuple* rtn;
if (cls == tuple_cls)
rtn = new (nelts) BoxedTuple(nelts);
rtn = new (nelts) BoxedTuple();
else
rtn = new (cls, nelts) BoxedTuple(nelts);
rtn = new (cls, nelts) BoxedTuple();
memmove(&rtn->elts[0], elts, sizeof(Box*) * nelts);
return rtn;
}
......@@ -666,7 +673,7 @@ public:
}
private:
BoxedTuple(size_t size) { memset(elts, 0, sizeof(Box*) * size); }
BoxedTuple() {}
BoxedTuple(std::initializer_list<Box*>& members) {
// by the time we make it here elts[] is big enough to contain members
......
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