Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:92067 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 471 invoked from network); 2 Apr 2016 03:29:48 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 2 Apr 2016 03:29:48 -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.218.43 as permitted sender) X-PHP-List-Original-Sender: cornelius.howl@gmail.com X-Host-Fingerprint: 209.85.218.43 mail-oi0-f43.google.com Received: from [209.85.218.43] ([209.85.218.43:33180] helo=mail-oi0-f43.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 39/30-29546-7AC3FF65 for ; Fri, 01 Apr 2016 22:29:45 -0500 Received: by mail-oi0-f43.google.com with SMTP id d205so131467843oia.0 for ; Fri, 01 Apr 2016 20:29:43 -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=wi0NoGVUPB0fUU1rGORsJlmaJP4tf7bGJP6ghNvAbBk=; b=MaXQcrUhajp7NtxYDsED9hrWAs97n1EiNWcc/hdaHlT8Rc5uFFl18bWqFuOR4Z/8nd ZNP1TQcJTGhszoJN+jRmX17v4brecDPzBdDsC2afSvD9Cd/33xpbgdXDu63nF+zZiAVy NpKZxAONfi8LjLnHSlCs02U0ukrt2QWC1HnbrmKgp99teaU4IvwbwjKgCx5eBbKx/QWW OjOTFaHAhi+9FGuQzvh6q0URPxQgZAuTk9ZFgPXntnykMjca9WREnkRJxMeOjf1KdjcM PRQiiKsKVnccjZ0RMX9wj69aMMTpz4b36xhIYn8oCla+ahJiuB/yXCcBb7pcARwXpB0F rRdQ== 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=wi0NoGVUPB0fUU1rGORsJlmaJP4tf7bGJP6ghNvAbBk=; b=WJ1zb1xPQzzEW61Qr41dgGcVeTWWxpj2llCJ+hTKDYlEVI4Ku4+tPxsh96WjnpMUHC QQXE8vfvzvjbdEq/SUMBR3qUpOKjdfq+d0qc6Vj7NuArvxH56F7ht8wAol2sxZlEQxIw lzbK4OX2ShUT3L2mSBlcrRgGoKvouug6ZJq8w3dYEg7SLG6RIbhUN2ea1sJerGJLdY63 09ZzeCY588Pss4/dqkpCzb4zthv42AEfLNQVjGZ/xRhWSW31AdOz6n+WWG+8D1eJ6310 Pql1XE92Y8KnMJwrWlGpgt/t5N+RaESw4/D2eE6sRy4gZsRczkmIt4z8wniEkTceYfGp GwcQ== X-Gm-Message-State: AD7BkJKAxbDvS2bgMkRU6C4E02++ILo+R8rGsI7qponfWg1bOwEztRo85cCGfWHQzsHKDDV04jaGK3KO2oNBIg== MIME-Version: 1.0 X-Received: by 10.202.83.75 with SMTP id h72mr2599631oib.121.1459567780483; Fri, 01 Apr 2016 20:29:40 -0700 (PDT) Received: by 10.157.7.194 with HTTP; Fri, 1 Apr 2016 20:29:40 -0700 (PDT) In-Reply-To: References: Date: Sat, 2 Apr 2016 11:29:40 +0800 Message-ID: To: Xinchen Hui Cc: Dmitry Stogov , internals , Nikita Popov Content-Type: multipart/alternative; boundary=001a113de8e414daa5052f781bc9 Subject: Re: Object getter method optimization From: cornelius.howl@gmail.com (Lin Yo-An) --001a113de8e414daa5052f781bc9 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Hi Xinchen Hui, The magic get method is not being optimized. This optimization only focuses on simple getter, which is used in a lot of OO-based appoications like Symfony or Drupal. Hi Dimitry, Thanks for reviewing the code, comments are helpful. :) could you explain a little bit of how runtime_cache_slot works? I think adding the property_offset in op_array is kinda like a workaround for POC, and I want to remove it from op_array. Cheers, Yo-An Xinchen Hui =E6=96=BC 2016=E5=B9=B44=E6=9C=881=E6=97=A5 = =E6=98=9F=E6=9C=9F=E4=BA=94=E5=AF=AB=E9=81=93=EF=BC=9A > Hey: > > 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 objec= t >> property directly without invoking zend_std_read_property and pushing ne= w >> 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 th= e >> property offset in the accessor field and mark the method as a "getter". >> > I am not sure if I understand you correctly, but.. have you consider this > case? > > class A { > private $a =3D 1; > private $b =3D 2; > public function __get($name) { > static $is_first =3D 1; > if ($is_first) { > $is_first =3D 0; > return $this->a; > } else { > return $this->b; > } > } > } > > > $a =3D new A(); > echo $a->nomeaning; > echo $a->nomeaning; > ?> > > thanks > >> >> 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 UNU= SED, >>> 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 point= s: >>> >>> If I have a main.php and worker.php >>> >>> And I defined work($worker) { $status =3D $worker->getStatus(); } insid= e >>> main.php >>> >>> when main.php is compiled, we don't know what the class entry of $worke= r >>> is. What we only know is invoking a method "getStatus" on $worker CV un= less >>> we know we have to compile worker.php before main.php and add a type hi= nt >>> 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 ar= e >>> 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 "gette= r >>> method" flag, we simply execute FETCH_OBJ_R on that object and return t= he >>> 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, becaus= e >>>> 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 >> > > > > -- > Xinchen Hui > @Laruence > http://www.laruence.com/ > --=20 Sent from Gmail Mobile --001a113de8e414daa5052f781bc9--