[PHP-DEV] Re: Object getter method optimization

2016-04-12 Thread Lin Yo-An
On Mon, Apr 11, 2016 at 11:53 PM, Dmitry Stogov  wrote:

> Or... maybe we shall move the function info related functions into the
> core? since we might have some optimization based on the function info
> instead of optimizing opcode only in the future.
>
> We consider, possibility of moving the whole Optimizer into Zend, but it
> won't change a lot, because expensive optimization make sense only with
> opcache (when script is optimized once and executed many times).
>

Is this something I can help? I mean, moving the core of func info into the
core.

I think I might need to postpone the accessor optimization before the
func_info is integrated into the core since it's the best place to store
the accessor information.



Best Regards,

Yo-An Lin


[PHP-DEV] Re: Object getter method optimization

2016-04-11 Thread Dmitry Stogov
I think, It's going to be a part of opcache.

Today, all PHP processes use shared bytecode, with JIT we will in addition 
share the native code.


Thanks. Dmitry.



From: Lin Yo-An 
Sent: Monday, April 11, 2016 19:04
To: Dmitry Stogov
Cc: Xinchen Hui; Nikita Popov; Bob Weinand; Joe Watkins; internals
Subject: Re: Object getter method optimization



On Mon, Apr 11, 2016 at 11:53 PM, Dmitry Stogov 
> wrote:

We consider, possibility of moving the whole Optimizer into Zend, but it won't 
change a lot, because expensive optimization make sense only with opcache (when 
script is optimized once and executed many times).

Do you (or the team?) prefer to keep the JIT implementation as an extension or 
integrate the JIT implementation into the Zend core?


Thanks, Yo-An


[PHP-DEV] Re: Object getter method optimization

2016-04-11 Thread Lin Yo-An
On Mon, Apr 11, 2016 at 11:53 PM, Dmitry Stogov  wrote:
>
>

> We consider, possibility of moving the whole Optimizer into Zend, but it
> won't change a lot, because expensive optimization make sense only with
> opcache (when script is optimized once and executed many times).
>

Do you (or the team?) prefer to keep the JIT implementation as an extension
or integrate the JIT implementation into the Zend core?


Thanks, Yo-An


[PHP-DEV] Re: Object getter method optimization

2016-04-11 Thread Dmitry Stogov

Hi Yo-An

On 04/11/2016 02:54 PM, Lin Yo-An wrote:

Hi Dmitry,

How's it going?

I traversed the code of opcache extension, and just found the 
FUNC_INFO related macros.  I guess the accessor information is more 
like an entry that should be put in the function info.


That, FUNC_INFO is available only during optimization (it's especially 
used in inter-procedure data-flow pass).
Or... maybe we shall move the function info related functions into the 
core? since we might have some optimization based on the function info 
instead of optimizing opcode only in the future.
We consider, possibility of moving the whole Optimizer into Zend, but it 
won't change a lot, because expensive optimization make sense only with 
opcache (when script is optimized once and executed many times).




And I think the function info we pre-processed in the compile-time 
would help JIT to compile the opcode a lot.
Of course. Actually, the new optimization passes introduced in "master" 
branch came from our zend-jit project and reused to generate LLVM code.


By the way, would you mind to let me know the plan of implementing the 
JIT compilation in PHP? I saw your zend-jit branch is using LLVM as 
the backend.
We don't have special plans yet. We are going to work on JIT later, and 
now we mainly work on interpretative optimizations.
Once we start JIT, it's going to be much difficult to change something 
in VM...


In my experience, LLVM compiles large code a lot of slower.  what do 
you think of using DynASM as the JIT backend?

Right. LLVM is not suitable for JIT. It's a compiler without front-end part.
We will probably go with DynASM from LuaJIT, Low Level Interpreter from 
WebKit or our own similar approach.


V8 compiles ast nodes into native code directly without 
interpreting/translating the op codes, I don't know if it's a good 
approach to try. your thoughts?
In my experience, this approach doesn't work well especially with big 
PHP applications.


Thanks. Dmitry.


Cheers, Yo-An









[PHP-DEV] Re: Object getter method optimization

2016-04-11 Thread Lin Yo-An
Hi Dmitry,

How's it going?

I traversed the code of opcache extension, and just found the FUNC_INFO
related macros.  I guess the accessor information is more like an entry
that should be put in the function info.

Or... maybe we shall move the function info related functions into the
core? since we might have some optimization based on the function info
instead of optimizing opcode only in the future.

And I think the function info we pre-processed in the compile-time would
help JIT to compile the opcode a lot.

By the way, would you mind to let me know the plan of implementing the JIT
compilation in PHP? I saw your zend-jit branch is using LLVM as the backend.

In my experience, LLVM compiles large code a lot of slower.  what do you
think of using DynASM as the JIT backend?

V8 compiles ast nodes into native code directly without
interpreting/translating the op codes, I don't know if it's a good approach
to try. your thoughts?


Cheers, Yo-An


[PHP-DEV] Re: Object getter method optimization

2016-04-07 Thread Lin Yo-An
Yeah I know. I've saw that yesterday.


[PHP-DEV] Re: Object getter method optimization

2016-04-07 Thread Dmitry Stogov
did you see my patch? It already uses run_time_cache of calling op_array to get 
getter property offset.


It's also possible to "allocate" slots in "run_time_cache" of caller op_array 
at compile_time, increasing op_array->cache_size. (see zend_compile.c), but I 
don't see a big reason to do it.


Thanks. Dmitry.



From: Lin Yo-An 
Sent: Tuesday, April 5, 2016 17:32
To: Dmitry Stogov
Cc: Xinchen Hui; Nikita Popov; Bob Weinand; Joe Watkins; internals
Subject: Re: Object getter method optimization

On Tue, Apr 5, 2016 at 10:14 PM, Dmitry Stogov 
> wrote:

I think, op_array->type and op_array->fn_flags can't be reused.

Also, usage of op_array->run_time_cache is safer (I remember, I saw some 
SIGSEGV with your patch and opcache.protect_memory=1)

Got it.Does run_time_cache vary when caller is different? maybe I can use 
the first 2 bytes for the accessor information.

Cheers, Yo-An


[PHP-DEV] Re: Object getter method optimization

2016-04-05 Thread Lin Yo-An
On Tue, Apr 5, 2016 at 10:14 PM, Dmitry Stogov  wrote:

> I think, op_array->type and op_array->fn_flags can't be reused.
>
> Also, usage of op_array->run_time_cache is safer (I remember, I saw some
> SIGSEGV with your patch and opcache.protect_memory=1)
>
Got it.Does run_time_cache vary when caller is different? maybe I can
use the first 2 bytes for the accessor information.

Cheers, Yo-An


[PHP-DEV] Re: Object getter method optimization

2016-04-05 Thread Lin Yo-An
I updated my PR here
https://github.com/php/php-src/pull/1847/files#diff-3054389ad750ce9a9f5895cd6d27800fR3159


On Tue, Apr 5, 2016 at 10:02 PM, Lin Yo-An  wrote:

> sorry, one typo, the "op_array->type" should be "op_array->fn_flags"
>



-- 
Best Regards,

Yo-An Lin


[PHP-DEV] Re: Object getter method optimization

2016-04-05 Thread Lin Yo-An
sorry, one typo, the "op_array->type" should be "op_array->fn_flags"


[PHP-DEV] Re: Object getter method optimization

2016-04-05 Thread Dmitry Stogov
I think, op_array->type and op_array->fn_flags can't be reused.

Also, usage of op_array->run_time_cache is safer (I remember, I saw some 
SIGSEGV with your patch and opcache.protect_memory=1)


Most probably, I'll able to return to this idea only at the end of the week or 
even on next week.


Thanks. Dmitry.



From: Lin Yo-An 
Sent: Tuesday, April 5, 2016 17:00
To: Dmitry Stogov
Cc: Xinchen Hui; Nikita Popov; Bob Weinand; Joe Watkins; internals
Subject: Re: Object getter method optimization

Hi Dmitry,


Glad to hear your news, I just checked your patch and I like the approach 
you've done. :]

I'm also still working on this idea this week, the const value accessor support 
was just added today.  And I guess we may also support setters in the future 
(if possible)

my thought is:

- I think the getter optimization is useful since getter methods are heavily 
used in a lot of application like Drupal (like hundreds)

- If we could produce more information in compile-time, we can reduce more 
runtime cost when executing the opcode handler. This way, we can reduce the 
impact to the overall performance.

- I found the first two bytes in zend_op_array produces a 2 bytes room on 32bit 
machine and even more on 64bit machine because the memory alignment (not sure 
if it could be optimzed when memory alignment optimization is not enabled with 
gcc)


My first attempt was to add a new flag in op_array->type, however it's already 
full, all bits are used currently.

I think we can either extend the op_array type to uint32 or just add a new 
zend_uchar field to save the information (from the 2 bytes room). And using 
cache slot to save the property offset information.

This field will be not only for simple getters, but also for simple setters and 
functions return const or return values that are simplified to scalar value.

Your thoughts?



Cheers, Yo-An









On Tue, Apr 5, 2016 at 7:29 PM, Dmitry Stogov 
> wrote:

Hi Yo-An Lin,


I spent few hours working on your idea and came to the following path.


https://gist.github.com/dstogov/2221ffc21ac16311c958a4830dbcee0f


I tried to keep binary compatibility, minimize run-time checks overhead and fix 
related problems and leaks.

BTW I'm not sure, if I like the patch even in this state.


The patch significantly speed-ups getters (more than 2 times) in small cost for 
all other methods, but the final effect on application may be negative.

Of course, we may add specialized opcode for INIT_METHOD_CALL without 
arguments, that would almost completely eliminate overhead.


Anyway, I like to listen opinions:

- if we should include such optimizations?

- do you see any other applications to similar optimizations?


Thanks. Dmitry.



From: Lin Yo-An >
Sent: Sunday, April 3, 2016 11:10
To: Xinchen Hui
Cc: Dmitry Stogov; internals; Nikita Popov
Subject: Re: Object getter method optimization

I submitted the new benchmark result here:

Benchmark Result
Getter Method Only

https://gist.github.com/8cd230a5601cbe38439661adf3caca0d

Without getter optimization (3 runs):
151.0169506073ms

With getter optimization (3 runs)
39.201021194458ms

Template Engine Benchmark

https://gist.github.com/a23cf294dfcf74683b8f02d93a47bc5b

With getter optimization:
1118ms

Without getter optimization:
1235ms

Affect

Other Microbench result: 
https://gist.github.com/c9s/0273ac21631562724cabf86c42e86e32

On Sat, Apr 2, 2016 at 11:29 AM, Lin Yo-An 
> wrote:
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 > 於 2016年4月1日 星期五寫道:

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 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".
I am not sure if I understand you correctly, but.. have you consider this case?

a;
} else {
return $this->b;
}
}
}


$a = new A();
echo $a->nomeaning;
echo $a->nomeaning;
?>

thanks


[PHP-DEV] Re: Object getter method optimization

2016-04-05 Thread Lin Yo-An
Hi Dmitry,


Glad to hear your news, I just checked your patch and I like the approach
you've done. :]

I'm also still working on this idea this week, the const value accessor
support was just added today.  And I guess we may also support setters in
the future (if possible)

my thought is:

- I think the getter optimization is useful since getter methods are
heavily used in a lot of application like Drupal (like hundreds)

- If we could produce more information in compile-time, we can reduce more
runtime cost when executing the opcode handler. This way, we can reduce the
impact to the overall performance.

- I found the first two bytes in zend_op_array produces a 2 bytes room on
32bit machine and even more on 64bit machine because the memory alignment
(not sure if it could be optimzed when memory alignment optimization is not
enabled with gcc)


My first attempt was to add a new flag in op_array->type, however it's
already full, all bits are used currently.

I think we can either extend the op_array type to uint32 or just add a new
zend_uchar field to save the information (from the 2 bytes room). And using
cache slot to save the property offset information.

This field will be not only for simple getters, but also for simple setters
and functions return const or return values that are simplified to scalar
value.

Your thoughts?



Cheers, Yo-An









On Tue, Apr 5, 2016 at 7:29 PM, Dmitry Stogov  wrote:

> Hi Yo-An Lin,
>
>
> I spent few hours working on your idea and came to the following path.
>
>
> https://gist.github.com/dstogov/2221ffc21ac16311c958a4830dbcee0f
>
>
> I tried to keep binary compatibility, minimize run-time checks overhead
> and fix related problems and leaks.
>
> BTW I'm not sure, if I like the patch even in this state.
>
>
> The patch significantly speed-ups getters (more than 2 times) in small
> cost for all other methods, but the final effect on application may be
> negative.
>
> Of course, we may add specialized opcode for INIT_METHOD_CALL without
> arguments, that would almost completely eliminate overhead.
>
>
> Anyway, I like to listen opinions:
>
> - if we should include such optimizations?
>
> - do you see any other applications to similar optimizations?
>
>
> Thanks. Dmitry.
>
>
> --
> *From:* Lin Yo-An 
> *Sent:* Sunday, April 3, 2016 11:10
> *To:* Xinchen Hui
> *Cc:* Dmitry Stogov; internals; Nikita Popov
> *Subject:* Re: Object getter method optimization
>
> I submitted the new benchmark result here:
>
> Benchmark Result Getter Method Only
>
> https://gist.github.com/8cd230a5601cbe38439661adf3caca0d
>
> Without getter optimization (3 runs):
> 151.0169506073ms
>
> With getter optimization (3 runs)
> 39.201021194458ms
> Template Engine Benchmark
>
> https://gist.github.com/a23cf294dfcf74683b8f02d93a47bc5b
>
> With getter optimization:
> 1118ms
>
> Without getter optimization:
> 1235ms
> Affect
>
> Other Microbench result:
> https://gist.github.com/c9s/0273ac21631562724cabf86c42e86e32
>
> On Sat, Apr 2, 2016 at 11:29 AM, Lin Yo-An 
> wrote:
>
>> 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  於 2016年4月1日 星期五寫道:
>>
>> 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
 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".

>>> I am not sure if I understand you correctly, but.. have you consider
>>> this case?
>>>
>>> >> class A {
>>> private $a = 1;
>>> private $b = 2;
>>> public function __get($name) {
>>> static $is_first = 1;
>>> if ($is_first) {
>>> $is_first = 0;
>>> return $this->a;
>>> } else {
>>> return $this->b;
>>> }
>>> }
>>> }
>>>
>>>
>>> $a = 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 

[PHP-DEV] Re: Object getter method optimization

2016-04-05 Thread Dmitry Stogov
Hi Yo-An Lin,


I spent few hours working on your idea and came to the following path.


https://gist.github.com/dstogov/2221ffc21ac16311c958a4830dbcee0f


I tried to keep binary compatibility, minimize run-time checks overhead and fix 
related problems and leaks.

BTW I'm not sure, if I like the patch even in this state.


The patch significantly speed-ups getters (more than 2 times) in small cost for 
all other methods, but the final effect on application may be negative.

Of course, we may add specialized opcode for INIT_METHOD_CALL without 
arguments, that would almost completely eliminate overhead.


Anyway, I like to listen opinions:

- if we should include such optimizations?

- do you see any other applications to similar optimizations?


Thanks. Dmitry.



From: Lin Yo-An 
Sent: Sunday, April 3, 2016 11:10
To: Xinchen Hui
Cc: Dmitry Stogov; internals; Nikita Popov
Subject: Re: Object getter method optimization

I submitted the new benchmark result here:

Benchmark Result
Getter Method Only

https://gist.github.com/8cd230a5601cbe38439661adf3caca0d

Without getter optimization (3 runs):
151.0169506073ms

With getter optimization (3 runs)
39.201021194458ms

Template Engine Benchmark

https://gist.github.com/a23cf294dfcf74683b8f02d93a47bc5b

With getter optimization:
1118ms

Without getter optimization:
1235ms

Affect

Other Microbench result: 
https://gist.github.com/c9s/0273ac21631562724cabf86c42e86e32

On Sat, Apr 2, 2016 at 11:29 AM, Lin Yo-An 
> wrote:
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 > 於 2016年4月1日 星期五寫道:

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 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".
I am not sure if I understand you correctly, but.. have you consider this case?

a;
} else {
return $this->b;
}
}
}


$a = 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 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 

[PHP-DEV] Re: Object getter method optimization

2016-04-03 Thread Lin Yo-An
I submitted the new benchmark result here:

Benchmark ResultGetter Method Only

https://gist.github.com/8cd230a5601cbe38439661adf3caca0d

Without getter optimization (3 runs):
151.0169506073ms

With getter optimization (3 runs)
39.201021194458ms
Template Engine Benchmark

https://gist.github.com/a23cf294dfcf74683b8f02d93a47bc5b

With getter optimization:
1118ms

Without getter optimization:
1235ms
Affect

Other Microbench result:
https://gist.github.com/c9s/0273ac21631562724cabf86c42e86e32

On Sat, Apr 2, 2016 at 11:29 AM, Lin Yo-An  wrote:

> 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  於 2016年4月1日 星期五寫道:
>
> 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
>>> 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".
>>>
>> I am not sure if I understand you correctly, but.. have you consider this
>> case?
>>
>> > class A {
>> private $a = 1;
>> private $b = 2;
>> public function __get($name) {
>> static $is_first = 1;
>> if ($is_first) {
>> $is_first = 0;
>> return $this->a;
>> } else {
>> return $this->b;
>> }
>> }
>> }
>>
>>
>> $a = 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 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 

[PHP-DEV] Re: Object getter method optimization

2016-04-01 Thread Lin Yo-An
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  於 2016年4月1日 星期五寫道:

> 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 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".
>>
> I am not sure if I understand you correctly, but.. have you consider this
> case?
>
>  class A {
> private $a = 1;
> private $b = 2;
> public function __get($name) {
> static $is_first = 1;
> if ($is_first) {
> $is_first = 0;
> return $this->a;
> } else {
> return $this->b;
> }
> }
> }
>
>
> $a = 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 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, 

[PHP-DEV] Re: Object getter method optimization

2016-03-21 Thread Lin Yo-An
>
>
>> I was playing with this idea sometime ago, it gives good performance
> boost for code like `for ($i = 0; $i < 10; $i++) $a->getFoo();` but in
> the end of the day it's a very limited optimization.
> If you abstract away from getters and say you want to optimize more and
> more small functions like this one, you end up realizing that what you're
> actually doing is what JIT compilation would do in a more generic way.


I agree with you that JIT could achieve this.

Although this could be done by JIT, however the JIT approach would require
good code generation to produce efficient getter code to return the
property value, and there will be a JIT threshold and extra compilation
time for caller to reach.







> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
>
>

-- 
Sent from Gmail Mobile