Successfully reported this slideshow.

More Related Content

Related Books

Free with a 14 day trial from Scribd

See all

Related Audiobooks

Free with a 14 day trial from Scribd

See all

Hacking hhvm

  1. 1. Hacking HHVM Waqar Alamgir @wajrcs walamgir@folio3.com Aug 13, 2015
  2. 2. “What is HHVM?”
  3. 3. HHVM is not a source code transformer That was HPHPc, it’s dead. ▪ Runs your PHP pages live, just like PHP ▪ Uses a builtin web server or 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.phplogin.php index.php PHP A P C
  4. 4. HHVM is not a source code transformer That was HPHPc, it’s dead. ▪ Runs your PHP pages live, just like PHP ▪ Uses a builtin web server or 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.phplogin.php index.php HHVM Just Plug and Pray! Erm, I mean… Play
  5. 5. HHVM supports (most) PHP syntax Tracking 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
  6. 6. 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.
  7. 7. HHVM is easy to install If 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…
  8. 8. HHVM is buildable On 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 git@github.com:facebook/hhvm cmake . make –j • hphp/hhvm/hhvm xkcd.org/303
  9. 9. Running a server Built-in HTTP server FastCGI Server { 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
  10. 10. Running a FastCGI server nginx HHVM server { 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 }} }
  11. 11. 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.
  12. 12. PHP is webscale HHVM’s JIT is the secret sauce
  13. 13. HHVM – Bytecode interpreter • PHP5 style bytecode execution • APC-like caching of bytecodes • Perf about on par with PHP Modified? Invalidate Cache Compile to Bytecode Run Bytecode Y N
  14. 14. HHVM – Native code JIT • Bytecodes run a few times “cold” • Variable type inference • Hotpath detection • Transform to native code Modified? Invalidate Cache Compile to Bytecode Have native? Run Native Hot? Run Bytecode Compile to Native Y Y Y N N N
  15. 15. HHVM – Compiling to Native
  16. 16. HHVM – Repo Authoritative Mode • “Production Mode” • Improved offline pre-analysis • Assumes no changes • Another 10% or so perf gain PreCompil e Bytecode Have native? Run Native Hot? Run Bytecode Compile to Native Y Y N N
  17. 17. HHVM – Warming Up Server
  18. 18. Your CPU on PHP.
  19. 19. Magento (Daniel Sloof) https://t.co/UB1aOzJ73c
  20. 20. Magento (Daniel Sloof) https://t.co/UB1aOzJ73c
  21. 21. Symfony (Christian Stocker) Requests per Second http://bit.ly/1fCRw99
  22. 22. Symfony (Christian Stocker) Page load Time http://bit.ly/1fCRw99
  23. 23. HPHPd – HPHP Debugger • Interactive shell • GDB-like debugging • Standalone or w/ server • Breakpoints • Watches • Macros
  24. 24. Extending HHVM You *can* do that in PHP
  25. 25. 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); } } }
  26. 26. 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; }
  27. 27. Crossing the PHP->C++ barrier Array 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; }
  28. 28. Questions
  29. 29. 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

Editor's Notes

  • Facebook started to work on HipHop for PHP in 2008. Their goal was to speed up the PHP execution speed and the first version of the project was composed of the tandem HPHPc/HPHPi. HPHPc is a PHP to C++ transpiler which was used to deploy the code to the production servers while HPHPi was an interpreter used during development and debug stages.

    HPHPc did a good job on improving performance but it was not without issues: maintaining both HPHPc and HPHPi in sync proved to be cumbersome plus some differences still existed between the transpiled code vs the interpreted one. That's why back in 2010 Facebook decided to go for another approach and created HHVM – a new virtual machine designed to replace the Zend Engine used by PHP. By the end of 2012 HHVM achieved performance parity with the former HPHPc and soon surpassed it.
  • Facebook started to work on HipHop for PHP in 2008. Their goal was to speed up the PHP execution speed and the first version of the project was composed of the tandem HPHPc/HPHPi. HPHPc is a PHP to C++ transpiler which was used to deploy the code to the production servers while HPHPi was an interpreter used during development and debug stages.

    HPHPc did a good job on improving performance but it was not without issues: maintaining both HPHPc and HPHPi in sync proved to be cumbersome plus some differences still existed between the transpiled code vs the interpreted one. That's why back in 2010 Facebook decided to go for another approach and created HHVM – a new virtual machine designed to replace the Zend Engine used by PHP. By the end of 2012 HHVM achieved performance parity with the former HPHPc and soon surpassed it.

  • Rather than directly interpret or compile PHP code directly to C++, HHVM compiles Hack and PHP into an intermediate bytecode. This bytecode is then translated into x64 machine code dynamically at runtime by a just-in-time (JIT) compiler. This compilation process allows for all sorts of optimizations that cannot be made in a statically compiled binary, thus enabling higher performance of your Hack and PHP programs.
  • Okay to mention that we’re about to move to github.com/hhvm/hhvm
  • This slide isn’t meant to be readable. It just illustrates how onerous writing an extension function for PHP can be.
  • ×