{"id":18761,"date":"2026-03-28T15:08:35","date_gmt":"2026-03-28T15:08:35","guid":{"rendered":"https:\/\/cryptoted.net\/index.php\/2026\/03\/28\/go-ethereums-jit-evm-ethereum-foundation-blog\/"},"modified":"2026-03-28T15:08:35","modified_gmt":"2026-03-28T15:08:35","slug":"go-ethereums-jit-evm-ethereum-foundation-blog","status":"publish","type":"post","link":"https:\/\/cryptoted.net\/index.php\/2026\/03\/28\/go-ethereums-jit-evm-ethereum-foundation-blog\/","title":{"rendered":"Go Ethereum\u2019s JIT-EVM | Ethereum Foundation Blog"},"content":{"rendered":"<p> <br \/>\n<\/p>\n<div id=\"\">\n<p class=\"chakra-text css-gi02ar\">The Ethereum Virtual machine is kind of different than most other Virtual Machines out there. In my\u00a0<a target=\"_blank\" rel=\"noopener\" class=\"chakra-link css-vezwxf\" href=\"https:\/\/medium.com\/@jeff.ethereum\/optimising-the-ethereum-virtual-machine-58457e61ca15\">previous post<\/a>\u00a0I already explained how it\u2019s used and described some of its characteristics.<\/p>\n<blockquote class=\"chakra-code css-gk0tva\"><p>The Ethereum Virtual Machine (EVM) is a simple but powerful, Turing complete 256bit Virtual Machine that allows anyone to execute arbitrary\u00a0<a target=\"_blank\" rel=\"noopener\" class=\"chakra-link css-vezwxf\" href=\"https:\/\/github.com\/ethereum\/go-ethereum\/blob\/master\/core\/vm\/opcodes.go\">EVM Byte Code<\/a>.<\/p><\/blockquote>\n<p>The go-ethereum project contains two implementations of the EVM. A simple and straightforward\u00a0<a target=\"_blank\" rel=\"noopener\" class=\"chakra-link css-vezwxf\" href=\"https:\/\/en.wikipedia.org\/wiki\/Bytecode\">byte-code VM<\/a>\u00a0and a more sophisticated\u00a0<a target=\"_blank\" rel=\"noopener\" class=\"chakra-link css-vezwxf\" href=\"https:\/\/en.wikipedia.org\/wiki\/Just-in-time_compilation\">JIT-VM<\/a>. In this post I\u2019m going to explain some of the differences between the two implementations and describe some of the characteristics of the JIT EVM and why it can be so much faster than the byte-code EVM.<br \/>\n<!-- --><\/p>\n<h3 class=\"chakra-heading group css-xuzltg\" id=\"c1d8\" data-group=\"true\"><a class=\"chakra-link css-128fqrf\" aria-label=\"c1d8 permalink\" href=\"#c1d8\"><svg viewbox=\"0 0 24 24\" focusable=\"false\" class=\"chakra-icon css-173jpr1\"><g fill=\"currentColor\"><path d=\"M10.458,18.374,7.721,21.11a2.853,2.853,0,0,1-3.942,0l-.892-.891a2.787,2.787,0,0,1,0-3.941l5.8-5.8a2.789,2.789,0,0,1,3.942,0l.893.892A1,1,0,0,0,14.94,9.952l-.893-.892a4.791,4.791,0,0,0-6.771,0l-5.8,5.8a4.787,4.787,0,0,0,0,6.77l.892.891a4.785,4.785,0,0,0,6.771,0l2.736-2.735a1,1,0,1,0-1.414-1.415Z\"\/><path d=\"M22.526,2.363l-.892-.892a4.8,4.8,0,0,0-6.77,0l-2.905,2.9a1,1,0,0,0,1.414,1.414l2.9-2.9a2.79,2.79,0,0,1,3.941,0l.893.893a2.786,2.786,0,0,1,0,3.942l-5.8,5.8a2.769,2.769,0,0,1-1.971.817h0a2.766,2.766,0,0,1-1.969-.816,1,1,0,1,0-1.415,1.412,4.751,4.751,0,0,0,3.384,1.4h0a4.752,4.752,0,0,0,3.385-1.4l5.8-5.8a4.786,4.786,0,0,0,0-6.771Z\"\/><\/g><\/svg><\/a>Go-ethereum\u2019s Byte Code Virtual Machine<\/h3>\n<p>The EVM\u2019s internals are pretty simple; it has a single run loop which will attempt to execute the instruction at the current\u00a0<em class=\"chakra-text css-0\">Program Counter (PC<\/em>\u00a0in short). Within this loop the\u00a0<em class=\"chakra-text css-0\">Gas<\/em>\u00a0is calculated for each instruction, memory is expanded if necessary and executes the instruction if the preamble succeeds. This will continue on until the VM either finishes gracefully or returns with an error by throwing an exception (e.g.\u00a0<em class=\"chakra-text css-0\">out-of-gas<\/em>).<\/p>\n<div class=\"chakra-stack css-1jx0in4\">\n<pre><pre style=\"color:white;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none;padding:1em;margin:0.5em 0;overflow:auto;background:#011627\"><code class=\"language-bash\" style=\"color:#d6deeb;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none\"><span class=\"token\" style=\"color:rgb(127, 219, 202)\">for<\/span><span> <\/span><span class=\"token\" style=\"color:rgb(130, 170, 255)\">op<\/span><span> <\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">=<\/span><span> contract<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">[<\/span><span>pc<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">]<\/span><span> <\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">{<\/span><\/code><\/pre>\n<pre style=\"color:white;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none;padding:1em;margin:0.5em 0;overflow:auto;background:#011627\"><code class=\"language-bash\" style=\"color:#d6deeb;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none\"><span>    <\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">if<\/span><span> <\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">!<\/span><span>sufficientGas<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">(<\/span><span>op<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">)<\/span><span> <\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">{<\/span><\/code><\/pre>\n<pre style=\"color:white;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none;padding:1em;margin:0.5em 0;overflow:auto;background:#011627\"><code class=\"language-bash\" style=\"color:#d6deeb;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none\"><span>        <\/span><span class=\"token\" style=\"color:rgb(255, 203, 139)\">return<\/span><span> error<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">(<\/span><span class=\"token\" style=\"color:rgb(173, 219, 103)\">\"insufficient gas for op:\"<\/span><span>, or<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">)<\/span><\/code><\/pre>\n<pre style=\"color:white;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none;padding:1em;margin:0.5em 0;overflow:auto;background:#011627\"><code class=\"language-bash\" style=\"color:#d6deeb;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none\"><span>    <\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">}<\/span><span>\n<\/span><\/code><\/pre>\n<pre style=\"color:white;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none;padding:1em;margin:0.5em 0;overflow:auto;background:#011627\"><code class=\"language-bash\" style=\"color:#d6deeb;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none\"><span>    switch <\/span><span class=\"token\" style=\"color:rgb(130, 170, 255)\">op<\/span><span> <\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">{<\/span><\/code><\/pre>\n<pre style=\"color:white;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none;padding:1em;margin:0.5em 0;overflow:auto;background:#011627\"><code class=\"language-bash\" style=\"color:#d6deeb;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none\"><span>    <\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">case<\/span><span> <\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">..<\/span><span>.:<\/span><\/code><\/pre>\n<pre style=\"color:white;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none;padding:1em;margin:0.5em 0;overflow:auto;background:#011627\"><code class=\"language-bash\" style=\"color:#d6deeb;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none\"><span>        \/* execute *\/<\/span><\/code><\/pre>\n<pre style=\"color:white;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none;padding:1em;margin:0.5em 0;overflow:auto;background:#011627\"><code class=\"language-bash\" style=\"color:#d6deeb;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none\"><span>    <\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">case<\/span><span> RETURN:<\/span><\/code><\/pre>\n<pre style=\"color:white;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none;padding:1em;margin:0.5em 0;overflow:auto;background:#011627\"><code class=\"language-bash\" style=\"color:#d6deeb;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none\"><span>        <\/span><span class=\"token\" style=\"color:rgb(255, 203, 139)\">return<\/span><span> memory<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">[<\/span><span>stack<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">[<\/span><span>-1<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">]<\/span><span>, stack<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">[<\/span><span>-2<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">]<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">]<\/span><\/code><\/pre>\n<pre style=\"color:white;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none;padding:1em;margin:0.5em 0;overflow:auto;background:#011627\"><code class=\"language-bash\" style=\"color:#d6deeb;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none\"><span>    <\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">}<\/span><\/code><\/pre>\n<pre style=\"color:white;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none;padding:1em;margin:0.5em 0;overflow:auto;background:#011627\"><code class=\"language-bash\" style=\"color:#d6deeb;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none\"><span>    pc++<\/span><\/code><\/pre>\n<pre style=\"color:white;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none;padding:1em;margin:0.5em 0;overflow:auto;background:#011627\"><code class=\"language-bash\" style=\"color:#d6deeb;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none\"><span class=\"token\" style=\"color:rgb(199, 146, 234)\">}<\/span><span>\n<\/span><\/code><\/pre>\n<\/div>\n<p>At the end of the execution loop the program-counter gets increment to run the next instruction and continues to do so until it has finished.<\/p>\n<p class=\"chakra-text css-gi02ar\">The EVM has another way to\u00a0<em class=\"chakra-text css-0\">change<\/em>\u00a0the program-counter through something called\u00a0<em class=\"chakra-text css-0\">jump<\/em>-instructions (<em class=\"chakra-text css-0\">JUMP<\/em>\u00a0&amp;\u00a0<em class=\"chakra-text css-0\">JUMPI).\u00a0<\/em>Instead of letting the program-counter increment (pc++) the EVM can also jump to arbitrary positions in the contract code. The EVM knows two jump instructions, a normal jump that reads as \u201c<em class=\"chakra-text css-0\">jump to position X<\/em>\u201d and a conditional jump that read as \u201c<em class=\"chakra-text css-0\">jump to position X if condition Y is true<\/em>\u201d. When either such a jump occurs it must always land on a\u00a0<em class=\"chakra-text css-0\">jump-destination<\/em>. If the program lands on an instruction other than a jump destination the program fails\u200a\u2014\u200ain other words, for a jump to be valid it must always be followed by a jump-destination instruction if the condition yielded true.<\/p>\n<p class=\"chakra-text css-gi02ar\">Prior to running any Ethereum program the EVM iterates over the code and finds all possible jump-destinations, it then puts them in a map that can be referenced by the program-counter to find them. Each and every time the EVM encounters a jump-instructions the jump validity is checked.<\/p>\n<p class=\"chakra-text css-gi02ar\">As you can see the executing code is relatively easy and simply interpreted by the byte-code VM, we may conclude even that through its sheer simplicity it\u2019s actually pretty dumb.<\/p>\n<h3 class=\"chakra-heading group css-xuzltg\" id=\"0544\" data-group=\"true\"><a class=\"chakra-link css-128fqrf\" aria-label=\"0544 permalink\" href=\"#0544\"><svg viewbox=\"0 0 24 24\" focusable=\"false\" class=\"chakra-icon css-173jpr1\"><g fill=\"currentColor\"><path d=\"M10.458,18.374,7.721,21.11a2.853,2.853,0,0,1-3.942,0l-.892-.891a2.787,2.787,0,0,1,0-3.941l5.8-5.8a2.789,2.789,0,0,1,3.942,0l.893.892A1,1,0,0,0,14.94,9.952l-.893-.892a4.791,4.791,0,0,0-6.771,0l-5.8,5.8a4.787,4.787,0,0,0,0,6.77l.892.891a4.785,4.785,0,0,0,6.771,0l2.736-2.735a1,1,0,1,0-1.414-1.415Z\"\/><path d=\"M22.526,2.363l-.892-.892a4.8,4.8,0,0,0-6.77,0l-2.905,2.9a1,1,0,0,0,1.414,1.414l2.9-2.9a2.79,2.79,0,0,1,3.941,0l.893.893a2.786,2.786,0,0,1,0,3.942l-5.8,5.8a2.769,2.769,0,0,1-1.971.817h0a2.766,2.766,0,0,1-1.969-.816,1,1,0,1,0-1.415,1.412,4.751,4.751,0,0,0,3.384,1.4h0a4.752,4.752,0,0,0,3.385-1.4l5.8-5.8a4.786,4.786,0,0,0,0-6.771Z\"\/><\/g><\/svg><\/a>Welcome JIT VM<\/h3>\n<p>The JIT-EVM takes a different approach to running EVM byte-code and is by definition\u00a0<em class=\"chakra-text css-0\">initially<\/em>\u00a0slower than the byte-code VM. Before the VM can run any code it must first\u00a0<em class=\"chakra-text css-0\">compile<\/em>\u00a0the byte-code in to components that can be understood by the JIT VM.<\/p>\n<p class=\"chakra-text css-gi02ar\">The initialisation- and execution procedure is done in 3-steps:<\/p>\n<ol role=\"list\" class=\"css-vgl4zd\">\n<li class=\"css-0\">We check whether there\u2019s a JIT program ready to be run using the hash of the code\u200a\u2014\u200a<em class=\"chakra-text css-0\">H(C)<\/em>\u00a0is used as an identifier to identify the program;<\/li>\n<li class=\"css-0\">if a program was found we run the program and return the result;<\/li>\n<li class=\"css-0\">if no program was found we run the byte-code\u00a0<em class=\"chakra-text css-0\">and<\/em>\u00a0we compile a JIT program in the background.<\/li>\n<\/ol>\n<p class=\"chakra-text css-gi02ar\">Initially I tried to check whether the JIT program had finished compiling and move the execution over to the JIT\u200a\u2014\u200athis all happened during runtime in the same loop using Go\u2019s\u00a0<em class=\"chakra-text css-0\">atomic<\/em>\u00a0package\u200a\u2014\u200aunfortunately it turned out to be slower than letting the byte-code VM run and use the JIT program for every sequential call after the compilation of the program had finished.<\/p>\n<p class=\"chakra-text css-gi02ar\">By compiling the byte-code in to logical pieces the JIT has the ability to analyse the code more precisely and optimise where and whenever necessary.<\/p>\n<p class=\"chakra-text css-gi02ar\">For example an incredible simple optimisation that I did was compiling several\u00a0<em class=\"chakra-text css-0\">push<\/em>\u00a0operation in to a single instruction. Let\u2019s take the\u00a0<em class=\"chakra-text css-0\">CALL\u00a0<\/em>instruction; call requires 7 push instructions\u200a\u2014\u200ai.e. gas, address, value, input-offset, input-size, return-offset and return-size\u200a\u2014\u200aprior to executing it, and what I did instead of looping through these 7 instructions, executing them one by one, I\u2019ve optimised this away by taking the 7 instructions and append the 7 values in to a single slice. Now, whenever the\u00a0<em class=\"chakra-text css-0\">start<\/em>\u00a0of the 7 push instructions is executed, it instead executes the one optimised instruction by immediately appending the static slice to the VM stack. Now of course this only works for static values (i.e.\u00a0<em class=\"chakra-text css-0\">push 0x10),<\/em>\u00a0but these are present in the code quite a lot.<\/p>\n<p class=\"chakra-text css-gi02ar\">I\u2019ve also optimised the\u00a0<em class=\"chakra-text css-0\">static jump\u00a0<\/em>instructions. Static jumps are jumps who always jump to the same position (i.e.\u00a0<em class=\"chakra-text css-0\">push 0x1, jump<\/em>) and never change under any circumstance. By determining which jumps are static we can pre-check whether a jump is valid and lies within the bounds of the contract and if so we create a new instructions that replaces both the\u00a0<em class=\"chakra-text css-0\">push<\/em>\u00a0and\u00a0<em class=\"chakra-text css-0\">jump<\/em>instruction and is flagged as\u00a0<em class=\"chakra-text css-0\">valid<\/em>. This prevents the VM from having to do two instructions and it prevents it from having to check whether the jump is valid and doing an expensive hash-map lookup for valid jump position.<\/p>\n<h4 class=\"chakra-heading group css-qm6a1\" id=\"20a3\" data-group=\"true\"><a class=\"chakra-link css-128fqrf\" aria-label=\"20a3 permalink\" href=\"#20a3\"><svg viewbox=\"0 0 24 24\" focusable=\"false\" class=\"chakra-icon css-173jpr1\"><g fill=\"currentColor\"><path d=\"M10.458,18.374,7.721,21.11a2.853,2.853,0,0,1-3.942,0l-.892-.891a2.787,2.787,0,0,1,0-3.941l5.8-5.8a2.789,2.789,0,0,1,3.942,0l.893.892A1,1,0,0,0,14.94,9.952l-.893-.892a4.791,4.791,0,0,0-6.771,0l-5.8,5.8a4.787,4.787,0,0,0,0,6.77l.892.891a4.785,4.785,0,0,0,6.771,0l2.736-2.735a1,1,0,1,0-1.414-1.415Z\"\/><path d=\"M22.526,2.363l-.892-.892a4.8,4.8,0,0,0-6.77,0l-2.905,2.9a1,1,0,0,0,1.414,1.414l2.9-2.9a2.79,2.79,0,0,1,3.941,0l.893.893a2.786,2.786,0,0,1,0,3.942l-5.8,5.8a2.769,2.769,0,0,1-1.971.817h0a2.766,2.766,0,0,1-1.969-.816,1,1,0,1,0-1.415,1.412,4.751,4.751,0,0,0,3.384,1.4h0a4.752,4.752,0,0,0,3.385-1.4l5.8-5.8a4.786,4.786,0,0,0,0-6.771Z\"\/><\/g><\/svg><\/a>Next steps<\/h4>\n<p class=\"chakra-text css-gi02ar\">Full stack and memory analysis would also fit nicely in this model where large chunks of code could fit in to single instructions. Further I\u2019d like to add\u00a0<a target=\"_blank\" rel=\"noopener\" class=\"chakra-link css-vezwxf\" href=\"https:\/\/en.wikipedia.org\/wiki\/Symbolic_execution\">symbolic-execution<\/a>\u00a0and turn the JIT in to a proper JIT-VM. I think this would be a logical next step once programs get large enough to take advantage of these optimisations.<\/p>\n<h3 class=\"chakra-heading group css-xuzltg\" id=\"c1b6\" data-group=\"true\"><a class=\"chakra-link css-128fqrf\" aria-label=\"c1b6 permalink\" href=\"#c1b6\"><svg viewbox=\"0 0 24 24\" focusable=\"false\" class=\"chakra-icon css-173jpr1\"><g fill=\"currentColor\"><path d=\"M10.458,18.374,7.721,21.11a2.853,2.853,0,0,1-3.942,0l-.892-.891a2.787,2.787,0,0,1,0-3.941l5.8-5.8a2.789,2.789,0,0,1,3.942,0l.893.892A1,1,0,0,0,14.94,9.952l-.893-.892a4.791,4.791,0,0,0-6.771,0l-5.8,5.8a4.787,4.787,0,0,0,0,6.77l.892.891a4.785,4.785,0,0,0,6.771,0l2.736-2.735a1,1,0,1,0-1.414-1.415Z\"\/><path d=\"M22.526,2.363l-.892-.892a4.8,4.8,0,0,0-6.77,0l-2.905,2.9a1,1,0,0,0,1.414,1.414l2.9-2.9a2.79,2.79,0,0,1,3.941,0l.893.893a2.786,2.786,0,0,1,0,3.942l-5.8,5.8a2.769,2.769,0,0,1-1.971.817h0a2.766,2.766,0,0,1-1.969-.816,1,1,0,1,0-1.415,1.412,4.751,4.751,0,0,0,3.384,1.4h0a4.752,4.752,0,0,0,3.385-1.4l5.8-5.8a4.786,4.786,0,0,0,0-6.771Z\"\/><\/g><\/svg><\/a>Conclusion<\/h3>\n<p class=\"chakra-text css-gi02ar\"><span class=\"graf-dropCap\">O<\/span>ur JIT-VM is a whole lot smarter than the byte-code VM, but is far from being completely done (if ever). There are many more clever tricks we could add with this structure, but simply aren\u2019t realistic for the moment. The runtime is within the bounds of being \u201creasonable\u201d speedy. May the need arise to further optimise the VM we have the tools to do so.<\/p>\n<h4 class=\"chakra-heading group css-qm6a1\" id=\"06ef\" data-group=\"true\"><a class=\"chakra-link css-128fqrf\" aria-label=\"06ef permalink\" href=\"#06ef\"><svg viewbox=\"0 0 24 24\" focusable=\"false\" class=\"chakra-icon css-173jpr1\"><g fill=\"currentColor\"><path d=\"M10.458,18.374,7.721,21.11a2.853,2.853,0,0,1-3.942,0l-.892-.891a2.787,2.787,0,0,1,0-3.941l5.8-5.8a2.789,2.789,0,0,1,3.942,0l.893.892A1,1,0,0,0,14.94,9.952l-.893-.892a4.791,4.791,0,0,0-6.771,0l-5.8,5.8a4.787,4.787,0,0,0,0,6.77l.892.891a4.785,4.785,0,0,0,6.771,0l2.736-2.735a1,1,0,1,0-1.414-1.415Z\"\/><path d=\"M22.526,2.363l-.892-.892a4.8,4.8,0,0,0-6.77,0l-2.905,2.9a1,1,0,0,0,1.414,1.414l2.9-2.9a2.79,2.79,0,0,1,3.941,0l.893.893a2.786,2.786,0,0,1,0,3.942l-5.8,5.8a2.769,2.769,0,0,1-1.971.817h0a2.766,2.766,0,0,1-1.969-.816,1,1,0,1,0-1.415,1.412,4.751,4.751,0,0,0,3.384,1.4h0a4.752,4.752,0,0,0,3.385-1.4l5.8-5.8a4.786,4.786,0,0,0,0-6.771Z\"\/><\/g><\/svg><\/a>Further code-reading<\/h4>\n<p>Cross posted from &#8211;\u00a0https:\/\/medium.com\/@jeff.ethereum\/go-ethereums-jit-evm-27ef88277520#.1ed9lj7dz<\/p><\/div>\n<p><br \/>\n<br \/><a href=\"https:\/\/blog.ethereum.org\/en\/2016\/06\/02\/go-ethereums-jit-evm\">Source link <\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>The Ethereum Virtual machine is kind of different than most other Virtual Machines out there. In my\u00a0previous post\u00a0I already explained how it\u2019s used and described some of its characteristics. The Ethereum Virtual Machine (EVM) is a simple but powerful, Turing complete 256bit Virtual Machine that allows anyone to execute arbitrary\u00a0EVM Byte Code. The go-ethereum project [&hellip;]<\/p>\n","protected":false},"author":6,"featured_media":18498,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"tdm_status":"","tdm_grid_status":"","footnotes":""},"categories":[24],"tags":[],"kronos_expire_date":[],"class_list":["post-18761","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ethereum"],"_links":{"self":[{"href":"https:\/\/cryptoted.net\/index.php\/wp-json\/wp\/v2\/posts\/18761","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cryptoted.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cryptoted.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cryptoted.net\/index.php\/wp-json\/wp\/v2\/users\/6"}],"replies":[{"embeddable":true,"href":"https:\/\/cryptoted.net\/index.php\/wp-json\/wp\/v2\/comments?post=18761"}],"version-history":[{"count":0,"href":"https:\/\/cryptoted.net\/index.php\/wp-json\/wp\/v2\/posts\/18761\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cryptoted.net\/index.php\/wp-json\/wp\/v2\/media\/18498"}],"wp:attachment":[{"href":"https:\/\/cryptoted.net\/index.php\/wp-json\/wp\/v2\/media?parent=18761"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cryptoted.net\/index.php\/wp-json\/wp\/v2\/categories?post=18761"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cryptoted.net\/index.php\/wp-json\/wp\/v2\/tags?post=18761"},{"taxonomy":"kronos_expire_date","embeddable":true,"href":"https:\/\/cryptoted.net\/index.php\/wp-json\/wp\/v2\/kronos_expire_date?post=18761"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}