本来寻思着写一篇"'Hello' + ', World'"是怎么从JS代码编译然后输出的,然而compile过程的复杂性远超我的想象,强上怕会走火入魔,还是老老实实先回家种田,找点咸鱼方法先写着。虽然说是咸鱼方法,但是V8任何一块拿出来都不简单,之前讲的Time模块说实话大概是属于源码里面幼儿园级别的,这次试试难一点的。
V8的源码在本地编译完成后,会提供一个hello-world.cc的sample,里面有新手用户标准的初始化流程,如下。
int main(int argc, char* argv[]) { // Initialize V8. // 这个方法在mac不作为 v8::V8::InitializeICUDefaultLocation(argv[0]); // 读取指定名称的配置文件 也不用鸟 v8::V8::InitializeExternalStartupData(argv[0]); // 生成一个默认的platform对象 std::unique_ptr<v8::Platform> platform = v8::platform::NewDefaultPlatform(); // 初始化刚才的platform v8::V8::InitializePlatform(platform.get()); // V8的初始化 v8::V8::Initialize(); // ... }
前两步不用去管,在入门阶段用不上。
第三步是主要内容,探究生成的默认platform对象(当然也可以选择自己定制一个platform对象),这个类主要负责管理线程池、调用栈、事件队列等一些杂活。
这一篇不会去深入方法一步一步走,里面内容太过于杂乱,跳来跳去的,先整体介绍一下所有涉及的类,有一个初步的印象(建议深入阅读所有基类的英文注释,解释的很明白)。
Platform
首先当然是核心类Platform,但这是一个基类,里面的大部分方法都是虚函数。
/** * V8 Platform abstraction layer. * * The embedder has to provide an implementation of this interface before * initializing the rest of V8. */ class Platform {};
如果需要定制platform来初始化V8,需要继承这个类并实现那些方法。一般情况下当然可以V8默认提供的类,即DefaultPlatform。
class DefaultPlatform : public Platform { public: // 接受一个枚举值、一个TracingController类的构造函数 explicit DefaultPlatform( IdleTaskSupport idle_task_support = IdleTaskSupport::kDisabled, std::unique_ptr<v8::TracingController> tracing_controller = {}); ~DefaultPlatform() override; // 设置线程池大小 void SetThreadPoolSize(int thread_pool_size); // 初始化线程池、管理线程任务相关的方法 void EnsureBackgroundTaskRunnerInitialized(); private: // 最大线程池数量 默认为8 static const int kMaxThreadPoolSize; int thread_pool_size_; IdleTaskSupport idle_task_support_; // 线程任务启动器 std::shared_ptr<DefaultWorkerThreadsTaskRunner> worker_threads_task_runner_; // 工具类 std::unique_ptr<TracingController> tracing_controller_; std::unique_ptr<PageAllocator> page_allocator_; // 计数方法 用的是之前介绍的Time模块 TimeFunction time_function_for_testing_; }; /** * V8 Tracing controller. * * Can be implemented by an embedder to record trace events from V8. */ class TracingController {}; /** * A V8 memory page allocator. * * Can be implemented by an embedder to manage large host OS allocations. */ class PageAllocator {};
只选了一些初始化相关的方法,其实内容远比这个要多。其中还定义了两个类似于Platform的基类变量,一个负责调用栈追踪,一个负责内存管理。
TaskRunner/Thread
接下来是任务执行者、线程,因为这两者基本上成对出现,所以放一起来看。
// Thread // // Thread objects are used for creating and running threads. When the start() // method is called the new thread starts running the run() method in the new // thread. The Thread object should not be deallocated before the thread has // terminated. class V8_BASE_EXPORT Thread { public: // Start new thread by calling the Run() method on the new thread. void Start(); // ... };
这是最基础的Thread,其中定义并实现了Start等常规方法,也有一些虚函数需要继承去重新实现,除此之外还有一些静态方法。默认情况下,V8实现了一个类继承于Thread,位置十分的隐蔽,在默认TaskRunner的private里面。
/** * A TaskRunner allows scheduling of tasks. The TaskRunner may still be used to * post tasks after the isolate gets destructed, but these tasks may not get * executed anymore. All tasks posted to a given TaskRunner will be invoked in * sequence. Tasks can be posted from any thread. */ class TaskRunner {}; class Def