又到了常规的堆砌代码凑文章字数环节,很多API我就直接贴官方的英文释义,个人翻译其实有时候并不是很准确,搞错了甚至会误导,还是尽量自己去理解。

  首先看看入口方法。

std::unique_ptr<v8::Platform> platform = v8::platform::NewDefaultPlatform();

// int类型 thread_pool_size => 0
// 枚举值 idle_task_support => kDisabled
// 枚举值 in_process_stack_dumping => kDisabled
// 类 tracing_controller => NULL
std::unique_ptr<v8::Platform> NewDefaultPlatform(
int thread_pool_size, IdleTaskSupport idle_task_support,
InProcessStackDumping in_process_stack_dumping,
std::unique_ptr<v8::TracingController> tracing_controller) {
// 不会进这里
if (in_process_stack_dumping == InProcessStackDumping::kEnabled) {
v8::base::debug::EnableInProcessStackDumping();
} //
std::unique_ptr<DefaultPlatform> platform(new DefaultPlatform(idle_task_support, std::move(tracing_controller)));
//
platform->SetThreadPoolSize(thread_pool_size);
//
platform->EnsureBackgroundTaskRunnerInitialized();
return std::move(platform);
}

  这里比较头疼的是我没找到NewDefaultPlatform方法是在哪里定义的,所以默认参数不知道是什么,只能打断点调试看变量值,已经在注释标注了。

  默认参数情况下,那个if分支是不会进去的,所以无视,后面的三个语句都各自负责了一部门功能,分别是初始化默认Platform对象、设置线程池大小、启动工作线程,分块来看各部分源码。

  第一条语句直接用new构造了一个DefaultPlatform对象,如下,加了一些标注。

//
DefaultPlatform::DefaultPlatform(
IdleTaskSupport idle_task_support,
std::unique_ptr<v8::TracingController> tracing_controller)
: thread_pool_size_(),
idle_task_support_(idle_task_support),
tracing_controller_(std::move(tracing_controller)),
// 1-1
page_allocator_(new v8::base::PageAllocator()),
time_function_for_testing_(nullptr) {
if (!tracing_controller_) {
// 1-2
tracing::TracingController* controller = new tracing::TracingController();
// 1-3
controller->Initialize(nullptr);
// 智能指针替换
tracing_controller_.reset(controller);
}
}

  这是接受两个参数的构造函数,而且DefaultPlatform只有这一个构造函数。除了用给定的2个参数初始化属性,一些其他属性也用默认的参数初始化了,对于0、nullptr这种就不用管,其中比较特殊的是那个page_allocator初始化,上一篇给出的类声明是基类,在V8的命名空间有一个同名的实现类。

class PageAllocator : public ::v8::PageAllocator {
// ...
private:
const size_t allocate_page_size_;
const size_t commit_page_size_;
} PageAllocator::PageAllocator()
: allocate_page_size_(base::OS::AllocatePageSize()),
commit_page_size_(base::OS::CommitPageSize()) {}

  我也是服了V8,弄了个同名的类,第一次看楞了好久。构造函数调用的是OS命名空间的方法,这个命名空间是用来取一些系统参数,调用mac系统上<unistd.h>头文件的一些API,看一下allocate_page_size的初始化就明白了。

size_t OS::AllocatePageSize() {
return static_cast<size_t>(sysconf(_SC_PAGESIZE));
}

  这里用了一个sysconf方法,在其他的很多地方也有使用,官方解释如下。

get configuration information at run time

  当成NODE_ENV来理解就差不多了,也就是一个获取系统配置参数的API,对于PageAllocator的两个属性,官方的解释依次如下。

1、Size of a page in bytes.  Must not be less than 1.
2、memory page size

  两个其实都是page size(内存页大小,关于Linux的内存模型我不太懂,后面有空再去了解),我本地测试了一下,都返回的4096。

  对属性初始化完后,构造函数会继续走代码块里的语句,由于外部传进来的tracing_controller是个NULL,所以这里还需要手动new一个。

TracingController::TracingController() = default;

  然而这个构造函数没啥好讲的,因为是默认构造函数,所以直接跳过了,后面的两步也没什么讲的,reset是智能指针的API,替换管理内容。

  下面是第二条语句,从命名直接能看出来了,就是设置线程池的大小,方法也比较简单暴力了。

//
void DefaultPlatform::SetThreadPoolSize(int thread_pool_size) {
base::MutexGuard guard(&lock_);
DCHECK_GE(thread_pool_size, );
if (thread_pool_size < ) {
// The number of processors currently online (available) => 4
thread_pool_size = base::SysInfo::NumberOfProcessors() - ;
}
// max(min(8, size), 1)
thread_pool_size_ = std::max(std::min(thread_pool_size, kMaxThreadPoolSize), );
}

  这里实际上也是调用了一个类似于上面的sysconf来获取系统参数,返回的系统处理器数量,由于其中一个要用来作为主线程,所以可用的线程池数量要减一,简单处理一下返回一个size。

  第三条语句内容相当的麻烦,看得我脑子疼,语义上理解就是保证后台线程runner的初始化运行。

  说得简单,由于之前的操作只是初始化了一个空白platform类,算了算线程池的大小,所以剩下的所有实际操作都在这里。大概包含了初始化线程池、生成线程同时分配任务、管理task队列、启动线程等一系列操作,其中的思想倒并不复杂,实际上跟libuv的异步原理相差无几,但是深入源码的每一步还是挺恶心的,下一篇再来搞。

深入V8引擎-默认Platform之mac篇(1)的更多相关文章

  1. 深入V8引擎-默认Platform之mac篇(2)

    先说结论,V8引擎在默认Platform中初始化的这个线程是用于处理类似于setTimeout的延时任务. 另外附一些图,包括继承树.关键属性归属.纯逻辑工作流程,对代码木得兴趣的看完图可以X掉了. ...

  2. 深入V8引擎-初始化默认Platform

    本来寻思着写一篇"'Hello' + ', World'"是怎么从JS代码编译然后输出的,然而compile过程的复杂性远超我的想象,强上怕会走火入魔,还是老老实实先回家种田,找点 ...

  3. 深入V8引擎-引擎内部类管理解析

    v8的初始化三部曲,前面花了三篇解决了第一步,由于只是生成了一个对象,第二步就是将其嵌入v8中,先看一下三个步骤. // 生成默认Platform对象 std::unique_ptr<v8::P ...

  4. V8引擎嵌入指南

    如果已读过V8编程入门那你已经熟悉了如句柄(handle).作用域(scope)和上下文(context)之类的关键概念,以及如何将V8引擎作为一个独立的虚拟机来使用.本文将进一步讨论这些概念,并介绍 ...

  5. 浅谈V8引擎中的垃圾回收机制

    最近在看<深入浅出nodejs>关于V8垃圾回收机制的章节,转自:http://blog.segmentfault.com/skyinlayer/1190000000440270 这篇文章 ...

  6. V8引擎——详解

    前言 JavaScript绝对是最火的编程语言之一,一直具有很大的用户群,随着在服务端的使用(NodeJs),更是爆发了极强的生命力.编程语言分为编译型语言和解释型语言两类,编译型语言在执行之前要先进 ...

  7. v8引擎详解

    引用网址: https://blog.csdn.net/swimming_in_it_/article/details/78869549 前言 JavaScript绝对是最火的编程语言之一,一直具有很 ...

  8. 一文搞懂V8引擎的垃圾回收

    引言 作为目前最流行的JavaScript引擎,V8引擎从出现的那一刻起便广泛受到人们的关注,我们知道,JavaScript可以高效地运行在浏览器和Nodejs这两大宿主环境中,也是因为背后有强大的V ...

  9. 探究JS V8引擎下的“数组”底层实现

    本文首发于 vivo互联网技术 微信公众号 链接:https://mp.weixin.qq.com/s/np9Yoo02pEv9n_LCusZn3Q作者:李超 JavaScript 中的数组有很多特性 ...

随机推荐

  1. 英语NanyangJade南阳玉NanyangJade独山玉

    南阳玉NanyangJade又叫做独山玉,独山玉,因产于河南南阳的独山而得名,亦称“南阳玉”. 独山玉是中国四大名玉之一,有南阳翡翠之称,独山玉是一种黝帘石化斜长岩,由多种矿物组成,属多色玉器. 据文 ...

  2. 搞NDK开发

    1.哪些场景下要用到NDK开发? 跨平台的库,如FFmpeg, skip,weex, 加固,防逆向 签名校验 图片压缩 音视频解码 OpenGL ES 高级特效 热修复 andfix 人脸识别 fac ...

  3. LeetCode——Nth Highest Salary

    Write a SQL query to get the nth highest salary from the Employee table. +----+--------+ | Id | Sala ...

  4. 爬取70城房价到oracle数据库并6合1

    学习数据分析,然后没有合适的数据源,从国家统计局的网页上抓取一页数据来玩玩(没有发现robots协议,也仅仅发出一次连接请求,不对网站造成任何负荷) 运行效果 源码 python代码 ''' 本脚本旨 ...

  5. 分布式系统全局唯一ID的生成

    分布式系统全局唯一ID的生成 一 .什么是分布式系统唯一ID ​ 在复杂分布式系统中,往往需要对大量的数据和消息进行唯一标识. ​ 如在金融.电商.支付.等产品的系统中,数据日渐增长,对数据分库分表后 ...

  6. Linux Workqueue【转】

    转自:http://kernel.meizu.com/linux-workqueue.html 21 August 2016   Workqueue 是内核里面很重要的一个机制,特别是内核驱动,一般的 ...

  7. MAC自动化环境搭建

    UI自动化环境搭建 第一阶段:配置appium环境硬件配置mac系统电脑 java环境sunjiedeMacBook-Air:~ vicent$ java -versionjava version & ...

  8. 代码审计-md5加密相等绕过

    <?php $md51 = md5('QNKCDZO'); $a = @$_GET['a']; $md52 = @md5($a); if(isset($a)){ if ($a != 'QNKCD ...

  9. Python运维中20个常用的库和模块

    1.psutil是一个跨平台库(https://github.com/giampaolo/psutil) 能够实现获取系统运行的进程和系统利用率(内存,CPU,磁盘,网络等),主要用于系统监控,分析和 ...

  10. html基础内容

    HTML基础 1. HTML 标题 HTML 标题(Heading)是通过 <h1> - <h6> 等标签进行定义的. 2. HTML 段落 HTML 段落是通过 <p& ...