HGraphBuilder方法分析一
来源:互联网 发布:sql server 权限管理 编辑:程序博客网 时间:2024/06/05 09:21
在~/android-6.0.1_r62/art/compiler/optimizing/builder.cc中为类HGraphBuilder的具体信息:
1/首要分析的方法为: bool AnalyzeDexInstruction(const Instruction& instruction, uint32_t dex_pc);
该方法的主要功能是分析dex instruction,将HInstruction添加到graph中以可以执行该dex instruction。返回值意为,该dex instruction是否能被处理。
具体实现:
A. 1317 if (current_block_ == nullptr) {
1318 return true; // Dead code
1319 }
先检查current_block_ == nullptr,若相等,则直接返回真。
B. switch (instruction.Opcode())
根据Opcode的不同进行不同的处理,类instruction中定义了dex instruction,Opcode()方法返回的是instruction的opcode field,也就是instruction的前16位。
下面以CONST_4为例,总共只有三行代码。
1322 case Instruction::CONST_4: {1323 int32_t register_index = instruction.VRegA();1324 HIntConstant* constant = graph_->GetIntConstant(instruction.VRegB_11n());//HIntConstant类包含的是int类型的常量。1325 UpdateLocal(register_index, constant);1326 break;1327 }
其中CONST_4为dalvik指令const/4:
const/4 vA,#+B 将数值符号扩展为32位后赋值给寄存器vA。
关于dalvik指令更详细的介绍在~/android-6.0.1_r62/art/runtime/dex_instruction_list.h中,例如对于CONST_4:
#define DEX_INSTRUCTION_LIST(V) \V(0x12, CONST_4, "const/4", k11n, true, kNone, kContinue | kRegBFieldOrConstant, kVerifyRegA)
①int32_t register_index = instruction.VRegA();
57 inline int32_t Instruction::VRegA() const { 58 switch (FormatOf(Opcode())) { 59 case k10t: return VRegA_10t(); 60 case k10x: return VRegA_10x(); 61 case k11n: return VRegA_11n(); 62 case k11x: return VRegA_11x(); 63 case k12x: return VRegA_12x(); 64 case k20t: return VRegA_20t(); 65 case k21c: return VRegA_21c(); 66 case k21h: return VRegA_21h(); 67 case k21s: return VRegA_21s(); 68 case k21t: return VRegA_21t(); 69 case k22b: return VRegA_22b(); 70 case k22c: return VRegA_22c(); 71 case k22s: return VRegA_22s(); 72 case k22t: return VRegA_22t(); 73 case k22x: return VRegA_22x(); 74 case k23x: return VRegA_23x(); 75 case k30t: return VRegA_30t(); 76 case k31c: return VRegA_31c(); 77 case k31i: return VRegA_31i(); 78 case k31t: return VRegA_31t(); 79 case k32x: return VRegA_32x(); 80 case k35c: return VRegA_35c(); 81 case k3rc: return VRegA_3rc(); 82 case k51l: return VRegA_51l(); 83 default: 84 LOG(FATAL) << "Tried to access vA of instruction " << Name() << " which has no A operand."; 85 exit(EXIT_FAILURE); 86 }
关于dalvik指令的一些知识:
寄存器有两种不同的命名方法:v字命名法和p字命名法;以小写字母v开头的方式表示方法中使用的局部变量和参数;以小写字母p开头的方式表示参数,参数名称从p0开始,依次增大.局部变量能够使用的寄存器仍然是以v开头.
以指令格式“A|G|op BBBB F|E|D|C”为例:
指令中间有两个空格,每个分开的部分大小为16位,所以这条指令由三个16位的字组成。第一个16位是“A|G|op”,高8位由A与G组成,低字节由操作码op组成。第二个16位由BBBB组成,它表示一个16位的偏移值。第三个16位分别由F,E,D,C共四个4位组成,在这里它们表示寄存器参数。
11n有特殊的含义:
1:指令有多少个16位的字组成
1:指令最多使用寄存器的个数
n:4位的立即数
以指令 “op vAA, string@BBBB” 为例:指令用到了1个寄存器参数 vAA,并且还附加了一个字符串常量池索引 string@BBBB,其实这条指令格式代表着 const-string 指令。
指令格式标示等的参考文献:https://my.oschina.net/fhd/blog/365337
根据DEX_ INSTRUCTION_ LIST中的定义可知:CONST_ 4属于k11n,所以返回的是VRegA_11n(),该函数的具体实现如下:
244 uint4_t VRegA_11n() const {245 return VRegA_11n(Fetch16(0));246 }532 uint16_t Fetch16(size_t offset) const {533 const uint16_t* insns = reinterpret_cast<const uint16_t*>(this);534 return insns[offset];//返回insns的第一个16位字的值。535 }556 uint4_t InstA(uint16_t inst_data) const {557 DCHECK_EQ(inst_data, Fetch16(0));//检查inst_data是否与Fetch16(0)相等558 return static_cast<uint4_t>((inst_data >> 8) & 0x0f);//inst_data右移8位后与00001111进行与运算。559 }
②HIntConstant* constant = graph_ ->GetIntConstant(instruction.VRegB_11n());
GetIntConstant函数的具体实现为:
(在~/android-6.0.1_r62/art/compiler/optimizing/nodes.h的class:art::HGraph中)
266 HIntConstant* GetIntConstant(int32_t value) { 267 return CreateConstant(value, &cached_int_constants_); 268 } //首先试着在cache中寻找给定value的已有的常量,如果没有找到,或者已经被删掉了,那么就创建并cache一个新的指令,最后返回常量。 301 InstructionType* CreateConstant(ValueType value, 302 ArenaSafeMap<ValueType, InstructionType*>* cache) { 303 // Try to find an existing constant of the given value. 304 InstructionType* constant = nullptr; 305 auto cached_constant = cache->find(value); 306 if (cached_constant != cache->end()) { 307 constant = cached_constant->second; 308 } 309 310 // If not found or previously deleted, create and cache a new instruction. 311 if (constant == nullptr || constant->GetBlock() == nullptr) { 312 constant = new (arena_) InstructionType(value); 313 cache->Overwrite(value, constant); 314 InsertConstant(constant); 315 } 316 return constant; 317 }
③UpdateLocal(register_index, constant);
(在~/android-6.0.1_r62/art/compiler/optimizing/builder.cc中)
2295 void HGraphBuilder::UpdateLocal(int register_index, HInstruction* instruction) const {2296 HLocal* local = GetLocalAt(register_index);//HLocal类内是graph中的一个local,也就是方法内的局部变量,与一个dex register相关。2297 current_block_->AddInstruction(new (arena_) HStoreLocal(local, instruction));//HStoreLocal类是将一个value存放(store)在一个给定的local里。该指令有两个输入:value和local。这里是new了一个该类的实例,即将HStoreLocal指令存入了指令序列中。传入的参数中instruction为对应的value。2298 } 2291 HLocal* HGraphBuilder::GetLocalAt(int register_index) const {2292 return locals_.Get(register_index);//locals_的定义为:GrowableArray<HLocal*> locals_;返回的是HLocal*队列中的第register_index个元素。2293 }//HStoreLocal的构造函数2190 HStoreLocal(HLocal* local, HInstruction* value) : HTemplateInstruction(SideEffects::None()) {2191 SetRawInputAt(0, local);2192 SetRawInputAt(1, value);2193 }//~/android-6.0.1_r62/art/compiler/optimizing/nodes.cc中实现: 483 void HBasicBlock::AddInstruction(HInstruction* instruction) { 484 Add(&instructions_, this, instruction);//instruction_的定义为:HInstructionList instructions_; 485 } 472 static void Add(HInstructionList* instruction_list, 473 HBasicBlock* block, 474 HInstruction* instruction) { 475 DCHECK(instruction->GetBlock() == nullptr); 476 DCHECK_EQ(instruction->GetId(), -1); 477 instruction->SetBlock(block); 478 instruction->SetId(block->GetGraph()->GetNextInstructionId()); 479 UpdateInputsUsers(instruction); 480 instruction_list->AddInstruction(instruction); 481 }
- HGraphBuilder方法分析一
- Jquery getJSON方法分析(一)
- Jquery getJSON方法分析(一)
- 如何看懂源代码--(分析源代码方法)一
- 如何看懂源代码--(分析源代码方法) 一
- Jquery getJSON方法分析(一)
- Jquery getJSON方法分析(一)
- Zepto源码分析一~核心方法
- Jquery .ajax方法分析(一)
- Jquery getJSON方法分析(一)
- Jquery getJSON方法分析(一)
- 语义分析的一些方法(一)
- 语义分析的一些方法(一)
- 语义分析的一些方法(一)
- 语义分析的一些方法(一)
- Jquery .ajax方法分析(一)
- 语义分析的一些方法(一)
- 语义分析的一些方法(一)
- js中获取select标签中选中的值
- 微信小程序github源码大全下载
- linux内核进程调度系列之调度概述
- Android
- 合并区间
- HGraphBuilder方法分析一
- 洛谷Oj-逆序对-分治(归并排序)
- HttpClient与参数json
- Logcat打印调试信息
- const各种用法总结
- http 请求头信息解释
- 红色警戒2共和国之辉联机教程(兼容到win10)
- 搭建Zookeeper服务器集群
- 研发人员应对需求的言与行