hacking hhvm
TRANSCRIPT
![Page 1: Hacking hhvm](https://reader036.vdocuments.us/reader036/viewer/2022062316/58ee5f1c1a28ab1f1f8b4663/html5/thumbnails/1.jpg)
Hacking HHVMWaqar Alamgir@wajrcs [email protected] Aug 13, 2015
![Page 2: Hacking hhvm](https://reader036.vdocuments.us/reader036/viewer/2022062316/58ee5f1c1a28ab1f1f8b4663/html5/thumbnails/2.jpg)
“What is HHVM?”
![Page 3: Hacking hhvm](https://reader036.vdocuments.us/reader036/viewer/2022062316/58ee5f1c1a28ab1f1f8b4663/html5/thumbnails/3.jpg)
HHVM is not a source code transformerThat was HPHPc, it’s dead.
▪ Runs your PHP pages live,just like PHP
▪ Uses a builtin web serveror FastCGI – Runs anywhere(on 64-bit x86 linux)
▪ Drop-in replacement for PHP(mostly)
Webserver(apache, nginx,
etc…)
Database(mysql, posges,mongo, redis,
etc…)
cart.phphome.php
login.php
index.php
PHPAPC
![Page 4: Hacking hhvm](https://reader036.vdocuments.us/reader036/viewer/2022062316/58ee5f1c1a28ab1f1f8b4663/html5/thumbnails/4.jpg)
HHVM is not a source code transformerThat was HPHPc, it’s dead.
▪ Runs your PHP pages live,just like PHP
▪ Uses a builtin web serveror FastCGI – Runs anywhere(on 64-bit x86 linux)
▪ Drop-in replacement for PHP(mostly)
Webserver(apache, nginx,
etc…)
Database(mysql, posges,mongo, redis,
etc…)
cart.phphome.php
login.php
index.php
HHVM
Just Plug and Pray!
Erm, I mean… Play
![Page 5: Hacking hhvm](https://reader036.vdocuments.us/reader036/viewer/2022062316/58ee5f1c1a28ab1f1f8b4663/html5/thumbnails/5.jpg)
HHVM supports (most) PHP syntaxTracking HEAD▪ Pending: Splat (5.6)(Variadics work already)
▪ Finally
▪ Generators▪ Namespaces
And some of its own▪ Scalar type hint(and much much more)
▪ Async co-routines▪ Generics▪ Collections (smart arrays)
▪ XHP (Integrated XHTML)▪ User Attributes
![Page 6: Hacking hhvm](https://reader036.vdocuments.us/reader036/viewer/2022062316/58ee5f1c1a28ab1f1f8b4663/html5/thumbnails/6.jpg)
HHVM’s Parity Gap• Only about 60% of PHP’s unit tests pass.
• 20 top framework (and more) do pass.
• So I wouldn’t sweat the small stuff.
![Page 7: Hacking hhvm](https://reader036.vdocuments.us/reader036/viewer/2022062316/58ee5f1c1a28ab1f1f8b4663/html5/thumbnails/7.jpg)
HHVM is easy to installIf you’re on Ubuntu▪ deb http://dl.hhvm.com/ubuntu saucy main▪ apt-get update▪ apt-get install hhvm (or hhvm-nightly)
▪ Provides one binary covering cli, fcgi server, and libevent server
▪ Coming very soon to a Debian near you!
Or something Debianish…
![Page 8: Hacking hhvm](https://reader036.vdocuments.us/reader036/viewer/2022062316/58ee5f1c1a28ab1f1f8b4663/html5/thumbnails/8.jpg)
HHVM is buildableOn other linux distros (MacOSX in interp mode only)• http://hhvm.com/repo/wiki
• gcc 4.8 or later (soon to be 4.8 or later)
• Boost 1.49 or later
• Lots of other dependencies….
• git clone [email protected]:facebook/hhvmcmake .make –j
• hphp/hhvm/hhvm xkcd.org/303
![Page 9: Hacking hhvm](https://reader036.vdocuments.us/reader036/viewer/2022062316/58ee5f1c1a28ab1f1f8b4663/html5/thumbnails/9.jpg)
Running a serverBuilt-in HTTP server FastCGIServer { Port = 80 Type = libevent SourceRoot = /var/www}Log { Level = Error UseLogFile = true File = /var/log/hhvm-error.log Access { * { File = /var/log/hhvm-access.log Format = %h %l %u %t \”%r\” %>s %b }}}
VirtualHost {…}StaticFile {…}
Server { Port = 9000 Type = fastcgi SourceRoot = /var/www}Log { Level = Error UseLogFile = true File = /var/log/hhvm-error.log Access { * { File = /var/log/hhvm-access.log Format = %h %l %u %t \”%r\” %>s %b }}}
Requires patched libevent
![Page 10: Hacking hhvm](https://reader036.vdocuments.us/reader036/viewer/2022062316/58ee5f1c1a28ab1f1f8b4663/html5/thumbnails/10.jpg)
Running a FastCGI servernginx HHVMserver { server_name www.example.com;
root /var/www; index index.php;
location ~ \.php$ { fastcgi_pass unix:/var/run/hhvm.sock fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /var/www$fastcgi_script_name; include fastcgi_param; }}
Server { FileSocket = /var/run/hhvm.sock Type = fastcgi SourceRoot = /var/www}Log { Level = Error UseLogFile = true File = /var/log/hhvm-error.log Access { * { File = /var/log/hhvm-access.log Format = %h %l %u %t \”%r\” %>s %b }}}
![Page 11: Hacking hhvm](https://reader036.vdocuments.us/reader036/viewer/2022062316/58ee5f1c1a28ab1f1f8b4663/html5/thumbnails/11.jpg)
HPHPC in 2010 - 2011• Crazy cross compiler.
• Converts php to C++.
HHVM in 2013• Complete new VM.
• Facebook is running it on Production.
• Great community, over 750 pull requests.
![Page 12: Hacking hhvm](https://reader036.vdocuments.us/reader036/viewer/2022062316/58ee5f1c1a28ab1f1f8b4663/html5/thumbnails/12.jpg)
PHP is webscale HHVM’s JIT is the secret sauce
![Page 13: Hacking hhvm](https://reader036.vdocuments.us/reader036/viewer/2022062316/58ee5f1c1a28ab1f1f8b4663/html5/thumbnails/13.jpg)
HHVM – Bytecode interpreter
• PHP5 style bytecode execution
• APC-like caching of bytecodes
• Perf about on par with PHP
Modified? InvalidateCache
Compile to
Bytecode
RunBytecode
Y
N
![Page 14: Hacking hhvm](https://reader036.vdocuments.us/reader036/viewer/2022062316/58ee5f1c1a28ab1f1f8b4663/html5/thumbnails/14.jpg)
HHVM – Native code JIT
• Bytecodes run a few times “cold”
• Variable type inference
• Hotpath detection
• Transform to native code
Modified? InvalidateCache
Compile to
BytecodeHave native?
Run Native
Hot?
RunBytecode
Compile to
Native
Y
Y
Y
N
N
N
![Page 15: Hacking hhvm](https://reader036.vdocuments.us/reader036/viewer/2022062316/58ee5f1c1a28ab1f1f8b4663/html5/thumbnails/15.jpg)
HHVM – Compiling to Native
![Page 16: Hacking hhvm](https://reader036.vdocuments.us/reader036/viewer/2022062316/58ee5f1c1a28ab1f1f8b4663/html5/thumbnails/16.jpg)
HHVM – Repo Authoritative Mode
• “Production Mode”
• Improved offline pre-analysis
• Assumes no changes
• Another 10% or so perf gain
PreCompile
Bytecode
Have native?
Run Native
Hot?
RunBytecode
Compile to
Native
Y
Y
N
N
![Page 17: Hacking hhvm](https://reader036.vdocuments.us/reader036/viewer/2022062316/58ee5f1c1a28ab1f1f8b4663/html5/thumbnails/17.jpg)
HHVM – Warming Up Server
![Page 18: Hacking hhvm](https://reader036.vdocuments.us/reader036/viewer/2022062316/58ee5f1c1a28ab1f1f8b4663/html5/thumbnails/18.jpg)
Your CPU on PHP.
![Page 19: Hacking hhvm](https://reader036.vdocuments.us/reader036/viewer/2022062316/58ee5f1c1a28ab1f1f8b4663/html5/thumbnails/19.jpg)
![Page 20: Hacking hhvm](https://reader036.vdocuments.us/reader036/viewer/2022062316/58ee5f1c1a28ab1f1f8b4663/html5/thumbnails/20.jpg)
![Page 21: Hacking hhvm](https://reader036.vdocuments.us/reader036/viewer/2022062316/58ee5f1c1a28ab1f1f8b4663/html5/thumbnails/21.jpg)
![Page 22: Hacking hhvm](https://reader036.vdocuments.us/reader036/viewer/2022062316/58ee5f1c1a28ab1f1f8b4663/html5/thumbnails/22.jpg)
![Page 23: Hacking hhvm](https://reader036.vdocuments.us/reader036/viewer/2022062316/58ee5f1c1a28ab1f1f8b4663/html5/thumbnails/23.jpg)
Magento (Daniel Sloof)https://t.co/UB1aOzJ73c
![Page 24: Hacking hhvm](https://reader036.vdocuments.us/reader036/viewer/2022062316/58ee5f1c1a28ab1f1f8b4663/html5/thumbnails/24.jpg)
Magento (Daniel Sloof)https://t.co/UB1aOzJ73c
![Page 25: Hacking hhvm](https://reader036.vdocuments.us/reader036/viewer/2022062316/58ee5f1c1a28ab1f1f8b4663/html5/thumbnails/25.jpg)
Symfony(Christian Stocker)
Requests per Secondhttp://bit.ly/1fCRw99
![Page 26: Hacking hhvm](https://reader036.vdocuments.us/reader036/viewer/2022062316/58ee5f1c1a28ab1f1f8b4663/html5/thumbnails/26.jpg)
Symfony(Christian Stocker)
Page load Timehttp://bit.ly/1fCRw99
![Page 27: Hacking hhvm](https://reader036.vdocuments.us/reader036/viewer/2022062316/58ee5f1c1a28ab1f1f8b4663/html5/thumbnails/27.jpg)
HPHPd – HPHP Debugger
• Interactive shell
• GDB-like debugging
• Standalone or w/ server
• Breakpoints
• Watches
• Macros
![Page 28: Hacking hhvm](https://reader036.vdocuments.us/reader036/viewer/2022062316/58ee5f1c1a28ab1f1f8b4663/html5/thumbnails/28.jpg)
Extending HHVMYou *can* do that in PHP
![Page 29: Hacking hhvm](https://reader036.vdocuments.us/reader036/viewer/2022062316/58ee5f1c1a28ab1f1f8b4663/html5/thumbnails/29.jpg)
Writing a PHP Extension…zend_bool array_column_param_helper(zval **param, const char *name TSRMLS_DC) { switch (Z_TYPE_PP(param)) { case IS_DOUBLE: convert_to_long_ex(param); case IS_LONG: return 1; case IS_OBJECT: convert_to_string_ex(param); case IS_STRING: return 1; default: php_error_docref(NULL TSRMLS_CC, E_WARNING, "The %s key should be either a string or an integer", name); return 0; }}PHP_FUNCTION(array_column) { zval **zcolumn = NULL, **zkey = NULL, **data; HashTable *arr_hash; HashPosition pointer;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "hZ!|Z!", &arr_hash, &zcolumn, &zkey) == FAILURE) { return; } if ((zcolumn && !array_column_param_helper(zcolumn, "column" TSRMLS_CC)) || (zkey && !array_column_param_helper(zkey, "index" TSRMLS_CC))) { RETURN_FALSE; } array_init(return_value); for (zend_hash_internal_pointer_reset_ex(arr_hash, &pointer); zend_hash_get_current_data_ex(arr_hash, (void**)&data, &pointer) == SUCCESS; zend_hash_move_forward_ex(arr_hash, &pointer)) { zval **zcolval, **zkeyval = NULL; HashTable *ht; if (Z_TYPE_PP(data) != IS_ARRAY) { continue; } ht = Z_ARRVAL_PP(data); if (!zcolumn) { zcolval = data; } else if ((Z_TYPE_PP(zcolumn) == IS_STRING) && (zend_hash_find(ht, Z_STRVAL_PP(zcolumn), Z_STRLEN_PP(zcolumn) + 1, (void**)&zcolval) == FAILURE)) { continue; } else if ((Z_TYPE_PP(zcolumn) == IS_LONG) && (zend_hash_index_find(ht, Z_LVAL_PP(zcolumn), (void**)&zcolval) == FAILURE)) { continue; } if (zkey && (Z_TYPE_PP(zkey) == IS_STRING)) { zend_hash_find(ht, Z_STRVAL_PP(zkey), Z_STRLEN_PP(zkey) + 1, (void**)&zkeyval); } else if (zkey && (Z_TYPE_PP(zkey) == IS_LONG)) { zend_hash_index_find(ht, Z_LVAL_PP(zkey), (void**)&zkeyval); } Z_ADDREF_PP(zcolval); if (zkeyval && Z_TYPE_PP(zkeyval) == IS_STRING) { add_assoc_zval(return_value, Z_STRVAL_PP(zkeyval), *zcolval); } else if (zkeyval && Z_TYPE_PP(zkeyval) == IS_LONG) { add_index_zval(return_value, Z_LVAL_PP(zkeyval), *zcolval); } else if (zkeyval && Z_TYPE_PP(zkeyval) == IS_OBJECT) { SEPARATE_ZVAL(zkeyval); convert_to_string(*zkeyval); add_assoc_zval(return_value, Z_STRVAL_PP(zkeyval), *zcolval); } else { add_next_index_zval(return_value, *zcolval); } }}
![Page 30: Hacking hhvm](https://reader036.vdocuments.us/reader036/viewer/2022062316/58ee5f1c1a28ab1f1f8b4663/html5/thumbnails/30.jpg)
The same function in HHVM<?php
function array_column(array $arr, $col, $key = null) { $ret = []; foreach($arr as $key => $val) { if (!is_array($val)) continue; $cval = ($col === null) ? $val : $val[$col]; if ($key === null || !isset($val[$key])) {
$ret[] = $cval; } else { $ret[$val[$key]] = $cval; } } return $ret;}
![Page 31: Hacking hhvm](https://reader036.vdocuments.us/reader036/viewer/2022062316/58ee5f1c1a28ab1f1f8b4663/html5/thumbnails/31.jpg)
Crossing the PHP->C++ barrierArray HHVM_FUNCTION(array_column, CArrRef arr, CVarRef col, CVarRef key) { Array ret; for (auto &pair : arr) { Variant key = pair.first, val = pair.second; if (val.isArray()) continue; Array aval = val.toArray(); Variant cval = col.isNull() ? aval : aval[col]; if (key.isNull() || !aval.exists(key)) { ret.append(cval); } else { ret[aval[key]] = cval; } } return ret;}
![Page 32: Hacking hhvm](https://reader036.vdocuments.us/reader036/viewer/2022062316/58ee5f1c1a28ab1f1f8b4663/html5/thumbnails/32.jpg)
Questions ?
![Page 33: Hacking hhvm](https://reader036.vdocuments.us/reader036/viewer/2022062316/58ee5f1c1a28ab1f1f8b4663/html5/thumbnails/33.jpg)
Resources
• http://hhvm.com/repo
• http://hhvm.com/blog
• http://hhvm.com/twitter
• http://docs.hhvm.com
• hphp/doc in git repository for Options and Technical… Stuff
• Freenode / #hhvm
• http://hhvm.com/fb/page
• http://hhvm.com/fb/general
• @HipHopVM
• @HackLang