2012-05-12 31 views
7

Trong bytecode java tại sao người nhận được đẩy lên ngăn xếp trước tiên theo sau là tất cả các tham số? Tôi dường như nhớ nó là một cái gì đó để làm với hiệu quả.Thứ tự mã Java của thứ tự này và các thông số trên ngăn xếp

Điều này đúng cho cả hai cuộc gọi phương thức và trường cài đặt.

Method Gọi

class X { 

    int p(int a) { 
     //Do something 
    } 
    int main() { 
     int ret = p(1); 
    } 

} 

phương thức Main biên dịch để:

aload_0 // Load this onto the stack 
iconst_1 // Load constant 1 onto the stack 
invokevirtual <int p(int)> from class X 

Thiết lập một lĩnh vực:

class X { 
    int x; 
    int main() { 
     x = 1; 
    } 

} 

phương thức Main biên dịch để:

aload_0 // Load this onto the stack 
iconst_1 // Load constant 1 onto the stack 
putfield <int x> from class X 
+0

Hãy suy nghĩ tôi đã tìm ra nhưng tôi không thể trả lời vì tôi không có đủ điểm! –

+0

Đây là một trong những câu hỏi "sự tò mò nhàn rỗi" đó. Thú vị, nhưng câu trả lời là không sử dụng thực tế ... trừ khi bạn đang dự tính thiết kế một bộ hướng dẫn bytecode hoàn toàn mới. –

+1

điểm của bạn là? Học cách máy tính hoạt động như thế nào là một câu hỏi "tò mò nhàn rỗi" nhất. –

Trả lời

1

Bị đẩy đầu tiên có lợi thế ở chỗ phương pháp

  • Mục tiêu có thể sử dụng dày đặc hơn "aload0" bytecode (nhỏ hơn thể nó là muộn hơn nhiều trong danh sách tham số và đã phải sử dụng một phiên bản tham số của Bởi vì "điều này" thường được tham chiếu trong các phương thức cho cả truy cập trường và phương thức, nó dẫn đến sự cải thiện mật độ mã thực.
  • Một phương thức xếp tầng thường gửi như "foo.bar(). baz()" Khi bar() trả về, tương lai "this" cho .baz() là một cách kỳ diệu đã ở đúng nơi trên ngăn xếp nếu bạn sắp xếp mọi thứ như đã được thực hiện trong Java.
+0

Những câu trả lời này là hợp lý, nhưng trên thực tế, các bytecode được biên dịch thành mã gốc, và cả hai lợi thế này đều không phát ra một khi điều đó xảy ra. –

+0

Điều đó không đúng đối với điểm thứ hai trên hầu hết các kiến ​​trúc RISC như POWER, nơi cả hai tham số và giá trị trả về đều thực sự trong thanh ghi. Có chúng xếp hàng chính xác (return -> arg 0) hoạt động rất tốt và cải thiện hiệu suất. Ngoài ra, ở điểm đầu tiên, trong khi 1 byte không có vẻ nhiều, JVM thường phải giữ các byte trong bộ nhớ (nghĩ lớp viết lại, vv .. từ JVMTI) và thêm tất cả những byte đã lưu vào hàng nghìn lớp thêm vào bộ nhớ không tầm thường. –

+0

Bạn giả sử rằng bố cục ngăn xếp ảo trong mô hình bytecode giống với bố cục ngăn xếp vật lý được sử dụng bởi mã được biên dịch JIT. Bạn có thể biện minh cho giả định đó không? Sử dụng lại bộ nhớ, tiết kiệm hàng chục hoặc hàng trăm nghìn byte bytecode >> là << tầm thường ... trên các máy có gigabyte bộ nhớ vật lý. Bên cạnh đó, một khi các bytecode được JIT biên dịch, chúng có thể được thu gom rác. (Tôi không chắc chắn nếu họ là ...) Và tối ưu hóa cho các trường hợp JVMTI có vẻ như là vô nghĩa. –

1

Bạn có hỏi tại sao nó được đẩy không? Trong cả hai trường hợp, bạn đang truy cập vào thứ gì đó thuộc về một thể hiện của lớp, vì vậy this phải là một phần của quá trình đó.

Bạn có hỏi tại sao nó được đẩy trước không? Chỉ cần quy ước Java. Tôi đoán nó là thuận tiện để luôn luôn có this đầu tiên bất kể nhiều điều có thể làm theo.

+0

Yêu cầu sau này. Các ví dụ rõ ràng cho thấy rằng tôi biết lý do tại sao điều này là có. Đó là lý do tôi nghĩ đến nhưng nó sẽ không cho phép tôi đăng bài. Nó không có vẻ là hiệu quả dựa trên như tôi chắc chắn tôi đã nói rằng nó được. Giả thuyết, ngay cả khi điều này là cuối cùng bạn vẫn có thể giải quyết vị trí của nó tĩnh tại biên dịch. Tôi không thể nghĩ ra bất cứ điều gì có nghĩa là bạn không thể mặc dù tôi chỉ biết các cấu trúc JVM rất cơ bản. –

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