<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><br class=""><div><br class=""><blockquote type="cite" class=""><div class="">On Sep 12, 2018, at 12:09 AM, Aditya K <<a href="mailto:hiraditya@msn.com" class="">hiraditya@msn.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class=""><br class=""><blockquote type="cite" class="">Objective-C allows method implementations to be replaced  dynamically.  It is not obvious that `objc_subclassing_restricted` in  any > way prevents either this or similar techniques where a dynamic  subclass is formed in order to change the implementation of a <br class="">method  on a particular instance.<br class=""></blockquote><br class="">Can we revise the semantics of `objc_subclassing_restricted` to disallow subclassing dynamically?<br class=""></div></div></blockquote><div><br class=""></div>No.  In general, we can't take existing attributes and make them mean something much stronger.</div><div><br class=""><blockquote type="cite" class=""><div class=""><div class=""><blockquote type="cite" class="">Objective-C also allows the class of a particular instance to be  changed, although I think it would be fair to restrict this to ensure  <br class="">that the new class is related in some reasonable way to the old class —  probably that it must have the old class (ignoring  dynamic > subclasses) as a superclass.<br class=""></blockquote><br class="">Yes, I guess while utilizing some of the super-dynamic behavior of Objective-C, it may be tricky to take advantage of devirutalization. We may need to have proper documentation etc. to make the programmers aware of the expected behavior as a result of this optimization.<br class=""></div></div></blockquote><div><br class=""></div>It needs to be opt-in.  You can't really fix "we changed the basic semantics of the language" with documentation.</div><div><br class=""><blockquote type="cite" class=""><div class=""><div class=""><blockquote type="cite" class="">There are some other concerns that apply to devirtualization in general, but not to your restricted case:<br class="">  - The receiver of a message send is generally allowed to be `nil`.<br class=""></blockquote>That was the reason why I restricted the optimization to work only for messages passed to self because, IIUC, self cannot be nil.<br class=""></div></div></blockquote><div><br class=""></div>That seems reasonable.  It also prevents proxy objects.</div><div><br class=""><blockquote type="cite" class=""><div class=""><div class=""><blockquote type="cite" class="">  - Objective-C is not strongly typed.  Instance-variable accesses  have C-like restrictions, but otherwise static type information is  <br class="">defined to only be meaningful for determining the type signature for  message sends, not for determining the actual dynamic  type. > For example, several major libraries rely on the ability to  create "proxy" objects that transparently forward most messages to  <br class="">another object.<br class=""></blockquote><br class=""><blockquote type="cite" class="">Ultimately, while I think devirtualization would be very powerful  in Objective-C, I think it really needs to be opted-in in some more  <br class="">explicit way.<br class=""></blockquote><br class="">We can have a compiler flag to enable Objective-C devirtualization. Additionally we can introduce an __attribute__((objc_local_method)) to enable finer grained control of devirtualization.<br class=""></div></div></blockquote><div><br class=""></div>I don't think an optimization that globally miscompiles Objective-C's dynamic features unless an attribute is used to suppress it is ever going to be acceptable, even if it's an opt-in flag.  So given that the optimization has to be opt-in with some new attribute, I don't think the flag adds anything.<br class=""><br class=""><blockquote type="cite" class=""><div class=""><div class="">Thanks for the review, I can start putting the patches for review if you think the overall approach seems reasonable.</div></div></blockquote><div><br class=""></div></div>I haven't really thought about the technical approach.  Assorted thoughts:<div class="">- The attribute could maybe just be the "inline" keyword, which both seems appropriate and is not otherwise used on Objective-C methods.</div><div class="">- You need some way to make synthesized property accessors inlinable.</div><div class="">- For the specific purpose of inlining privately-declared methods of the same class from the @implementation, do you even need a middle-end pass?  Can't this just be straight-up done by the frontend when it sees a use of the method?  (Incidentally, there's yet another reason you really need this to be opt-in for it to work — Objective-C overriding is defined by whether the selectors match, so a method can be legally overridden even if it's not declared outside the @implementation.)</div><div class="">- If we can reliably inline all the callers of the method, should we even add it to the method table?  Maybe it should only be in the method table if it's declared outside the @implementation (or overrides such a method) — users can always add such a declaration in a "private" class extension if they need it in the method table for dynamic reasons but don't want to make the method easily usable externally.</div><div class="">- If a method is declared outside the @implementation, is it actually reasonable to assume that this attribute on its definition means it isn't ever overridden?</div><div class="">- Is there a viable path from this to a more traditional devirtualization optimization?  Is such an optimization ever going to be feasible in Objective-C without a slew of new attributes?</div><div class=""><br class=""></div><div class="">Also, regardless of the technical approach, while you are welcome to work on an implementation, nobody here can actually approve adding it to Clang on our own.  Clang has a policy for language extensions that you can read here:</div><div class="">  <a href="https://clang.llvm.org/get_involved.html" class="">https://clang.llvm.org/get_involved.html</a></div><div class="">It is the longstanding practice of the Clang project to treat Apple as Objective-C's effective governing body; Objective-C is not an open language.  So to add a major feature like this to Clang, you will need to propose it to Apple's internal language committee for Objective-C.  Assuming we can get this into a satisfactory shape, I would be happy to serve as your proxy on this, but I do have to warn you that it can be a slow and frustratingly opaque process.</div><div class=""><br class=""></div><div class="">But I do think it's an interesting feature that would solve a significant problem for Objective-C programmers.  Currently, Objective-C programmers who need inlining for performance have to rewrite their methods as static functions, which requires them to rewrite the method calls as well.  Being able to easily turn those message sends into direct function calls would be great.</div><div class=""><br class=""></div><div class=""><div class=""><div class=""><div class=""><div class="">John.</div></div></div></div></div></body></html>