|
|
|
DESCRIPTION -------------------------------------------------------------------
|
|
|
|
|
|
|
|
gcmole is a simple static analysis tool used to find possible evaluation order
|
|
|
|
dependent GC-unsafe places in the V8 codebase.
|
|
|
|
|
|
|
|
For example the following code is GC-unsafe:
|
|
|
|
|
|
|
|
Handle<Object> Foo(); // Assume Foo can trigger a GC.
|
|
|
|
void Bar(Object*, Object*);
|
|
|
|
|
|
|
|
Handle<Object> baz;
|
|
|
|
baz->Qux(*Foo()); // (a)
|
|
|
|
Bar(*Foo(), *baz); // (b)
|
|
|
|
|
|
|
|
Both in cases (a) and (b) compiler is free to evaluate call arguments (that
|
|
|
|
includes receiver) in any order. That means it can dereference baz before
|
|
|
|
calling to Foo and save a raw pointer to a heap object in the register or
|
|
|
|
on the stack.
|
|
|
|
|
|
|
|
PREREQUISITES -----------------------------------------------------------------
|
|
|
|
|
|
|
|
1) Install Lua 5.1
|
|
|
|
|
|
|
|
2) Get LLVM 2.9 and Clang 2.9 sources and build them.
|
|
|
|
|
|
|
|
Follow the instructions on http://clang.llvm.org/get_started.html.
|
|
|
|
|
|
|
|
Make sure to pass --enable-optimized to configure to get Release build
|
|
|
|
instead of a Debug one.
|
|
|
|
|
|
|
|
3) Build gcmole Clang plugin (libgcmole.so)
|
|
|
|
|
|
|
|
In the tools/gcmole execute the following command:
|
|
|
|
|
|
|
|
LLVM_SRC_ROOT=<path-to-llvm-source-root> make
|
|
|
|
|
|
|
|
USING GCMOLE ------------------------------------------------------------------
|
|
|
|
|
|
|
|
gcmole consists of driver script written in Lua and Clang plugin that does
|
|
|
|
C++ AST processing. Plugin (libgcmole.so) is expected to be in the same
|
|
|
|
folder as driver (gcmole.lua).
|
|
|
|
|
|
|
|
To start analysis cd into the root of v8 checkout and execute the following
|
|
|
|
command:
|
|
|
|
|
|
|
|
CLANG_BIN=<path-to-clang-bin-folder> lua tools/gcmole/gcmole.lua [<arch>]
|
|
|
|
|
|
|
|
where arch should be one of architectures supported by V8 (arm, ia32, x64).
|
|
|
|
|
|
|
|
Analysis will be performed in 2 stages:
|
|
|
|
|
|
|
|
- on the first stage driver will parse all files and build a global callgraph
|
|
|
|
approximation to find all functions that might potentially cause GC, list
|
|
|
|
of this functions will be written into gcsuspects file.
|
|
|
|
|
|
|
|
- on the second stage driver will parse all files again and will locate all
|
|
|
|
callsites that might be GC-unsafe based on the list of functions causing GC.
|
|
|
|
Such places are marked with a "Possible problem with evaluation order."
|
|
|
|
warning. Messages "Failed to resolve v8::internal::Object" are benign and
|
|
|
|
can be ignored.
|
|
|
|
|
|
|
|
If any errors were found driver exits with non-zero status.
|