Jvm:编译器需要在方法字节码中的哪些位置指定堆栈映射帧?

时间:2018-06-10 06:15:41

标签: java jvm bytecode java-bytecode-asm

这是//View <?php echo form_open_multipart('Jobs_portal/job_apply')?> <input type="file" name="userfile" accept="application/msword,application/pdf" required=""> <button type="submit">Submit</button> </form> //end view //Controller <Jobs_portal> public function job_apply() { $q=$this->file_upload(); //calling function file_upload if ($q) { $file_attribute=$this->upload->data(); $file_name=$file_attribute['file_name']; $file_path=$file_attribute['file_path']; //calling function attachment_mail to send pdf $this->attachment_mail($file_path,$file_name); } } public function file_upload() { $config['upload_path'] = './uploads/'; $config['allowed_types'] = 'doc|pdf'; $config['max_size'] = 9000; $this->load->library('upload', $config); if ( ! $this->upload->do_upload('userfile')) { $this->upload->display_errors(); echo "Sorry! Apply again. Check Your Resume Format"; return false; } else { echo "i'll reply you after check your Resume. Thanks!"; return true; } } public function attachment_mail($file_path,$file_name) { $this->load->library('email'); $this->load->helper('path'); $this->email->from('No-Reply@ie.com', 'Resume Receive'); $this->email->to('umairhanif2054602@gmail.com'); $this->email->subject('Apply for Job '); $this->email->message('Sir I have attached my Resume for Job'); $this->email->attach($file_path.file_$name); $this->email->send(); echo $this->email->print_debugger(); } //end 用户指南的摘录:

  

为了节省空间,编译方法   每条指令不包含一个帧:实际上它只包含帧   对于与跳转目标或异常处理程序相对应的指令,或   遵循无条件跳转说明。实际上其他帧也可以   从这些中轻松快速地推断出来。

我可以理解为什么jvm需要跳转目标和异常处理程序的堆栈映射帧,但是在asm不必要的要求之后不需要堆栈映射帧,因为必须有跳转方法字节码中某处的指令指向goto指令之后的指令,该情况将由第一个要求处理。它必须是这样的,否则goto之后的指令将无法访问,因此是可废弃的。

示例:

方法及其字节码如下:

goto

索引public class t { public static void main(String[] s) { int i = 10; while ( i > 0 ) { i = i + 1; } int j = 10; } } public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC Code: stack=2, locals=3, args_size=1 0: bipush 10 2: istore_1 3: iload_1 4: ifle 14 7: iload_1 8: iconst_1 9: iadd 10: istore_1 11: goto 3 14: bipush 10 16: istore_2 17: return LineNumberTable: line 9: 0 line 10: 3 line 11: 7 line 13: 14 line 14: 17 StackMapTable: number_of_entries = 2 frame_type = 252 /* append */ offset_delta = 3 locals = [ int ] frame_type = 10 /* same */ } 处的指令是一个goto指令,索引11处的指令有4,这是14之后的指令,因为它是跳转目标。

在无条件跳转后需要堆栈映射帧的理性是什么?

1 个答案:

答案 0 :(得分:5)

堆栈映射的目标是允许在单个线性传递代码中执行验证。

如果goto后面的代码没有指向它的跳转,那么代码就死了,理论上不需要验证。但是,验证者不知道此。由于它在代码中执行单次传递,因此无法提前知道代码是否已死。因此,它必须验证所有内容,这意味着它需要一个堆栈框架来开始。

请注意,这与传统的非堆栈映射验证程序不同。在引入堆栈映射之前,验证器将简单地迭代它找到的所有代码(有效地)跟随跳转,并迭代直到收敛。这意味着在旧的验证器下,根本不会触及死代码。