当前位置: 首页 > wzjs >正文

花店网站源码汉中中药材初加工平台

花店网站源码,汉中中药材初加工平台,深圳网络专科网站建设,广州哪个区最繁华内存分段机制 在冯诺依曼机中,内存是一整块。数据放在数据段,代码放在代码段,二者之间不能混合。假设内存分布如下。 JVM的实现 CodeSection类 为了模拟内存中的这种机制,首先定义了CodeSection类。该类用于描述段。 不考虑重定…

内存分段机制

在冯诺依曼机中,内存是一整块。数据放在数据段,代码放在代码段,二者之间不能混合。假设内存分布如下。

在这里插入图片描述

JVM的实现

CodeSection类

为了模拟内存中的这种机制,首先定义了CodeSection类。该类用于描述段。

在这里插入图片描述

不考虑重定位计算,该类的关键属性包括下面几个方面

属性名备注
_start数据记录内存起始地址
_end当前数据记录内存终止地址
_limit分配的最后一个地址
_mark这个属性用于标记该段section,一般就是第一条指令
_index用于标记该段属于什么类型。

在这里插入图片描述

注意,通常我们在Java或者C#中描述某种固定类型通常使用enum关键字描述,但由于Java和C#是强类型语言,因此都是用enum的具体值来描述。例如在C#中定义段类型:

public enum EnumCodeSectionType{SECT_CONSTS,   //放置常量值SECT_INST,     //放置指令值SECT_STUB,     //放置装代码SECT_NONE=-1   //非代码段
}public class CodeSection{private EnumCodeSectionType _codeSectionType=;...
}

但是C或者C++是弱类型语言,其枚举类型的本质是整形,因此段枚举如下:

enum {// Here is the list of all possible sections.  The order reflects// the final layout.SECT_FIRST = 0,SECT_CONSTS = SECT_FIRST, // Non-instruction data:  Floats, jump tables, etc.SECT_INSTS,               // Executable instructions.SECT_STUBS,               // Outbound trampolines for supporting call sites.SECT_LIMIT, SECT_NONE = -1};

我们在CodeSection类中,使用_index字段描述该该枚举值。

public class CodeSection{private:int _index;  //默认值由构造函数决定,否则为原内存中的遗留值
}

CodeBuffer类

在JVM中,定义CodeBuffer类用于保存各种CodeSection

在这里插入图片描述

这里可以看到有3个CodeSection类对象,分别是_consts,_insts以及_stubs。这3个字段分别对应3种CodeSection。在内存上的分别可以用下图显示。

在这里插入图片描述

其他相关字段功能如下

字段名用途
_nameCodeBuffer的名称,用于打印信息
_total_start整个CodeBuffer的起始地址
_total_size整个CodeBuffer的大小
_last_insn最后一条指令

如何将指令插入_insts字段

假设使用的电脑架构是x86,使用gdb进行java -version命令的调试
build/linux-x86_64-normal-server-slowdebug/jdk/bin目录下新建.gdbinit文件

handle SIGSEGV pass noprint nostop
handle SIGUSR1 pass noprint nostop
handle SIGUSR2 pass noprint nostop
set logging on
set breakpoint pending onb mainr -Xint -version

这里使用-Xint选项表示采用纯解释器模式执行
使用下面的命令启动gdb调试

gdb -command=.gdbinit ./java

运行后,程序停在main函数处

Breakpoint 1, main (argc=3, argv=0x7fffffffe088)at /home/jx/src/openjdk/src/java.base/share/native/launcher/main.c:98
98      

此时,根据《openjdk底层(hotspot)汇编指令调用(四)——发送指令到内存》中讲述的内容,将断点设置在的下面函数处

//assembler.hpp
void emit_int8(   int8_t  x) { code_section()->emit_int8(   x); }

gdb打印信息如下

(gdb) b emit_int8
Function "emit_int8" not defined.
Breakpoint 2 (emit_int8) pending.
(gdb) c
Continuing.
[New Thread 0x7ffff7fe0700 (LWP 12619)]
[Switching to Thread 0x7ffff7fe0700 (LWP 12619)]Thread 2 "java" hit Breakpoint 2, AbstractAssembler::emit_int8 (this=0x7ffff001bbb0, x=-123 '\205') at /home/jx/src/openjdk/src/hotspot/share/asm/assembler.hpp:273
273       void emit_int8(   int8_t  x) { code_section()->emit_int8(   x); }
(gdb) s
AbstractAssembler::code_section (this=0x7ffff001bbb0)at /home/jx/src/openjdk/src/hotspot/share/asm/assembler.hpp:306
306       CodeSection*  code_section() const   { return _code_section; }
(gdb) print *_code_section
$1 = {_start = 0x7fffec9c20a0 '\314' <repeats 63 times>, <incomplete sequence \314>, _mark = 0x0, _end = 0x7fffec9c20a0 '\314' <repeats 63 times>, <incomplete sequence \314>, _limit = 0x7fffec9c20e0 "", _locs_start = 0x0, _locs_end = 0x0, _locs_limit = 0x0, _locs_point = 0x7fffec9c20a0 '\314' <repeats 63 times>, <incomplete sequence \314>, _locs_own = false, _frozen = false, _scratch_emit = false, _index = 1 '\001', _outer = 0x7ffff7fdf890
}

这里可以看到该CodeSection类对象的信息,

其中_index=1,结合上述的类图以及段类型枚举可知,当前CodeSection是SECT_INST类型,即代码段。

该段的起始地址和终止地址由_start和_end对象描述,由于是第一条插入的指令,因此二者相等

_start = 0x7fffec9c20a0
_end   = 0x7fffec9c20a0

该段最大只能到_limit处

_limit = 0x7fffec9c20e0

对应到内存的图形分布如下
在这里插入图片描述

可以看到该代码段有几个特征。

  • 起始地址能够被8整除,这样有利于CPU访存的速度
  • 整个代码段的长度是64字节,也有利于CPU访存速度

我们再让其运行到emit_8int处看看

Thread 2 "java" hit Breakpoint 2, AbstractAssembler::emit_int8 (this=0x7ffff001bbb0, x=-10 '\366') at /home/jx/src/openjdk/src/hotspot/share/asm/assembler.hpp:273
273       void emit_int8(   int8_t  x) { code_section()->emit_int8(   x); }
(gdb) s
AbstractAssembler::code_section (this=0x7ffff001bbb0)at /home/jx/src/openjdk/src/hotspot/share/asm/assembler.hpp:306
306       CodeSection*  code_section() const   { return _code_section; }
(gdb) print *_code_section
$2 = {_start = 0x7fffec9c20a0 "\205", '\314' <repeats 62 times>, <incomplete sequence \314>, _mark = 0x0, _end = 0x7fffec9c20a1 '\314' <repeats 62 times>, <incomplete sequence \314>, _limit = 0x7fffec9c20e0 "", _locs_start = 0x0, _locs_end = 0x0, _locs_limit = 0x0, _locs_point = 0x7fffec9c20a0 "\205", '\314' <repeats 62 times>, <incomplete sequence \314>, _locs_own = false, _frozen = false, _scratch_emit = false, _index = 1 '\001', _outer = 0x7ffff7fdf890
}

此时可以看到_end的值发生了改变

_start = 0x7fffec9c20a0
_end   = 0x7fffec9c20a1

可以看到_end的地址增加了1个字节,即8位
在这里插入图片描述

我们此时再看看_outer属性,该属性对应了CodeBuffer,即哪个CodeBuffer拥有该CodeSection

(gdb) print *_code_section->_outer
$4 = {<StackObj> = {<AllocatedObj> = {_vptr.AllocatedObj = 0x7ffff6fb7110 <vtable for CodeBuffer+16>}, <No data fields>}, members of CodeBuffer: _name = 0x7ffff6540ab4 "static buffer", _consts = {_start = 0x0, _mark = 0x0, _end = 0x0, _limit = 0x0, _locs_start = 0x0, _locs_end = 0x0, _locs_limit = 0x0, _locs_point = 0x0, _locs_own = false, _frozen = false, _scratch_emit = false, _index = 0 '\000', _outer = 0x7ffff7fdf890}, _insts = {_start = 0x7fffec9c20a0 "\205", '\314' <repeats 62 times>, <incomplete sequence \314>, _mark = 0x0, _end = 0x7fffec9c20a1 '\314' <repeats 62 times>, <incomplete sequence \314>, _limit = 0x7fffec9c20e0 "", _locs_start = 0x0, _locs_end = 0x0, _locs_limit = 0x0, _locs_point = 0x7fffec9c20a0 "\205", '\314' <repeats 62 times>, <incomplete sequence \314>, _locs_own = false, _frozen = false, _scratch_emit = false, _index = 1 '\001', _outer = 0x7ffff7fdf890}, _stubs = {_start = 0x0, _mark = 0x0, _end = 0x0, _limit = 0x0, _locs_start = 0x0, _locs_end = 0x0, _locs_limit = 0x0, _locs_point = 0x0, _locs_own = false, _frozen = false, _scratch_emit = false, _index = 2 '\002', _outer = 0x7ffff7fdf890}, 

看到了吗?这个CodeBuffer只有代码段有效,其他的段(_consts, _stubs)的起始地址都是0x0,而且_insts段的起始地址跟我们上面调试的起始地址一样。

总结

通过assembler生成的汇编指令机器码都放在CodeBuffer_insts字段所指的内存区域中。


文章转载自:

http://GUDSBhDk.kpygy.cn
http://6UUuI1KD.kpygy.cn
http://HnFS7np8.kpygy.cn
http://Pz7nNYUO.kpygy.cn
http://IwiwAHcS.kpygy.cn
http://jO7TnJss.kpygy.cn
http://a3OeoP2I.kpygy.cn
http://M40L2JK9.kpygy.cn
http://xDyPiSbT.kpygy.cn
http://vtvtZWCQ.kpygy.cn
http://9jEWRzz4.kpygy.cn
http://gRYQs68a.kpygy.cn
http://rD9kx655.kpygy.cn
http://aOSeU1KC.kpygy.cn
http://8MWKMOZj.kpygy.cn
http://f81mTDSz.kpygy.cn
http://wb4Um2VM.kpygy.cn
http://uUMUpbf5.kpygy.cn
http://zAENLiYn.kpygy.cn
http://jdZPASrV.kpygy.cn
http://tADeOJUL.kpygy.cn
http://Lsqu0tIg.kpygy.cn
http://rN15X0VZ.kpygy.cn
http://9841aMsA.kpygy.cn
http://fKRaDEGV.kpygy.cn
http://BRMJXLGf.kpygy.cn
http://Jo6ZZQ64.kpygy.cn
http://kjdj45RT.kpygy.cn
http://tjevugLv.kpygy.cn
http://R2QFV7HN.kpygy.cn
http://www.dtcms.com/wzjs/657838.html

相关文章:

  • 做网站的程序员厦门关键词seo排名网站
  • 网站做水印有没有影响吗软件定制开发公司排名
  • 做网站最好的软件ps制作网站模板
  • 做网站需要每年都缴费吗wordpress用户修改邮箱
  • 网站建设服务商城整站优化和单词
  • 中医网站模板做携程网站的技术
  • 网站后台上传图片不显示淘宝店铺首页装修
  • 佛山建设局官方网站龙岗网红公园
  • 购物网站主页设计图中国网重庆频道
  • 做网站和微信公众号如何招生免费资源部落wordpress
  • 单位网站建设典型材料免费ai写作网站3000字
  • 企业宣传网站建设用jsp做网站步骤
  • 档案网站建设与知识管理好的文案网站
  • 重庆最新网站备案网站建设方案文本模板
  • c2c电子商务网站建设吉林省建设厅网站特殊工种
  • 玉溪住房和城乡建设局网站织梦手机网站怎么修改密码
  • 番禺区住房和建设局物业网站淘宝客网站都用什么做
  • 域名 和网站有什么区别朝阳周边网站建设
  • 网站建设需要哪些准备莱芜网站建设哪里有
  • 装饰网站建设套餐报价seo外贸网站建设
  • 门户网站建设自查整改报告wordpress 自带的ajax
  • wordpress 浏览人数官网seo优化找哪家做
  • 在百度做个卷闸门网站怎么做WordPress快速发布文章
  • 福永营销型网站多少钱宣传视频
  • 网站建设用到什么软件企业网站建设综合实训心得
  • 河南郑州网站顾问dw如何做商业网站
  • 企业管理网站建设网站开发建站微信公众号小程序
  • 东莞住房和建设局网站腾讯云网站建设
  • asp 网站打不开网站优化的优势
  • 网站域名注册价格个人博客网站取名