Include Hack
Total Page:16
File Type:pdf, Size:1020Kb
HHVM - PHP++ PAUL TARJAN SARA GOLEMON HHVM OPEN SOURCE HHVM OPEN SOURCE What is HHVM? HHVM is not a source transformer That was HPHPc, it’s dead. ▪ Runs your PHP pages live, just like PHP ▪ Uses standard FastCGI transport ! Database Webserver A PHP P (mysql, posges, ! (apache, nginx, etc…) C mongo, redis, etc…) ▪ Runs anywhere (on 64-bit x86 linux) index.php ▪ Drop-in replacement for PHP login.php home.php (mostly) cart.php HHVM is not a source transformer That was HPHPc, it’s dead. ▪ Runs your PHP pages live, just like PHP ▪ Uses standard FastCGI transport ! Database Webserver HHVM (mysql, posges, ! (apache, nginx, etc…) mongo, redis, etc…) ▪ Runs anywhere (on 64-bit x86 linux) index.php ▪ Drop-in replacement for PHP login.php home.php (mostly) cart.php HHVM supports all PHP syntax Tracking HEAD And some of its own ▪ Splat & Variadics ▪ Scalar type hint (and much much more) ▪ Finally ▪ Async co-routines ! ▪ Generics ▪ Generators ▪ Collections (smart arrays) ▪ Namespaces ▪ XHP (Integrated XHTML) ▪ User Attributes HHVM’s Parity Gap ! • Only about 60% of PHP’s unit tests pass ▪ Missing Extensions ▪ Minor differences in error message output ▪ Most private extensions need a rewrite ! • 20 top frameworks (and more) do pass ▪ So I wouldn’t sweat the small stuff HHVM is easy to install If you’re on Ubuntu Or something Debianish… ▪ deb http://dl.hhvm.com/ubuntu trusty main ▪ apt-get update ▪ apt-get install hhvm (or hhvm-nightly) ▪ Provides one binary covering cli, debugger, & fcgi server ! ▪ Coming very soon to a Debian near you! HHVM is buildable On other linux distros (Mac in interp mode) ▪ http://hhvm.com/repo/wiki ▪ gcc 4.8 or later (We love C++11) ▪ Boost 1.49 or later ▪ Lots of other dependencies…. ▪ git clone [email protected]:facebook/hhvm cmake . make –j ▪ hphp/hhvm/hhvm xkcd.org/303 Running a FastCGI server nginx HHVM server {! hhvm.server.file_socket = /var/run/hhvm.sock! server_name www.example.com;! hhvm.server.type = fastcgi! ! hhvm.server.source_root = /var/www! root /var/www;! ! index index.php;! hhvm.log.level = Error! ! hhvm.log.user_log_file = true! location ~ \.php$ {! hhvm.log.file = /var/log/hhvm-error.log! fastcgi_pass unix:/var/run/hhvm.sock! ! fastcgi_index index.php;! hhvm.log.access.0.file = /var/log/hhvm-access.log! fastcgi_param SCRIPT_FILENAME! hhvm.log.access.0.format=%h %l %u %t \”%r\” %>s %b! /var/www$fastcgi_script_name;! ! include fastcgi_param;! ! }! ! } ! ! ; hhvm -m daemon -c /etc/hhvm/hhvm.ini -u www-data! Open Source means something HHVM’s walled garden HPHPc in 2010 - 2011 Throw it over the wall (FOSDEM 2010) 200 ▪ Handful of internal developers ▪ Irregular “when we get to it” pushes to github 150 ▪ Little curation of tasks/pull-requests 100 ▪ Nearly zero documentation ▪ Brittle build system 50 ▪ Went dark in late 2011 0 HipHop in 2012 “Oh right, we have an OSS project…” 200 ▪ Growing team as HHVM begins to take over from HPHPc ▪ Built out a semi-daily push process (fairly manual) 150 ▪ Begin working through backlog of issues and pull-requests 100 ▪ Still pretty thin on documentation ▪ Update build system 50 ▪ Launched social channels 0 HHVM in 2013 Making Open Source HHVM a priority 200 ▪ Dedicated HHVM-OSS team ▪ Automated most of push process (multiple daily runs) 150 ▪ Declared “bug bankruptcy” (about 500 issues at the time) More than 2000 bugs opened and properly closed since then 100 ▪ Improved process for taking pull-requests More than 750 PRs merged since April 2013 50 ▪ Introduce support for optional and 3rd party extensions 0 ▪ Blogging/Technical articles HHVM in 2014 Bringing down the walls ▪ OSS build integrated with FB’s CI testing ▪ Immediate* mirroring of FB->Github repo ▪ Proper documentation! - docs.hhvm.com ▪ Hack programming language announced ▪ Automated import of github PRs ▪ Internal diffs developed in the open ▪ Inclusion in standard distros** xkcd.org/1205 ▪ Composer support for community-driven extensions** ! * 30 min push window ** Coming in 2nd half of 2014 HHVM Community HHVM Community Who’s already running it? ▪ Facebook: 100% Production traffic since Feb 2013 ▪ Baidu: "Most products migrated to HHVM" ▪ Pocket Rent: github.com/PocketRent/BeatBox ▪ Escalate.EU: Cloud monitoring/alerts ▪ GREE: Games Developer ! ▪ Clearly a lot of people at least trying: 30K downloads in June PHP is webscale HHVM’s JIT is the secret sauce HHVM – Bytecode interpreter ! Y Invalidate Modified? Cache • PHP5 style bytecode execution N • APC-like caching of bytecodes Compile to Bytecode • Perf about on par with PHP5 Run Bytecode HHVM – Native code JIT Y Invalidate Modified? ! Cache ▪ Bytecodes run a few times “cold” N Y ▪ Variable type inference Have Compile to Native? Bytecode ▪ Hotpath detection N ▪ Transform to native code Run Native Y Hot? N Compile to Native Run Bytecode HHVM – Repo Authoritative Mode PreCompile ! Bytecode ▪ “Production Mode” Y ▪ Improved offline pre-analysis Have Native? ▪ Assumes no changes N ! Run Native Y ▪ Another 10-25% perf gain Hot? N Compile to Native Run Bytecode HHVM – Compiling to Native <?php Zend Source Engine Optimized Intermediate Optimized Virtual Bytecode Bytecode Representation IR Assembly Machine OpCache+ Code But don’t take my word for it... Magento (Daniel Sloof) Response time (lower is better) 800 600 400 200 Response time (milliseconds) 0 Homepage Category view Product view Search ‘test’ Add to cart Shopping cart CMS Page PHP 5.5 HHVM Magento (Daniel Sloof) Transaction rate (higher is better) 100 75 50 Transactions per second25 0 Homepage Category view Product view Search ‘test’ Add to cart Shopping cart CMS Page PHP 5.5 HHVM Symfony (Christian Stocker) Requests per Second ( 120 90 60 Requests per Second 30 0 1 2 3 4 5 6 10 20 50 PHP 5.5 HHVM Symfony (Christian Stocker) Page Load Time ( 900 675 450 Page Load Time 225 0 1 2 3 4 5 6 10 20 50 PHP 5.5 HHVM Sure it’s fast, but what else can it do? HACK (yes, it’s a horrible name…) Type Hinting gone mad Static Analysis ▪ Scalars ▪ Analyze entire code tree without running ▪ bool, int, float, num, string ▪ Return typehints ▪ Report type errors like a strictly typed language ▪ Typed properties ▪ Fallback on loose typing ▪ Constructor arg promotion when needed (because that’s what PHP is good at) ▪ Specialization ▪ array<int> ▪ array<string,array<string,stdClass>> HACK <?hh ! Basic Hack class Foo { private int $num = 123; ▪ Static Analyzer traces value public function add(int $delta): Foo { through whole program $this->num += $delta; return $this; } ! public function get(): int { return $this->num; ▪ Looks for mismatches and } public function __construct(int $num): void { reports errors $this->num = $num; } ! } ! $f = new Foo(123); ▪ “Foo::add() expected int” $f->add(456); $f->add(“banana”); “Foo::add() received string” HACK – Constructor arg promotion <?hh ! Avoid repeated patterns class Foo { ! ▪ public/protected/private public function add(int $delta): Foo { $this->num += $delta; as __construct arg modifiers return $this; } ! ! public function get(): int { return $this->num; ▪ Declares the property } ! and initializes from value public function __construct(private int $num) :void { } } ! ! $f = new Foo(123); ▪ echo $f->add(456)->get(); Less boilerplate, more coding HACK – Generics <?hh ! Specialize common code class Foo<T> { public function add(T $delta): Foo { ▪ T is replaced w/ specialization type at $this->num += $delta; return $this; instantiation } ! public function get(): T { ! return $this->num; } ▪ Type-checker propagates replacement ! public function __constructor(private T $num) through generic :void { } ! } ! ! $i = new Foo(123); // Makes a Foo<int> ▪ echo $i->add(456)->get(); Less boilerplate, ! $f = new Foo(3.14); // Makes a Foo<float> more coding echo $f->add(2.17)->get(); HACK – Collections <?hh ! Specialized array objects function foo(Vector<int> $nums, Set<string> $names, ▪ Vector, Set, Map, StableMap Map<int,string> $numNameMap, FrozenVector<int> $nums2): bool { ! ! foreach($nums as $num) { $mappedName = $numNameMap[$num]; ▪ if ($names->contains($mappedName)) { Frozen* return true; Mutable* (default) } } ! ! if ($nums2->count() == 0) return true; return false; } ▪ Support ArrayAccess ▪ Extensive library of methods Async Functions <?hh ! Cooperative Multitasking async function getPage($url) : Awaitable<string> { ▪ Parallelizing made easy $fp = fopen($url, ‘r’); return await async_get_contents($fp); } ! ! // Sends all requests in parallel, ▪ // blocks for response Allow multiple functions to run $pages = await [ cooperatively getPage(‘http://php.net’), getPage(‘http://example.com’), getPage(‘http://hhvm.com’), ! ]; ! ▪ While one is blocking, the other executes hh_server convert - The Hackificator ! ! <?hh function g($y): { ! f(42); function f( $x): { return f(103); if ($x) { } return new Foo(); ! } else { function h(): { return null; g('hello world'); } g(44); } } hh_server convert - The Hackificator ! ! <?hh function g($y): { ! f(42); function f(@int $x): @?Foo { return f(103); if ($x) { } return new Foo(); ! } else { function h(): @void { return null; g('hello world'); } g(44); } } hh_server convert - The Hackificator ! ! <?hh function g($y): @?Foo { ! f(42); function f(@int $x): @?Foo { return f(103); if ($x) { } return new Foo(); ! } else { function h(): @void { return null; g('hello world'); } g(44); } } Hackificating 100% 90% 80% 70% 60% 50% 40% 30% 20% 10% 0 Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec Jan Feb Mar Apr 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2014 2014 2014 2014 User Attributes <?php ! User-defined metadata <<Author(“sgolemon”),Clowny>> function life() { ▪ Arbitrary