Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:92063 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 69449 invoked from network); 1 Apr 2016 15:41:24 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 1 Apr 2016 15:41:24 -0000 Authentication-Results: pb1.pair.com smtp.mail=cornelius.howl@gmail.com; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=cornelius.howl@gmail.com; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.214.175 as permitted sender) X-PHP-List-Original-Sender: cornelius.howl@gmail.com X-Host-Fingerprint: 209.85.214.175 mail-ob0-f175.google.com Received: from [209.85.214.175] ([209.85.214.175:34640] helo=mail-ob0-f175.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 2F/C2-42107-2A69EF65 for ; Fri, 01 Apr 2016 10:41:22 -0500 Received: by mail-ob0-f175.google.com with SMTP id kf9so124520664obc.1 for ; Fri, 01 Apr 2016 08:41:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc; bh=jTieEaN+7+P6GgJSGsMJh8rEEd4it5QZiwC8GRoHEJY=; b=NCHSfieLjsaVsB6tCt2LYpviJKrQySoxb/wT4qKfFGCCy2/PSoMffYs5OElIVxURmH PSrLErGUKsmn1p0qVA16ImSc5nopvFfKOKFrQTGxew/p8BMvM5vhRVQEvrzdPLJyfXSx v6K3thxTdeW83EDV1RwNh0/h2J8lwV0Md4zNGNRR+9JcjhFksZSnSwW9HggDbv+6g+08 bYrH+SZtwmagipFw181BkgE8RhNkm8v73E/RonWW2KDc/ie5XqdIl6IDKTc+0EWzWKmS YjGnPmbF1p8FxnSTh55eejLTwPfxoxjp6wL+jDZ8J3djD6Y0D1hO7uwyAuUN7yWgiaGV pHGQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc; bh=jTieEaN+7+P6GgJSGsMJh8rEEd4it5QZiwC8GRoHEJY=; b=YAQQiUQ6W9R5F4zEmlR1MoZUzywQ4a7EbDZ1aJxIDH8b4lU0e+2mOcgn8sIynj5HRN OwRW++eu0SpqpAN9NDoJFiS2rpX8RwKp3WPdyPl+C6RzpGZV+BAORRWWqOwQpHTMVN6j eRWvSTWz/18ny0s/+lBQSY7twTiPy1eTJI6JHQZe/+ZRm07qIW/vtfDm/px7pvGuK0a0 K3qj2gJeQKCaNNIcbA9cli551EL3gOlv11rnNF3oDhyBsounkxRetunJZ/hy/pQO3Kaa 2QNlpevm2JkEOp5Sxh6h2ADqN0I1qz+4zA1Dhy6yRXrlEdRkz1nejwMjs6CYIaChhIML m1+g== X-Gm-Message-State: AD7BkJK4WtHWfD4A1BAwXf1S0s8/XU+CeEs/2LzvkLrDfSlwCYf3D/CJ3/w19qdidU34cshvqb9X9dzU6uOD5w== MIME-Version: 1.0 X-Received: by 10.182.27.98 with SMTP id s2mr5557321obg.50.1459525279402; Fri, 01 Apr 2016 08:41:19 -0700 (PDT) Received: by 10.157.7.194 with HTTP; Fri, 1 Apr 2016 08:41:18 -0700 (PDT) In-Reply-To: References: Date: Fri, 1 Apr 2016 23:41:18 +0800 Message-ID: To: Dmitry Stogov Cc: internals , Xinchen Hui , Nikita Popov Content-Type: multipart/alternative; boundary=089e013a0896d1d300052f6e35f3 Subject: Re: [PHP-DEV] Object getter method optimization From: cornelius.howl@gmail.com (Lin Yo-An) --089e013a0896d1d300052f6e35f3 Content-Type: text/plain; charset=UTF-8 Hi internals, Here comes the result: Without getter optimization (3 runs): 250.76603889465ms With getter optimization (3 runs) 110.88299751282ms Microbench result: https://gist.github.com/c9s/0273ac21631562724cabf86c42e86e32 On Fri, Apr 1, 2016 at 4:35 PM, Lin Yo-An wrote: > Hi Dmitry, Nikita, Andrea > > > My implementation now is able to get the property offset and fetch object > property directly without invoking zend_std_read_property and pushing new > call frame onto the stack. > > The current behavior: > > 1. In compile-time, the pass_two() function now marks the getter functions > in op_array.accessor.type > > 2. When Zend Engine first time attempt to read the property, it saves the > property offset in the accessor field and mark the method as a "getter". > > 3. When Zend Engine second time invoke the getter method, it checks the > accessor field and try to read the property value directly instead a > "method call" > > > > The implementation did some change: > > 1. Added accessor struct to op_array to save "accessor" related > information (getter or setter, property offset) > > 2. Added two statement in zend_std_read_property to save property offset. > > 3. Added op code check in zend_compile (The pass_two() function) to mark a > function is a getter) > > > But now I encountered a problem, I can't store the result value in > INIT_METHOD_CALL op, the result var is only available in DO_FCALL_* > > > > I have an idea for solving this, but I'm not sure if it's good or not: > > > If DO_FCALL_* will always follow a INIT_METHOD_CALL, then I think we can > store result var from the next op (DO_FCALL) and skip DO_FCALL directly. > > > Would be great if I can have your advices and suggestion. :-) > > > Thanks, Yo-An Lin > > > > > > > > > > > > > > > > > > > On Tue, Mar 22, 2016 at 4:45 PM, Dmitry Stogov wrote: > >> Hi Yo-An Lin, >> >> >> This "run-time inlining" approach may work. >> >> >> PHP compiler (or optimizer) may mark functions and methods suitable for >> "run-time" inlining (e.g. methods without arguments and FETCH_OBJ_R UNUSED, >> CONST -> TMP; RETURN TMP). >> >> Then INIT_METHOD_CALL may check this flag and execute "optimized code >> sequence" instead of pushing stack frame and real call. >> >> >> However, I'm not sure what kind of performance impact this may make, >> because we will have to make additional check on each INIT_METHOD_CALL >> execution. >> >> >> Thanks. Dmitry. >> >> >> ------------------------------ >> *From:* Lin Yo-An >> *Sent:* Saturday, March 19, 2016 10:08 >> *To:* Dmitry Stogov >> *Cc:* internals; Xinchen Hui >> *Subject:* Re: [PHP-DEV] Object getter method optimization >> >> Hi Dmitry, >> >> >> Thanks for your reply! You're correct. let me try to explain your points: >> >> If I have a main.php and worker.php >> >> And I defined work($worker) { $status = $worker->getStatus(); } inside >> main.php >> >> when main.php is compiled, we don't know what the class entry of $worker >> is. What we only know is invoking a method "getStatus" on $worker CV unless >> we know we have to compile worker.php before main.php and add a type hint >> on $worker. >> >> Is it correct? >> >> >> Since the original approach doesn't work, here comes another new idea: >> >> When executing method call on an object, if we found the method body are >> just 2 op codes (FETCH_OBJ_R and RETURN), we then denote the method is a >> "getter method" >> >> And the next time, when we execute the same method, we found the "getter >> method" flag, we simply execute FETCH_OBJ_R on that object and return the >> value to avoid extra op code execution time. >> >> Do you think if this could work? >> >> >> >> >> Best Regards and Thanks for your work on PHP VM >> Yo-An Lin >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> On Fri, Mar 18, 2016 at 3:36 PM, Dmitry Stogov wrote: >> >>> Hi Yo-An Lin, >>> >>> Unfortunately, this approach won't work. >>> At first, at compile time we don't know the body of called getter. >>> At second, the called method might be changed even at run-time, because >>> of polymorphism. >>> >>> Tricks like this might be implemented using JIT and polymorphic inline >>> caches. >>> >>> Thanks. Dmitry. >>> >>> ________________________________________ >>> From: Lin Yo-An >>> Sent: Friday, March 18, 2016 05:23 >>> To: internals >>> Subject: [PHP-DEV] Object getter method optimization >>> >>> Hello Everyone, >>> >>> >>> I am recently trying to write an optimizer that could optimize the getter >>> method call into just one object fetch opcode. >>> >>> I'd like to know thoughts from you guys, here is the note: >>> https://c9s.hackpad.com/INLINE-OP-TVGo9WcshbZ >>> >>> -- >>> Best Regards, >>> >>> Yo-An Lin >>> https://github.com/c9s >>> >> >> >> >> -- >> Best Regards, >> >> Yo-An Lin >> > > > > -- > Best Regards, > > Yo-An Lin > -- Best Regards, Yo-An Lin --089e013a0896d1d300052f6e35f3--