Hello,
Can somebody point me to where the concatenation operator is implemented ? "." operator.
Thanks,
Hi,
2012/6/5 Adi Mutu adi_mutu06@yahoo.com:
Hello,
Can somebody point me to where the concatenation operator is implemented ? "." operator.
Thanks,
See http://lxr.php.net/xref/PHP_TRUNK/Zend/zend_vm_def.h#133
--
Regards,
Felipe Pena
that's nice, but i haven't understood a thing...i know something about php core and php extensions, but nothing about the Zend engine specific.
Can you point me to some resources on this topic?
Thanks,
From: Felipe Pena felipensp@gmail.com
To: Adi Mutu adi_mutu06@yahoo.com
Cc: PHP Developers Mailing List internals@lists.php.net
Sent: Tuesday, June 5, 2012 11:17 PM
Subject: Re: [PHP-DEV] concatenation operator
Hi,
2012/6/5 Adi Mutu adi_mutu06@yahoo.com:
Hello,
Can somebody point me to where the concatenation operator is implemented ? "." operator.
Thanks,
See http://lxr.php.net/xref/PHP_TRUNK/Zend/zend_vm_def.h#133
--
Regards,
Felipe Pena
that's nice, but i haven't understood a thing...i know something about
php core and php extensions, but nothing about the Zend engine
specific.
The mentioned place is directly in the VM, which in general is harder to
understand, but well, it directs to the "concat_function" on
http://lxr.php.net/xref/PHP_TRUNK/Zend/zend_operators.c#1234
Knowing basic C should be enough to understand the code there. The
actual "algorithm" can also easily be guessed (allocate a buffer which
can hold both strings at once and copy them over,the code is a tiny bit
more complex as it tries tore use an existing buffer than allocating
something completely new)
The question is: What do you actually want to know?
Can you point me to some resources on this topic?
Unfortunately not. The source is the best documentation we have for
that.
johannes
Ok Johannes, thanks for the answer. I'll try to look deeper.
I basically just wanted to know what happens when you concatenate two strings? what emalloc/efree happens.
Also can you tell me if possible how to put a breakpoint to emalloc/efree which are executed only after all core functions are registered? because it takes like a million years like this and a million F8 presses...
Thanks.
From: Johannes Schlüter johannes@schlueters.de
To: Adi Mutu adi_mutu06@yahoo.com
Cc: Felipe Pena felipensp@gmail.com; PHP Developers Mailing List internals@lists.php.net
Sent: Thursday, June 7, 2012 10:44 PM
Subject: Re: [PHP-DEV] concatenation operator
that's nice, but i haven't understood a thing...i know something about
php core and php extensions, but nothing about the Zend engine
specific.
The mentioned place is directly in the VM, which in general is harder to
understand, but well, it directs to the "concat_function" on
http://lxr.php.net/xref/PHP_TRUNK/Zend/zend_operators.c#1234
Knowing basic C should be enough to understand the code there. The
actual "algorithm" can also easily be guessed (allocate a buffer which
can hold both strings at once and copy them over,the code is a tiny bit
more complex as it tries tore use an existing buffer than allocating
something completely new)
The question is: What do you actually want to know?
Can you point me to some resources on this topic?
Unfortunately not. The source is the best documentation we have for
that.
johannes
Ok Johannes, thanks for the answer. I'll try to look deeper.
I basically just wanted to know what happens when you concatenate two
strings? what emalloc/efree happens.
This depends. As always. As said what has to be done is one allocation
for the result value ... and then the zval magic, which depends on
refcount, references, ...
Also can you tell me if possible how to put a breakpoint to
emalloc/efree which are executed only after all core functions are
registered? because it takes like a million years like this and a
million F8 presses...
Depends on your debugger. Most allow conditional breakpoints or have a
breakpoint and while holding at some place add a few more ...
For such a question my preference is using DTrace (on Solaris, Mac or
BSD), something like this session:
$ cat test.d
#!/sbin/dtrace
pid$target::concat_function:entry {
self->in_concat = 1;
}
pid$target::execute:return {
self->in_concat = 0;
}
pid$target::_emalloc:entry
/ self->in_concat /
{
trace(arg0);
ustack();
}
pid$target::_erealloc:entry
/ self->in_concat /
{
trace(arg0);
trace(arg1);
ustack();
}
$ cat test1.php
<?php
$a = "foo"; $b = "bar"; $a.$b;
$ dtrace -s test.d -c 'php test1.php'
dtrace: script 'test.d' matched 4 probes
dtrace: pid 16406 has exited
CPU ID FUNCTION:NAME
3 100372 _emalloc:entry 7
php`_emalloc
php`concat_function+0x270
php`ZEND_CONCAT_SPEC_CV_CV_HANDLER+0xcd
php`execute+0x3d9
php`dtrace_execute+0xe7
php`zend_execute_scripts+0xf5
php`php_execute_script+0x2e8
php`do_cli+0x864
php`main+0x6e2
php`_start+0x83
$ cat test2.php
<?php
$a = 23; $b = "bar"; $a.$b;
$ dtrace -s test.d -c 'php test2.php'
dtrace: script 'test.d' matched 4 probes
dtrace: pid 16425 has exited
CPU ID FUNCTION:NAME
1 100373 _erealloc:entry 0 79
php`_erealloc
php`xbuf_format_converter+0x11ee
php`vspprintf+0x34
php`zend_spprintf+0x2f
php`_convert_to_string+0x174
php`zend_make_printable_zval+0x5ec
php`concat_function+0x3c
php`ZEND_CONCAT_SPEC_CV_CV_HANDLER+0xcd
php`execute+0x3d9
php`dtrace_execute+0xe7
php`zend_execute_scripts+0xf5
php`php_execute_script+0x2e8
php`do_cli+0x864
php`main+0x6e2
php`_start+0x83
1 100372 _emalloc:entry 6
php`_emalloc
php`concat_function+0x270
php`ZEND_CONCAT_SPEC_CV_CV_HANDLER+0xcd
php`execute+0x3d9
php`dtrace_execute+0xe7
php`zend_execute_scripts+0xf5
php`php_execute_script+0x2e8
php`do_cli+0x864
php`main+0x6e2
php`_start+0x83
So, when having two constant strings there's a single malloc, in this
case allocating 7 bytes (strlen("foo")+strlen("bar")+1), if you have a
different type it has to be converted first ...
johannes
Hello,
Sorry for the late reply, I was away for a while......
I don't think I have dtrace because I'm on fedora.....but i'll research.
If i would want to set a breakpoint after php's initialization process, but right before the scripts execution, so that after that I can set breakpoints to emalloc and efree which are executed only during my scripts execution where should i set it? Hope the question was clear enough.....
dtrace related:
Why have you used 'execute:return' and not concat_function:return? What's with the execute function?
Thanks,
A.
From: Johannes Schlüter johannes@schlueters.de
To: Adi Mutu adi_mutu06@yahoo.com
Cc: Felipe Pena felipensp@gmail.com; PHP Developers Mailing List internals@lists.php.net
Sent: Thursday, June 7, 2012 11:18 PM
Subject: Re: [PHP-DEV] concatenation operator
Ok Johannes, thanks for the answer. I'll try to look deeper.
I basically just wanted to know what happens when you concatenate two
strings? what emalloc/efree happens.
This depends. As always. As said what has to be done is one allocation
for the result value ... and then the zval magic, which depends on
refcount, references, ...
Also can you tell me if possible how to put a breakpoint to
emalloc/efree which are executed only after all core functions are
registered? because it takes like a million years like this and a
million F8 presses...
Depends on your debugger. Most allow conditional breakpoints or have a
breakpoint and while holding at some place add a few more ...
For such a question my preference is using DTrace (on Solaris, Mac or
BSD), something like this session:
$ cat test.d
#!/sbin/dtrace
pid$target::concat_function:entry {
self->in_concat = 1;
}
pid$target::execute:return {
self->in_concat = 0;
}
pid$target::_emalloc:entry
/ self->in_concat /
{
trace(arg0);
ustack();
}
pid$target::_erealloc:entry
/ self->in_concat /
{
trace(arg0);
trace(arg1);
ustack();
}
$ cat test1.php
<?php
$a = "foo"; $b = "bar"; $a.$b;
$ dtrace -s test.d -c 'php test1.php'
dtrace: script 'test.d' matched 4 probes
dtrace: pid 16406 has exited
CPU ID FUNCTION:NAME
3 100372 _emalloc:entry 7
php_emalloc php
concat_function+0x270
phpZEND_CONCAT_SPEC_CV_CV_HANDLER+0xcd php
execute+0x3d9
phpdtrace_execute+0xe7 php
zend_execute_scripts+0xf5
phpphp_execute_script+0x2e8 php
do_cli+0x864
phpmain+0x6e2 php
_start+0x83
$ cat test2.php
<?php
$a = 23; $b = "bar"; $a.$b;
$ dtrace -s test.d -c 'php test2.php'
dtrace: script 'test.d' matched 4 probes
dtrace: pid 16425 has exited
CPU ID FUNCTION:NAME
1 100373 _erealloc:entry 0 79
php_erealloc php
xbuf_format_converter+0x11ee
phpvspprintf+0x34 php
zend_spprintf+0x2f
php_convert_to_string+0x174 php
zend_make_printable_zval+0x5ec
phpconcat_function+0x3c php
ZEND_CONCAT_SPEC_CV_CV_HANDLER+0xcd
phpexecute+0x3d9 php
dtrace_execute+0xe7
phpzend_execute_scripts+0xf5 php
php_execute_script+0x2e8
phpdo_cli+0x864 php
main+0x6e2
php_start+0x83 1 100372 _emalloc:entry 6 php
_emalloc
phpconcat_function+0x270 php
ZEND_CONCAT_SPEC_CV_CV_HANDLER+0xcd
phpexecute+0x3d9 php
dtrace_execute+0xe7
phpzend_execute_scripts+0xf5 php
php_execute_script+0x2e8
phpdo_cli+0x864 php
main+0x6e2
php`_start+0x83
So, when having two constant strings there's a single malloc, in this
case allocating 7 bytes (strlen("foo")+strlen("bar")+1), if you have a
different type it has to be converted first ...
johannes
Sorry for the late reply, I was away for a while......
I don't think I have dtrace because I'm on fedora.....but i'll
research.
As said: Currently only on Solaris, MacOS and BSD. Oracle is porting
DTrace to Oracle Linux. RedHat created SystemTap which is similar, ut I
have never used it.
If i would want to set a breakpoint after php's initialization
process, but right before the scripts execution, so that after that I
can set breakpoints to emalloc and efree which are executed only
during my scripts execution where should i set it? Hope the question
was clear enough.....
Depends on your view what "initialization" is. But execute() might be a
place which helps ... but even then you will see many things you're
probably not interested in. Only thing that helps is learning the code
structure and digging through it.
dtrace related:
Why have you used 'execute:return' and not concat_function:return?
What's with the execute function?
That was a bug since I quickly edited an older script. In this case it
doesn't change the result.
johannes
By initialization i mean the latest point possible where I can set a breakpoint, but right before my scripts starts executing it's emalloc's or efree's.....
but even then you will see many things you're probably not interested in
such as?......
Only thing that helps is learning the code structure and digging through it.
Any hint/documentation to learn that?
Thanks.
From: Johannes Schlüter johannes@schlueters.de
To: Adi Mutu adi_mutu06@yahoo.com
Cc: Felipe Pena felipensp@gmail.com; PHP Developers Mailing List internals@lists.php.net
Sent: Saturday, June 30, 2012 12:36 AM
Subject: Re: [PHP-DEV] concatenation operator
Sorry for the late reply, I was away for a while......
I don't think I have dtrace because I'm on fedora.....but i'll
research.
As said: Currently only on Solaris, MacOS and BSD. Oracle is porting
DTrace to Oracle Linux. RedHat created SystemTap which is similar, ut I
have never used it.
If i would want to set a breakpoint after php's initialization
process, but right before the scripts execution, so that after that I
can set breakpoints to emalloc and efree which are executed only
during my scripts execution where should i set it? Hope the question
was clear enough.....
Depends on your view what "initialization" is. But execute() might be a
place which helps ... but even then you will see many things you're
probably not interested in. Only thing that helps is learning the code
structure and digging through it.
dtrace related:
Why have you used 'execute:return' and not concat_function:return?
What's with the execute function?
That was a bug since I quickly edited an older script. In this case it
doesn't change the result.
johannes
By initialization i mean the latest point possible where I can set a
breakpoint, but right before my scripts starts executing it's
emalloc's or efree's.....
Does "executing" include "compilation"? Does it include creating a stack
frame etc. for the "main" routine? ...
but even then you will see many things you're probably not
interested insuch as?......
Well, PHP is complex, it does quite a few things in order to run a
seemingly small script.
Only thing that helps is learning the code structure and digging
through it.Any hint/documentation to learn that?
Use the source. ;-)
A bit more seriously: No, there's no good single place to look at, there
are different blogs etc looking at specific pieces in detail, but the
best thing to do is looking at the code (the filenames in Zend/ give a
good idea what they are for ...), take a question and time and start
digging. For some things it's also good to look into xdebug, vld,
runkit, ... and see where they hook in to do their magic. And well, the
path from main() in sapi/cli/php_cli.c to execute() is not that long,
what then happens is a bit more complicated though (while then again,
once you're in, quite easy for most parts, too)
johannes
Only thing that helps is learning the code structure and digging
through it.Any hint/documentation to learn that?
Use the source. ;-)
A bit more seriously: No, there's no good single place to look at, there
are different blogs etc looking at specific pieces in detail, but the
best thing to do is looking at the code (the filenames in Zend/ give a
good idea what they are for ...), take a question and time and start
digging. For some things it's also good to look into xdebug, vld,
runkit, ... and see where they hook in to do their magic. And well, the
path from main() in sapi/cli/php_cli.c to execute() is not that long,
what then happens is a bit more complicated though (while then again,
once you're in, quite easy for most parts, too)johannes
There is a wiki page linking to some useful resources: https://wiki.php.net/internals/references
Chris