2011-08-28 41 views
9

Tôi chỉ tò mò là làm thế nào nó có thể cho Java JVM để đôi khi nội tuyến phương pháp có khả năng ném ngoại lệ. Tôi giả sử rằng có thể nội tuyến ít nhất một số phương pháp như vậy (chẳng hạn như những phương thức có truy cập mảng và do đó có khả năng ném ArrayIndexOutOfBoundsException s). Vấn đề tôi thấy là nếu ngoại lệ thực sự xảy ra, làm thế nào để bạn hiển thị theo dõi stack đúng nếu bạn đã phác thảo phương pháp? Vì các phương thức khác nhau có thể được gạch chân trên các máy khác nhau, làm cách nào để nội tuyến không phá vỡ cơ chế theo dõi ngăn xếp?Làm cách nào để các phương pháp ném ngoại lệ được gạch chân?

+2

Trong C++, nội tuyến gần như đảm bảo mất thông tin ngăn xếp. Thực tế là một dấu vết ngăn xếp ngoại lệ bị thiếu một khung không phải là kết thúc của thế giới, mặc dù; nó chỉ là một hậu quả được chấp nhận của nội tuyến (và một trong những lý do trình biên dịch cung cấp các tùy chọn chế độ gỡ lỗi để ngăn chặn tất cả nội tuyến). Tôi không biết liệu Java có hoạt động giống nhau hay không. –

+0

Tôi có nghĩa đây là một câu hỏi Java, nhưng thú vị để biết về cách thức hoạt động của nó trong C++. – Gravity

Trả lời

8

Vấn đề bạn dự tính là gì? Vì chính bản thân JVM thực hiện nội tuyến, không có gì ngăn cản nó ghi nhớ những gì nó đã phác thảo ở đâu và chính xác cho điều này khi nó xây dựng một dấu vết ngăn xếp để cài đặt trong một đối tượng Throwable.

Khi ngoại lệ là ném được xây dựng, JVM sẽ đi bộ ngăn xếp CPU và tìm hiểu xem mỗi khung ngăn xếp máy có tương ứng với mã bytecode, mã JITted, mã gốc từ thư viện hay không. Đối với điều này, nó đề cập đến các bảng cho biết địa chỉ nào trong mã máy tương ứng với các lệnh từ bytecode (và tiếp tục quay trở lại các dòng nguồn, nếu thông tin đó là nhấn trong tệp lớp). Bảng này hoàn toàn có thể chỉ rõ rằng một nơi nhất định trong mã JITted có thể tương ứng với nhiều hơn một khung ngăn xếp cấp Java.

Tuy nhiên, JVM không phải là yêu cầu để thực hiện việc này. Nó cũng có thể chỉ đơn giản là để xây dựng dấu vết ngăn xếp với phá vỡ bí ẩn trong đó. Xem javadoc for Throwable.getStackTrace(). (Thậm chí không có yêu cầu rằng một JVM có thể tạo ra các dấu vết ngăn xếp ở tất cả).

3

Bạn có thể muốn kiểm tra this document sẽ giải thích cách xử lý ngoại lệ hoạt động trong JVM:

Mỗi phương pháp mà bắt ngoại lệ được kết hợp với một bảng ngoại lệ đó là giao trong tập tin lớp cùng với các chuỗi bytecode của phương thức . Bảng ngoại lệ có một mục nhập cho mỗi ngoại lệ là bị chặn bởi mỗi khối thử. Mỗi mục có bốn mẩu thông tin: điểm bắt đầu và điểm kết thúc, bù trừ máy tính trong chuỗi bytecode để chuyển đến và chỉ mục hồ bơi không đổi của lớp ngoại lệ là bị bắt.

+0

Tôi sẽ quan tâm để kiểm tra xem nó ra. Tôi đã đặc biệt hỏi về sự tương tác của nội tuyến với ngoại lệ, mặc dù. Dường như nếu một hàm được gạch chân, thông tin dấu vết ngăn xếp sẽ bị mất, nhưng dường như nó không có trong một chương trình Java. – Gravity

+1

Hãy nhớ rằng nội tuyến trong Java diễn ra trong thời gian chạy, không biên dịch thời gian như C/C++, vì vậy bạn không 'mất' bất kỳ thông tin nào. Bất kỳ thông tin nào được tối ưu hóa và cần được lấy ra có thể được lưu trữ trong bảng tra cứu/nhảy. –

+0

Sẽ không lưu trữ thông tin ngoại lệ trong bảng tra cứu gây ra hiệu suất không được chấp nhận, đặc biệt là đối với trường hợp ngoại lệ rất phổ biến như ArrayIndexOutOfBounds? – Gravity

Các vấn đề liên quan