Skip to content

Commit 9a3a43c

Browse files
committed
Merge pull request #899 from undingen/perf_oldstyle2
rewrite oldstyle class getattro
2 parents 7b84d99 + 4975866 commit 9a3a43c

File tree

3 files changed

+90
-25
lines changed

3 files changed

+90
-25
lines changed

src/runtime/classobj.cpp

Lines changed: 83 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "capi/types.h"
2020
#include "core/types.h"
2121
#include "runtime/objmodel.h"
22+
#include "runtime/rewrite_args.h"
2223
#include "runtime/types.h"
2324

2425
namespace pyston {
@@ -27,14 +28,24 @@ extern "C" {
2728
BoxedClass* classobj_cls, *instance_cls;
2829
}
2930

30-
static Box* classLookup(BoxedClassobj* cls, BoxedString* attr) {
31-
Box* r = cls->getattr(attr);
31+
32+
static Box* classLookup(BoxedClassobj* cls, BoxedString* attr, GetattrRewriteArgs* rewrite_args = NULL) {
33+
if (rewrite_args)
34+
assert(!rewrite_args->out_success);
35+
36+
Box* r = cls->getattr(attr, rewrite_args);
3237
if (r)
3338
return r;
3439

40+
if (rewrite_args) {
41+
// abort rewriting because we currenly don't guard the particular 'bases' hierarchy
42+
rewrite_args->out_success = false;
43+
rewrite_args = NULL;
44+
}
45+
3546
for (auto b : *cls->bases) {
3647
RELEASE_ASSERT(b->cls == classobj_cls, "");
37-
Box* r = classLookup(static_cast<BoxedClassobj*>(b), attr);
48+
Box* r = classLookup(static_cast<BoxedClassobj*>(b), attr, rewrite_args);
3849
if (r)
3950
return r;
4051
}
@@ -253,38 +264,76 @@ Box* classobjStr(Box* _obj) {
253264

254265

255266
// Analogous to CPython's instance_getattr2
256-
static Box* instanceGetattributeSimple(BoxedInstance* inst, BoxedString* attr_str) {
257-
Box* r = inst->getattr(attr_str);
267+
static Box* instanceGetattributeSimple(BoxedInstance* inst, BoxedString* attr_str,
268+
GetattrRewriteArgs* rewriter_args = NULL) {
269+
Box* r = inst->getattr(attr_str, rewriter_args);
258270
if (r)
259271
return r;
260272

261-
r = classLookup(inst->inst_cls, attr_str);
273+
RewriterVar* r_inst = NULL;
274+
RewriterVar* r_inst_cls = NULL;
275+
if (rewriter_args) {
276+
if (!rewriter_args->out_success)
277+
rewriter_args = NULL;
278+
else {
279+
rewriter_args->out_success = false;
280+
r_inst = rewriter_args->obj;
281+
r_inst_cls = r_inst->getAttr(offsetof(BoxedInstance, inst_cls));
282+
}
283+
}
284+
GetattrRewriteArgs grewriter_inst_args(rewriter_args ? rewriter_args->rewriter : NULL, r_inst_cls,
285+
rewriter_args ? rewriter_args->rewriter->getReturnDestination()
286+
: Location());
287+
r = classLookup(inst->inst_cls, attr_str, rewriter_args ? &grewriter_inst_args : NULL);
288+
if (!grewriter_inst_args.out_success)
289+
rewriter_args = NULL;
290+
262291
if (r) {
263-
return processDescriptor(r, inst, inst->inst_cls);
292+
Box* rtn = processDescriptor(r, inst, inst->inst_cls);
293+
if (rewriter_args) {
294+
RewriterVar* r_rtn = rewriter_args->rewriter->call(true, (void*)processDescriptor,
295+
grewriter_inst_args.out_rtn, r_inst, r_inst_cls);
296+
rewriter_args->out_rtn = r_rtn;
297+
rewriter_args->out_success = true;
298+
rewriter_args->out_return_convention = GetattrRewriteArgs::VALID_RETURN;
299+
}
300+
return rtn;
264301
}
265302

266303
return NULL;
267304
}
268305

269-
static Box* instanceGetattributeWithFallback(BoxedInstance* inst, BoxedString* attr_str) {
270-
Box* attr_obj = instanceGetattributeSimple(inst, attr_str);
306+
static Box* instanceGetattributeWithFallback(BoxedInstance* inst, BoxedString* attr_str,
307+
GetattrRewriteArgs* rewriter_args = NULL) {
308+
Box* attr_obj = instanceGetattributeSimple(inst, attr_str, rewriter_args);
271309

272310
if (attr_obj) {
273311
return attr_obj;
274312
}
275313

314+
if (rewriter_args) {
315+
if (!rewriter_args->out_success)
316+
rewriter_args = NULL;
317+
else
318+
rewriter_args->out_success = false;
319+
320+
// abort rewriting for now
321+
rewriter_args = NULL;
322+
}
323+
276324
static BoxedString* getattr_str = internStringImmortal("__getattr__");
277325
Box* getattr = classLookup(inst->inst_cls, getattr_str);
278326

279327
if (getattr) {
280328
getattr = processDescriptor(getattr, inst, inst->inst_cls);
281-
return runtimeCall(getattr, ArgPassSpec(1), attr_str, NULL, NULL, NULL, NULL);
329+
return runtimeCallInternal<CXX>(getattr, NULL, ArgPassSpec(1), attr_str, NULL, NULL, NULL, NULL);
282330
}
283331

284332
return NULL;
285333
}
286334

287-
static Box* _instanceGetattribute(Box* _inst, BoxedString* attr_str, bool raise_on_missing) {
335+
static Box* _instanceGetattribute(Box* _inst, BoxedString* attr_str, bool raise_on_missing,
336+
GetattrRewriteArgs* rewriter_args = NULL) {
288337
RELEASE_ASSERT(_inst->cls == instance_cls, "");
289338
BoxedInstance* inst = static_cast<BoxedInstance*>(_inst);
290339

@@ -297,7 +346,7 @@ static Box* _instanceGetattribute(Box* _inst, BoxedString* attr_str, bool raise_
297346
return inst->inst_cls;
298347
}
299348

300-
Box* attr = instanceGetattributeWithFallback(inst, attr_str);
349+
Box* attr = instanceGetattributeWithFallback(inst, attr_str, rewriter_args);
301350
if (attr) {
302351
return attr;
303352
} else if (!raise_on_missing) {
@@ -308,25 +357,34 @@ static Box* _instanceGetattribute(Box* _inst, BoxedString* attr_str, bool raise_
308357
}
309358
}
310359

311-
Box* instanceGetattribute(Box* _inst, Box* _attr) {
312-
STAT_TIMER(t0, "us_timer_instance_getattribute", 0);
360+
// Analogous to CPython's instance_getattr
361+
Box* instance_getattro(Box* cls, Box* attr) noexcept {
362+
return instanceGetattroInternal<CAPI>(cls, attr, NULL);
363+
}
364+
365+
template <ExceptionStyle S>
366+
Box* instanceGetattroInternal(Box* cls, Box* _attr, GetattrRewriteArgs* rewrite_args) noexcept(S == CAPI) {
367+
STAT_TIMER(t0, "us_timer_instance_getattro", 0);
313368

314369
RELEASE_ASSERT(_attr->cls == str_cls, "");
315370
BoxedString* attr = static_cast<BoxedString*>(_attr);
316-
return _instanceGetattribute(_inst, attr, true);
317-
}
318371

319-
320-
// Analogous to CPython's instance_getattr
321-
static Box* instance_getattro(Box* cls, Box* attr) noexcept {
322-
try {
323-
return instanceGetattribute(cls, attr);
324-
} catch (ExcInfo e) {
325-
setCAPIException(e);
326-
return NULL;
372+
if (S == CAPI) {
373+
try {
374+
return _instanceGetattribute(cls, attr, true, rewrite_args);
375+
} catch (ExcInfo e) {
376+
setCAPIException(e);
377+
return NULL;
378+
}
379+
} else {
380+
return _instanceGetattribute(cls, attr, true, rewrite_args);
327381
}
328382
}
329383

384+
// Force instantiation of the template
385+
template Box* instanceGetattroInternal<CAPI>(Box*, Box*, GetattrRewriteArgs*) noexcept;
386+
template Box* instanceGetattroInternal<CXX>(Box*, Box*, GetattrRewriteArgs*);
387+
330388
Box* instanceSetattr(Box* _inst, Box* _attr, Box* value) {
331389
RELEASE_ASSERT(_inst->cls == instance_cls, "");
332390
BoxedInstance* inst = static_cast<BoxedInstance*>(_inst);
@@ -1458,7 +1516,7 @@ void setupClassobj() {
14581516

14591517

14601518
instance_cls->giveAttr("__getattribute__",
1461-
new BoxedFunction(boxRTFunction((void*)instanceGetattribute, UNKNOWN, 2)));
1519+
new BoxedFunction(boxRTFunction((void*)instanceGetattroInternal<CXX>, UNKNOWN, 2)));
14621520
instance_cls->giveAttr("__setattr__", new BoxedFunction(boxRTFunction((void*)instanceSetattr, UNKNOWN, 3)));
14631521
instance_cls->giveAttr("__delattr__", new BoxedFunction(boxRTFunction((void*)instanceDelattr, UNKNOWN, 2)));
14641522
instance_cls->giveAttr("__str__", new BoxedFunction(boxRTFunction((void*)instanceStr, UNKNOWN, 1)));

src/runtime/classobj.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,11 @@ class BoxedInstance : public Box {
8181
v->visit(&o->inst_cls);
8282
}
8383
};
84+
85+
Box* instance_getattro(Box* cls, Box* attr) noexcept;
86+
class GetattrRewriteArgs;
87+
template <ExceptionStyle S>
88+
Box* instanceGetattroInternal(Box* self, Box* attr, GetattrRewriteArgs* rewrite_args) noexcept(S == CAPI);
8489
}
8590

8691
#endif

src/runtime/objmodel.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1440,6 +1440,8 @@ Box* getattrInternalEx(Box* obj, BoxedString* attr, GetattrRewriteArgs* rewrite_
14401440

14411441
if (obj->cls->tp_getattro == slot_tp_getattr_hook) {
14421442
return slotTpGetattrHookInternal<S>(obj, attr, rewrite_args);
1443+
} else if (obj->cls->tp_getattro == instance_getattro) {
1444+
return instanceGetattroInternal<S>(obj, attr, rewrite_args);
14431445
}
14441446

14451447
Box* r = obj->cls->tp_getattro(obj, attr);

0 commit comments

Comments
 (0)