タグ

ブックマーク / nmi.jp (12)

  • JavaScript 実行エンジン V8 の JIT 出力コードを読んでみよう

    ChromeJavaScript はとても高速なことでも有名ですが、その実行エンジンは V8 と呼ばれます。V8 自体は独立したモジュールであり、Node.js 等にも使われております。 V8 が JavaScript を高速に実行する技術の一つが JIT (Just In Time) コンパイルです(一般的に JIT と呼ばれます)。これは、そのまま実行すると遅い JavaScript を実行中にリアルタイムに直接マシンコードに変換し(これが Just In Time と呼ばれる所以です)、途中からそのコードに入れ替えて実行することで高速化を達成しています。特に何度も実行される関数で効力を発揮します。 JIT という名前は聞いたことがあろうとも、実際に JIT がどのようなコードを実行しているのかを確認する機会は滅多にないでしょう。この記事では、実際に V8 の JIT の出力を確

    mizdra
    mizdra 2024/06/20
    "実際の業務において、ここまでする必要は、まずありません。しかし、ここまでするやり方を知っていると、本当に困った時にどこまでも潜っていける自信になるのではないかと思います。"
  • ARM に存在する JavaScript 専用命令「FJCVTZS」を追う(ついでに V8 をビルドする)

    前回の記事では、JavaScript の実行エンジン V8 の JIT 出力コードを読んでみました。記事は M1 Mac 上で動かした結果でしたので、ARM アーキテクチャのアセンブラを読むことになりました。 さてそんな ARM アーキテクチャですが、最近の ARM には FJCVTZS という JavaScript 専用の機械語命令があるのをご存知でしょうか?CPU に、特定の言語(それもコンパイラを持たない JavaScript)専用の命令があると知ったとき、私は大いに驚きました(過去にも Jazelle みたいなものはありましたが) 今回は、この FJCVTZS 命令について、実際にどれだけ効果があるのか、V8 をビルドしながら調べてみましょう。 FJCVTZS 命令とは? FJCVTZS 命令は、Arm v8.3 から導入された JSCVT 命令の一つで、JavaScript の言

  • Maximum call stack size exceeded について解説

    "Maximum call stack size exceeded" というエラーに関する解説を書きます。JavaScript を前提に解説しております。 ざっくり解説 Uncaught RangeError: Maximum call stack size exceeded これは、関数が何度も深く深く呼ばれてしまった場合に出るエラーです。 大抵は、間違って自分自身の関数を呼んでしまった、もしくは再帰の終了条件をミスった場合に発生します。 ここに検索で来た方は、自分自身を呼んでいたり、関数同士が循環的に呼びあっていたりするミスを犯していないか確認してください 。 図にすると、こんな感じです ちなみに、関数呼び出しがなければこのエラーは発生しません。ただの無限ループでは決して発生しないエラーです。以下、解説を書きます。 「関数を深く呼ぶ」とは? ここでは、関数からリターンせず再度関数を呼び

    mizdra
    mizdra 2023/12/05
    なるほど / “特に JavaScript の場合は、ユーザーの端末によって実装がバラバラであり、スタックサイズも一定ではありません。それが原因で、特定のごく小数のユーザーのみで問題が起こるバグとなることもあります。 ”
  • JavaScript で CPU が Intel かどうかを判定する(ついでに JIT を検知する)

    先日、次のような Tweet を見かけました TIL I discovered that TensorFlow.js uses an interesting trick to sniff your CPU architecture in WebAssembly. pic.twitter.com/LVyywIM48I — Robert Knight (@robknight_) January 4, 2023 面白かったので、なぜこうなるのかの解説と、ついでにこのテクニックを使った JIT 検知方法などについて紹介します。 JavaScript における低レイヤーの扱い JavaScript においては、挙動が比較的しっかりと仕様に定められているために、環境による振る舞いの違いはあまり発生しません。しかし、低レイヤーに降りるほど振る舞いは実装依存になり、環境差が発生する余地が出てきます。 一番

    mizdra
    mizdra 2023/01/14
    面白い
  • setTimeout を完璧に理解する

    setTimeout は、指定された時間以降に指定されたコードを実行する JavaScriptAPI です。ブラウザでも Node.js でも広く使われているのですが、実装はまちまちで、色々と特殊な条件も多く、挙動を完璧に理解している人は少ないと思います。この記事では、そんな setTimeout を可能な限り深堀りしてみようと思います。 先に書いておきますが、ものすごくニッチで細かい話ばかり並びます。突然私が、ただ純粋に setTimeout について調べたくなったので、その結果をまとめただけのものです。普通に開発している人には必要のない情報が多くなるでしょう。この記事は基礎から setTimeout を学ぼう、という方には全然向かないと思います。 また、JavaScript のイベントループについてある程度理解していることを前提とします。その詳しい理解には、@PADAone さん

    mizdra
    mizdra 2022/11/22
    よかった / ふと調べてみたら、Chrome 108 からは今の5回目から大幅に増やして16回目から setTimeout ネスト時のスロットリングが発生するようにするっぽい: https://chromestatus.com/feature/5710690097561600
  • JavaScript の undefined と null を完全に理解する

    JavaScript で頻出する undefined と null について語ります。 言語仕様上の違い JavaScript (ECMAScript) において、仕様上 undefined と null は当然ながら明確に区別されています。いくつか言語仕様上の扱いについて挙げてみます。 比較 厳密な比較演算子 === において undefined と null は区別されます。ゆるい比較演算子 == においては両者は区別されません(仕様 7.2.14)。 console.log(undefined === null); // false console.log(undefined == null); // true 他の falsy な値(false とみなされる値)との比較は、ゆるい比較演算子であっても区別されます(仕様 同上)。 console.log(undefined == fa

  • document.all の例外仕様を知っていますか

    昨日、ツイッターで次のような JavaScript クイズを出しました。 久しぶりの JavaScript クイズ! function hello(x) { if(typeof x === 'undefined') { alert(x.f()); } } この hello 関数で "Hello, World!" のアラートを表示させることが出来るか? — Takuo Kihira (@tkihira) July 31, 2022 このブログ記事では、この問題について解説します。 解答 答えは「出来る」です。出題者の意図としては document.all を想定しておりました。 document.all は、ブラウザに存在する、非常に特殊なオブジェクトです。 document.all 自体は object 型である。console.log(document.all) とすると内容が確認出来る

  • 10 年前に JavaScript で Flash Player を開発し買収された話

    この記事は、JavaScript で Flash Player の実現を頑張った(もしくは現在進行系で頑張っている)人たちの集う Flash Advent Calendar 2020 に参加しております。 私は過去に自分が設立した会社で ExGame という HTML5 実装の Flash Player(正確には Flash Runtime Engine)を開発し、その会社ごと DeNA に買収(M&A)されました。あまり出来ない体験であるのは間違いないので、Flash が終了を迎える今、改めて振り返ってみようと思います。 Flash Player の開発 今から 10 年前の 2010 年、ちょうど iPhone が普及し始めてきてガラケーのシェアが 8 割から 6 割くらいに落ちようとしていた時期に、私は Flash Player を JavaScript で実装していました。以前この

  • Chrome の隠し機能 chrome://tracing (about:tracing) の使い方

    こんにちは。仕事上で chrome://tracing (about:tracing) を使う必要が出たので、私の知っている限りの情報をここでまとめることにしました。 chrome://tracing の情報は世の中にあまりありません。もし記事中に間違いを見つけられたり、より良い利用方法をご存知の方は、ぜひ @tkihira まで教えてください。よろしくお願いします! なお実際は隠し機能ではなく、ただあまり知られていないだけです。公式の情報は https://www.chromium.org/developers/how-tos/trace-event-profiling-tool ここから辿れると思います。 注意 この機能は、Chrome のインスタンス全体のプロファイルを取るものです。不用意に実行すると、すべての Chrome のタブを巻き込んで落ちます。記事中では Chrome Ca

  • Rust で WebAssembly を出力する

    もう結構前になりますが、RustEmscripten を利用することなく WebAssembly の出力ができるようになりました。それにより、Rust を使った WebAssembly の開発が現実的な選択肢としてさらに力を帯びてきました。 自分の勉強で Rust から WebAssembly に出力するプログラムを書いてみたので、その道筋をご紹介することで自分のような Rust 初心者の方々の WebAssembly 開発の助けになればと思い、この記事を投稿しました。 もし記事中に間違い等がありましたら、是非 @tkihira までご連絡ください。 Emscripten との依存関係を切った Rust つい最近まで、WebAssembly の出力は Emscripten を使うことがほとんどでした。Emscripten は、元々は他言語のプログラムを JavaScript に変換す

  • WebAssembly の基礎

    WebAssembly をご存知でしょうか?2年前に突然発表された新しい仕様です。まだ登場して間もないため、実際に格的に利用しているサービスは数えるほどしかありませんが、Twitter 等を見ているとじわりじわりと評判になっており、技術としての勢いを感じます。 一方で、WebAssembly について言及された資料がまだまだ少なかったり、技術のレイヤーが一般的なフロントエンドエンジニア技術セットとは大きくかけ離れているなどの理由により、WebAssembly について誤解されていることも多々あることを感じました。 そこで今回、あまり技術的に詳細な所まで深入りせず、「専門外の方でもこの程度知っておけば良い」よりちょっと詳しいくらいの内容を目標にして WebAssembly を解説してみたいと思います。 WebAssembly とは WebAssemblywasmとも呼ばれます)とは、ざ

  • 巨大 WebAssembly ファイルのコンパイル時間

    funcs というのは、wasm 内に何個関数が入っているか、です。1 func の場合は Function body が約 25Mb、100,000 funcs の場合は約 2.5kb、500,000 funcs の場合は約 0.5kb です。 Chrome では 20秒〜1分 ほどかかっています。なおこのコンパイル処理は現在の Chrome の実装だとページをロードする度に必ず発生するので、巨大 WebAssembly が存在するページを Chrome で開いた場合、キャッシュの有無等と関係なく相当待つ必要があります。 Firefox だと、Function Body のサイズによって処理時間が大きく変わります。1 つしか関数がないときはクラッシュしましたが、Function Body が小さくなるにつれて速度が向上しています。例えば Emscripten 等で出力される巨大な Web

  • 1