Skip to content

Commit 93a65a7

Browse files
committed
callattr runtimeCall: don't generate arg guards if we know that the classes can't change
1 parent e37660e commit 93a65a7

File tree

8 files changed

+36
-20
lines changed

8 files changed

+36
-20
lines changed

src/asm_writing/icinfo.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,7 @@ ICInfo::ICInfo(void* start_addr, void* slowpath_rtn_addr, void* continue_addr, S
247247
retry_in(0),
248248
retry_backoff(1),
249249
times_rewritten(0),
250+
has_const_arg_classes(false),
250251
ic_global_decref_locations(std::move(ic_global_decref_locations)),
251252
start_addr(start_addr),
252253
slowpath_rtn_addr(slowpath_rtn_addr),

src/asm_writing/icinfo.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ class ICInfo {
137137
TypeRecorder* const type_recorder;
138138
int retry_in, retry_backoff;
139139
int times_rewritten;
140+
bool has_const_arg_classes;
140141

141142
DecrefInfo slowpath_decref_info;
142143
// This is a vector of locations which always need to get decrefed inside this IC.
@@ -176,6 +177,9 @@ class ICInfo {
176177
int percentBackedoff() const { return retry_backoff; }
177178
int timesRewritten() const { return times_rewritten; }
178179

180+
void setHasConstArgClasses(bool b = true) { has_const_arg_classes = b; }
181+
bool hasConstArgClasses() const { return has_const_arg_classes; }
182+
179183
friend class ICSlotRewrite;
180184

181185
static ICInfo* getICInfoForNode(AST* node);

src/asm_writing/rewriter.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2327,9 +2327,9 @@ Rewriter* Rewriter::createRewriter(void* rtn_addr, int num_args, const char* deb
23272327
// Horrible non-robust optimization: addresses below this address are probably in the binary (ex the interpreter),
23282328
// so don't do the more-expensive hash table lookup to find it.
23292329
if (rtn_addr > (void*)0x1000000) {
2330-
ic = getICInfo(rtn_addr);
2330+
ic = pyston::getICInfo(rtn_addr);
23312331
} else {
2332-
ASSERT(!getICInfo(rtn_addr), "%p", rtn_addr);
2332+
ASSERT(!pyston::getICInfo(rtn_addr), "%p", rtn_addr);
23332333
}
23342334

23352335
log_ic_attempts(debug_name);

src/asm_writing/rewriter.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,8 @@ class Rewriter : public ICSlotRewrite::CommitHook {
580580

581581
TypeRecorder* getTypeRecorder();
582582

583+
const ICInfo* getICInfo() { return rewrite->getICInfo(); }
584+
583585
const char* debugName() { return rewrite->debugName(); }
584586

585587
// Register that this rewrite will embed a reference to a particular gc object.

src/codegen/compvars.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -584,12 +584,16 @@ _call(IREmitter& emitter, const OpInfo& info, llvm::Value* func, ExceptionStyle
584584
bool pass_keyword_names = (keyword_names != nullptr);
585585
assert(pass_keyword_names == (argspec.num_keywords > 0));
586586

587+
bool has_const_arg_classes = true;
587588
std::vector<BoxedClass*> guaranteed_classes;
588589
std::vector<ConcreteCompilerVariable*> converted_args;
589590
for (int i = 0; i < args.size(); i++) {
590591
assert(args[i]);
591592
converted_args.push_back(args[i]->makeConverted(emitter, args[i]->getBoxType()));
592-
guaranteed_classes.push_back(converted_args.back()->guaranteedClass());
593+
BoxedClass* guaranteed_class = converted_args.back()->guaranteedClass();
594+
guaranteed_classes.push_back(guaranteed_class);
595+
if (guaranteed_class == NULL)
596+
has_const_arg_classes = false;
593597
}
594598

595599
std::vector<llvm::Value*> llvm_args;
@@ -658,7 +662,8 @@ _call(IREmitter& emitter, const OpInfo& info, llvm::Value* func, ExceptionStyle
658662
if (do_patchpoint) {
659663
assert(func_addr);
660664

661-
ICSetupInfo* pp = createCallsiteIC(info.getTypeRecorder(), args.size(), info.getBJitICInfo());
665+
ICSetupInfo* pp
666+
= createCallsiteIC(info.getTypeRecorder(), args.size(), info.getBJitICInfo(), has_const_arg_classes);
662667

663668
llvm::Instruction* uncasted = emitter.createIC(pp, func_addr, llvm_args, info.unw_info, target_exception_style,
664669
getNullPtr(g.llvm_value_type_ptr));

src/codegen/patchpoints.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,9 @@ int ICSetupInfo::totalSize() const {
4949
static std::vector<std::pair<PatchpointInfo*, void* /* addr of func to call */>> new_patchpoints;
5050

5151
ICSetupInfo* ICSetupInfo::initialize(bool has_return_value, int num_slots, int slot_size, ICType type,
52-
TypeRecorder* type_recorder) {
53-
ICSetupInfo* rtn = new ICSetupInfo(type, num_slots, slot_size, has_return_value, type_recorder);
52+
TypeRecorder* type_recorder, bool has_const_arg_classes) {
53+
ICSetupInfo* rtn
54+
= new ICSetupInfo(type, num_slots, slot_size, has_return_value, type_recorder, has_const_arg_classes);
5455

5556
// We use size == CALL_ONLY_SIZE to imply that the call isn't patchable
5657
assert(rtn->totalSize() > CALL_ONLY_SIZE);
@@ -325,6 +326,7 @@ void processStackmap(CompiledFunction* cf, StackMap* stackmap) {
325326
start_addr, initialization_info.slowpath_start, initialization_info.continue_addr,
326327
initialization_info.slowpath_rtn_addr, ic, StackInfo(scratch_size, scratch_rsp_offset),
327328
std::move(initialization_info.live_outs));
329+
icinfo->setHasConstArgClasses(ic->has_const_arg_classes);
328330

329331
assert(cf);
330332
// TODO: unsafe. hard to use a unique_ptr here though.
@@ -403,9 +405,9 @@ ICSetupInfo* createDelattrIC(TypeRecorder* type_recorder) {
403405
return ICSetupInfo::initialize(false, 1, 144, ICSetupInfo::Delattr, type_recorder);
404406
}
405407

406-
ICSetupInfo* createCallsiteIC(TypeRecorder* type_recorder, int num_args, ICInfo* bjit_ic_info) {
407-
return ICSetupInfo::initialize(true, numSlots(bjit_ic_info, 4), 640 + 48 * num_args, ICSetupInfo::Callsite,
408-
type_recorder);
408+
ICSetupInfo* createCallsiteIC(TypeRecorder* type_recorder, int num_args, ICInfo* bjit_ic_info, bool const_arg_classes) {
409+
return ICSetupInfo::initialize(true, const_arg_classes ? 1 : numSlots(bjit_ic_info, 4), 640 + 48 * num_args,
410+
ICSetupInfo::Callsite, type_recorder, const_arg_classes);
409411
}
410412

411413
ICSetupInfo* createGetGlobalIC(TypeRecorder* type_recorder) {

src/codegen/patchpoints.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,18 +64,21 @@ class ICSetupInfo {
6464
};
6565

6666
private:
67-
ICSetupInfo(ICType type, int num_slots, int slot_size, bool has_return_value, TypeRecorder* type_recorder)
67+
ICSetupInfo(ICType type, int num_slots, int slot_size, bool has_return_value, TypeRecorder* type_recorder,
68+
bool has_const_arg_classes)
6869
: type(type),
6970
num_slots(num_slots),
7071
slot_size(slot_size),
7172
has_return_value(has_return_value),
73+
has_const_arg_classes(has_const_arg_classes),
7274
type_recorder(type_recorder) {}
7375

7476
public:
7577
const ICType type;
7678

7779
const int num_slots, slot_size;
7880
const bool has_return_value;
81+
const bool has_const_arg_classes;
7982
TypeRecorder* const type_recorder;
8083

8184
int totalSize() const;
@@ -96,7 +99,7 @@ class ICSetupInfo {
9699
}
97100

98101
static ICSetupInfo* initialize(bool has_return_value, int num_slots, int slot_size, ICType type,
99-
TypeRecorder* type_recorder);
102+
TypeRecorder* type_recorder, bool has_const_arg_classes = false);
100103
};
101104

102105
struct PatchpointInfo {
@@ -168,7 +171,8 @@ struct PatchpointInfo {
168171

169172
class ICInfo;
170173
ICSetupInfo* createGenericIC(TypeRecorder* type_recorder, bool has_return_value, int size);
171-
ICSetupInfo* createCallsiteIC(TypeRecorder* type_recorder, int num_args, ICInfo* bjit_ic_info);
174+
ICSetupInfo* createCallsiteIC(TypeRecorder* type_recorder, int num_args, ICInfo* bjit_ic_info,
175+
bool has_const_arg_classes);
172176
ICSetupInfo* createGetGlobalIC(TypeRecorder* type_recorder);
173177
ICSetupInfo* createGetattrIC(TypeRecorder* type_recorder, ICInfo* bjit_ic_info);
174178
ICSetupInfo* createSetattrIC(TypeRecorder* type_recorder, ICInfo* bjit_ic_info);

src/runtime/objmodel.cpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3885,12 +3885,11 @@ Box* _callattrEntry(Box* obj, BoxedString* attr, CallattrFlags flags, Box* arg1,
38853885
}
38863886

38873887
if (rewriter.get()) {
3888-
// TODO feel weird about doing this; it either isn't necessary
3889-
// or this kind of thing is necessary in a lot more places
3890-
// rewriter->getArg(3).addGuard(npassed_args);
3891-
38923888
CallattrRewriteArgs rewrite_args(rewriter.get(), rewriter->getArg(0)->setType(RefType::BORROWED),
38933889
rewriter->getReturnDestination());
3890+
if (rewriter->getICInfo()->hasConstArgClasses())
3891+
rewrite_args.args_guarded = true;
3892+
38943893
if (npassed_args >= 1)
38953894
rewrite_args.arg1 = rewriter->getArg(3)->setType(RefType::BORROWED);
38963895
if (npassed_args >= 2)
@@ -5369,12 +5368,11 @@ static Box* runtimeCallEntry(Box* obj, ArgPassSpec argspec, Box* arg1, Box* arg2
53695368
#endif
53705369

53715370
if (rewriter.get()) {
5372-
// TODO feel weird about doing this; it either isn't necessary
5373-
// or this kind of thing is necessary in a lot more places
5374-
// rewriter->getArg(1).addGuard(npassed_args);
5375-
53765371
CallRewriteArgs rewrite_args(rewriter.get(), rewriter->getArg(0)->setType(RefType::BORROWED),
53775372
rewriter->getReturnDestination());
5373+
if (rewriter->getICInfo()->hasConstArgClasses())
5374+
rewrite_args.args_guarded = true;
5375+
53785376
if (npassed_args >= 1)
53795377
rewrite_args.arg1 = rewriter->getArg(2)->setType(RefType::BORROWED);
53805378
if (npassed_args >= 2)

0 commit comments

Comments
 (0)