《深入理解Android JVM ART》勘误及建立读者交流群的说明

缘起

前几天有一位热心的刘同学给我发了个邮件,说阅读《深入理解Android Java虚拟机ART》一书过程中发现了多处错误。他整理了一个word文档,有图有真相,非常细心(我待会把错误和修改的地方放到本文中)。错误的地方主要是拼写错误,但其中有几个错误是技术错误,比如有不正确的,有不严谨的。我仔细研读后,和刘同学就其中几个技术问题来回讨论了几次,最终还是我错了。Anyway,这个事情引发了我的一次思考。

自从出版了深入理解Android这几本书后,几乎很少和读者有过这种切磋。虽然我从《深入理解Android:Wi-Fi、NFC和GPS》一书开始邀请审稿专家,审稿专家们和我是有过密切的交流和切磋。但书出版后,就没有和读者有过交流了。

刘同学的反馈让我意识到,书的出版其实只是知识传播的第一步,并不是终结。而且,在学习的旅程,如果有个地方能让大家交流,沟通,切磋的话,效果比自己单干是要强不少的。所以,我打算就咱们深入理解Android系列做一个交流群,搭建一个平台。当然,这个平台上也可以讨论技术发展,管理方面的问题。

其实我早该如此了。我学个开车都加了不少车友学习交流群,更何况是吃高精尖技术饭的码农们呢?抱团一起变老吧smiley_2.png。交流群的二维码在下面和文末,欢迎大家把周围的读者,或者隐藏的高手(比如刘同学这样的)邀请进来。我想,这个交流平台应是一个严肃又活泼,思维自由又自律,可以沉默不语,但别人的话又能给你启发的地方吧。

640?wx_fmt=jpeg

JVM ART一书的勘误(2019/8/29)

来自刘同学的反馈以及我们讨论的结果。

注意,刘同学看的是京东电子版,下面的勘误我以原书的对应页数为标题。请各位忽略截图片中的章节号(感觉有些对不上原书)。另外,有2-3处不确定的问题,我暂时先不发上来了。

573页图10-2

640?wx_fmt=jpeg

573页图10-2这个地方有技术错误。ESP指向的地方应该存储的是ArtMethod*。而不是ArtMethod**。这个错误要搞明白还需要看一下代码。

往这个单元塞数据的地方在quick_entrypoints_x86.S中,如图所示:

640?wx_fmt=jpeg

其中:

  • REG_VAR(temp_reg)相当于得到系统中唯一的那个runtime*对象。runtime就是ART虚拟机的化身。

  • 而RUNTIME_SAVE_ALL_CALLEE_SAVE_FRAME_OFFSET的值为0(定义在asm_support.h中)

也就是说,pushl实际上将runtime[0]的值放到栈中。那么,runtime[0]是什么呢?来看runtime类的声明:

640?wx_fmt=jpeg

可以看到,Runtime对象的头部就是callee_save_methods数组,这个数组里的元素是ArtMethod*。kLastCalleeSaveType属于枚举CalleeSaveType,而我们要取的kSaveAll刚好值为0。也就是说,runtime[0]就是runtime->callee_save_methods[kSaveAll](数组的第一个元素),那么它自然就是ArtMethod*,而不是ArtMethod**了。

之所以会写错,因为我被代码中的OFFSET给迷惑了。OFFSET是偏移量的意思。我习惯性的把偏移量当做地址了,所以会理解成callee_save_methods[kSaveAll]的地址,这样的话,就变成ArtMethod**了。

730页图13-2

640?wx_fmt=jpeg

图13-2 Mainblock的描述有错误。Main block不是绑定给某个线程用的。而是所有没有绑定自己的block的线程都可以使用Main block。

243页最后一段

640?wx_fmt=jpeg

应该是物理寄存器。但我觉得从理论上倒是不必要过分强调到底是物理寄存器还是虚拟寄存器。当然,这个假设的前提条件是虚拟寄存器不能是无限多个。

180页ConnectBasicBlocks代码

640?wx_fmt=jpeg

block==nullptr的条件有两个:

  • dex_pc非基本块的起始地址

  • 还有别的情况。代码注释中叫dead code。但并未展开说明dead code 情况。

以下是有拼写错误的地方:

227页图6-35

640?wx_fmt=jpeg

HUserList写错了,应为HUseList

228页第三个列表项的倒数第一行

640?wx_fmt=jpeg

HUserListNode应为HUseListNode

229页的第二行

640?wx_fmt=jpeg

users_应为user_

243页第二行

640?wx_fmt=jpeg

268页第一段代码

640?wx_fmt=jpeg

注释中的图6-44应为图6-45

267页第二段

640?wx_fmt=jpeg

split应为spill

330页提示部分

640?wx_fmt=jpeg

incline应为inline

495页

640?wx_fmt=jpeg

ScrMapElem应该为SrcMapElem

517页代码部分

640?wx_fmt=jpeg

DeclaringCallsOffset应为DeclaringClassOffset

525页最后一行

640?wx_fmt=jpeg

JniMethodStart应为JniMethodEnd

738页最后两段代码

640?wx_fmt=jpeg

函数所在的类写反了,应为:

  • 第一个Clear是RegionSpace的,位于region_space.cc中。

  • 第二个Clear函数是Region的,位于region_space.h中

786页第二行

640?wx_fmt=jpeg

0x7014000应为0x70140000

789页提示语第二行

640?wx_fmt=jpeg

“分布”应为“分别”

790页第六行

640?wx_fmt=jpeg

由高到低应为由低到高

846页第一个提示

640?wx_fmt=jpeg

mark_sweep_应为mark_stack_。注意,这附近一共有三处同样的错误。代码中并没有mark_sweep_,只有mark_stack_

873页代码下的一段话

640?wx_fmt=jpeg

各创建了一个SpaceBitmap对象,不是三个。原文是想说一共创建了三个对象。

后继安排

文末再发一次群二维,七天有效。失效的话,以后再更新。

640?wx_fmt=jpeg

后面的安排

  • JVM ART涉及基础核心技术,难度较大。我考虑写几篇导读文章,让大家先了解ART大面上的知识,这样能大幅降低阅读的难度。

  • 读者群里大家可以一起交流。有些时候,思想碰撞碰撞一下,会学得更快更好。比如,我从刘同学的反馈里就学到不少。

关于quickjs

上期说了quickjs的事情。这一个月来一直潜心在研究,但它的难度非常大。而且,确实需要深度了解javascript语言的各种特性。稍微了解JS的同学可能会知道,js的语言特性太多太多了。所以,单纯从quickjs的代码是无法攻破它的。我现在转而学习js语言了,越深越好。到时候有成功的话,我定会分享的——BTW,我感觉难度比ART大得多....

最后的最后

  • 我期望的结果不是朋友们从我的书、文章、博客后学会了什么知识,干成了什么,而应该是说,神农,我可是踩在你的肩膀上的喔。

  • 关于学习方面的问题,我已经讨论完了。后面这个公众号将对一些基础的技术,新技术做一些学习和分享。也欢迎你的投稿。不过,正如我在公众号“联系方式”里说的那样——郑渊洁在童话大王《智齿》里有一句话令我印象深刻,大意是“我有权保持沉默,但你说的每一句话都可能成为我灵感的源泉”。所以,影响不是单向的,很可能我从你那学到的东西更多。

640?wx_fmt=jpeg

神农和朋友们的杂文集

长按识别二维码关注我们

猜你喜欢

转载自blog.csdn.net/Innost/article/details/100148363