@@ -3674,31 +3674,6 @@ Box* callattrInternal(Box* obj, BoxedString* attr, LookupScope scope, CallattrRe
3674
3674
3675
3675
int npassed_args = argspec.totalPassed ();
3676
3676
3677
- if (rewrite_args && !rewrite_args->args_guarded ) {
3678
- // TODO duplication with runtime_call
3679
- // TODO should know which args don't need to be guarded, ex if we're guaranteed that they
3680
- // already fit, either since the type inferencer could determine that,
3681
- // or because they only need to fit into an UNKNOWN slot.
3682
-
3683
- if (npassed_args >= 1 )
3684
- rewrite_args->arg1 ->addAttrGuard (offsetof (Box, cls), (intptr_t )arg1->cls );
3685
- if (npassed_args >= 2 )
3686
- rewrite_args->arg2 ->addAttrGuard (offsetof (Box, cls), (intptr_t )arg2->cls );
3687
- if (npassed_args >= 3 )
3688
- rewrite_args->arg3 ->addAttrGuard (offsetof (Box, cls), (intptr_t )arg3->cls );
3689
-
3690
- if (npassed_args > 3 ) {
3691
- for (int i = 3 ; i < npassed_args; i++) {
3692
- // TODO if there are a lot of args (>16), might be better to increment a pointer
3693
- // rather index them directly?
3694
- RewriterVar* v = rewrite_args->args ->getAttr ((i - 3 ) * sizeof (Box*), Location::any ());
3695
- v->addAttrGuard (offsetof (Box, cls), (intptr_t )args[i - 3 ]->cls );
3696
- }
3697
- }
3698
-
3699
- rewrite_args->args_guarded = true ;
3700
- }
3701
-
3702
3677
// right now I don't think this is ever called with INST_ONLY?
3703
3678
assert (scope != INST_ONLY);
3704
3679
@@ -5173,61 +5148,70 @@ Box* runtimeCallInternal(Box* obj, CallRewriteArgs* rewrite_args, ArgPassSpec ar
5173
5148
return rtn;
5174
5149
}
5175
5150
5176
- if (rewrite_args) {
5177
- if (!rewrite_args->args_guarded ) {
5178
- // TODO should know which args don't need to be guarded, ex if we're guaranteed that they
5179
- // already fit, either since the type inferencer could determine that,
5180
- // or because they only need to fit into an UNKNOWN slot.
5181
-
5182
- int kwargs_index = -1 ;
5183
- if (argspec.has_kwargs )
5184
- kwargs_index = argspec.kwargsIndex ();
5185
-
5186
- for (int i = 0 ; i < npassed_args; i++) {
5187
- Box* v = getArg (i, arg1, arg2, arg3, args);
5188
-
5189
- if (i == kwargs_index) {
5190
- if (v == NULL ) {
5191
- // I don't think this case should ever get hit currently -- the only places
5192
- // we offer rewriting are places that don't have the ability to pass a NULL
5193
- // kwargs.
5194
- getArg (i, rewrite_args)->addGuard (0 );
5195
- } else {
5196
- getArg (i, rewrite_args)->addAttrGuard (offsetof (Box, cls), (intptr_t )v->cls );
5197
- }
5198
- } else {
5199
- assert (v);
5200
- getArg (i, rewrite_args)->addAttrGuard (offsetof (Box, cls), (intptr_t )v->cls );
5201
- }
5202
- }
5203
- rewrite_args->args_guarded = true ;
5204
- }
5205
- }
5206
5151
5207
5152
if (obj->cls == function_cls || obj->cls == builtin_function_or_method_cls) {
5208
5153
BoxedFunctionBase* f = static_cast <BoxedFunctionBase*>(obj);
5209
-
5210
- if (rewrite_args && !rewrite_args->func_guarded ) {
5211
- rewrite_args->obj ->addGuard ((intptr_t )f);
5212
- rewrite_args->func_guarded = true ;
5213
- rewrite_args->rewriter ->addDependenceOn (f->dependent_ics );
5214
- }
5154
+ auto md = f->md ;
5215
5155
5216
5156
// Some functions are sufficiently important that we want them to be able to patchpoint themselves;
5217
5157
// they can do this by setting the "internal_callable" field:
5218
- auto callable = f-> md ->internal_callable .get <S>();
5158
+ auto callable = md->internal_callable .get <S>();
5219
5159
5220
5160
if (S == CAPI)
5221
- assert ((bool (f-> md ->internal_callable .get (CXX)) == bool (callable))
5161
+ assert ((bool (md->internal_callable .get (CXX)) == bool (callable))
5222
5162
&& " too many opportunities for mistakes unless both CXX and CAPI versions are implemented" );
5223
5163
else
5224
- assert ((bool (f-> md ->internal_callable .get (CAPI)) == bool (callable))
5164
+ assert ((bool (md->internal_callable .get (CAPI)) == bool (callable))
5225
5165
&& " too many opportunities for mistake unless both CXX and CAPI versions are implementeds" );
5226
5166
5227
5167
if (callable == NULL ) {
5228
5168
callable = callFunc<S>;
5229
5169
}
5230
5170
5171
+ if (rewrite_args) {
5172
+ if (!rewrite_args->args_guarded ) {
5173
+ bool does_not_need_guards
5174
+ = callable == &callFunc<S> && (md->always_use_version || md->versions .empty ()
5175
+ || (md->versions .size () == 1
5176
+ && md->versions [0 ]->spec ->accepts_all_inputs ));
5177
+ if (!does_not_need_guards) {
5178
+ // TODO should know which args don't need to be guarded, ex if we're guaranteed that they
5179
+ // already fit, either since the type inferencer could determine that,
5180
+ // or because they only need to fit into an UNKNOWN slot.
5181
+
5182
+ int kwargs_index = -1 ;
5183
+ if (argspec.has_kwargs )
5184
+ kwargs_index = argspec.kwargsIndex ();
5185
+
5186
+ for (int i = 0 ; i < npassed_args; i++) {
5187
+ Box* v = getArg (i, arg1, arg2, arg3, args);
5188
+
5189
+ if (i == kwargs_index) {
5190
+ if (v == NULL ) {
5191
+ // I don't think this case should ever get hit currently -- the only places
5192
+ // we offer rewriting are places that don't have the ability to pass a NULL
5193
+ // kwargs.
5194
+ getArg (i, rewrite_args)->addGuard (0 );
5195
+ } else {
5196
+ getArg (i, rewrite_args)->addAttrGuard (offsetof (Box, cls), (intptr_t )v->cls );
5197
+ }
5198
+ } else {
5199
+ assert (v);
5200
+ getArg (i, rewrite_args)->addAttrGuard (offsetof (Box, cls), (intptr_t )v->cls );
5201
+ }
5202
+ }
5203
+ rewrite_args->args_guarded = true ;
5204
+ }
5205
+ }
5206
+ }
5207
+
5208
+
5209
+ if (rewrite_args && !rewrite_args->func_guarded ) {
5210
+ rewrite_args->obj ->addGuard ((intptr_t )f);
5211
+ rewrite_args->func_guarded = true ;
5212
+ rewrite_args->rewriter ->addDependenceOn (f->dependent_ics );
5213
+ }
5214
+
5231
5215
KEEP_ALIVE (f);
5232
5216
Box* res = callable (f, rewrite_args, argspec, arg1, arg2, arg3, args, keyword_names);
5233
5217
return res;
0 commit comments