Mercurial > hg > truffle
comparison src/share/vm/interpreter/bytecode.hpp @ 726:be93aad57795
6655646: dynamic languages need dynamically linked call sites
Summary: invokedynamic instruction (JSR 292 RI)
Reviewed-by: twisti, never
author | jrose |
---|---|
date | Tue, 21 Apr 2009 23:21:04 -0700 |
parents | a61af66fc99e |
children | bd02caa94611 |
comparison
equal
deleted
inserted
replaced
725:928912ce8438 | 726:be93aad57795 |
---|---|
63 | 63 |
64 | 64 |
65 // The base class for different kinds of bytecode abstractions. | 65 // The base class for different kinds of bytecode abstractions. |
66 // Provides the primitive operations to manipulate code relative | 66 // Provides the primitive operations to manipulate code relative |
67 // to an objects 'this' pointer. | 67 // to an objects 'this' pointer. |
68 // | |
69 // Note: Even though it seems that the fast_index & set_fast_index | |
70 // functions are machine specific, they're not. They only use | |
71 // the natural way to store a 16bit index on a given machine, | |
72 // independent of the particular byte ordering. Since all other | |
73 // places in the system that refer to these indices use the | |
74 // same method (the natural byte ordering on the platform) | |
75 // this will always work and be machine-independent). | |
76 | 68 |
77 class Bytecode: public ThisRelativeObj { | 69 class Bytecode: public ThisRelativeObj { |
78 protected: | 70 protected: |
79 u_char byte_at(int offset) const { return *addr_at(offset); } | 71 u_char byte_at(int offset) const { return *addr_at(offset); } |
80 bool check_must_rewrite() const; | 72 bool check_must_rewrite() const; |
81 | 73 |
82 public: | 74 public: |
83 // Attributes | 75 // Attributes |
84 address bcp() const { return addr_at(0); } | 76 address bcp() const { return addr_at(0); } |
85 address next_bcp() const { return addr_at(0) + Bytecodes::length_at(bcp()); } | 77 address next_bcp() const { return addr_at(0) + Bytecodes::length_at(bcp()); } |
78 int instruction_size() const { return Bytecodes::length_at(bcp()); } | |
86 | 79 |
87 Bytecodes::Code code() const { return Bytecodes::code_at(addr_at(0)); } | 80 Bytecodes::Code code() const { return Bytecodes::code_at(addr_at(0)); } |
88 Bytecodes::Code java_code() const { return Bytecodes::java_code(code()); } | 81 Bytecodes::Code java_code() const { return Bytecodes::java_code(code()); } |
89 bool must_rewrite() const { return Bytecodes::can_rewrite(code()) && check_must_rewrite(); } | 82 bool must_rewrite() const { return Bytecodes::can_rewrite(code()) && check_must_rewrite(); } |
90 bool is_active_breakpoint() const { return Bytecodes::is_active_breakpoint_at(bcp()); } | 83 bool is_active_breakpoint() const { return Bytecodes::is_active_breakpoint_at(bcp()); } |
91 | 84 |
92 int one_byte_index() const { return byte_at(1); } | 85 int one_byte_index() const { assert_index_size(1); return byte_at(1); } |
93 int two_byte_index() const { return (byte_at(1) << 8) + byte_at(2); } | 86 int two_byte_index() const { assert_index_size(2); return (byte_at(1) << 8) + byte_at(2); } |
87 | |
94 int offset() const { return (two_byte_index() << 16) >> 16; } | 88 int offset() const { return (two_byte_index() << 16) >> 16; } |
95 address destination() const { return bcp() + offset(); } | 89 address destination() const { return bcp() + offset(); } |
96 int fast_index() const { return Bytes::get_native_u2(addr_at(1)); } | |
97 | 90 |
98 // Attribute modification | 91 // Attribute modification |
99 void set_code(Bytecodes::Code code); | 92 void set_code(Bytecodes::Code code); |
100 void set_fast_index(int i); | |
101 | 93 |
102 // Creation | 94 // Creation |
103 inline friend Bytecode* Bytecode_at(address bcp); | 95 inline friend Bytecode* Bytecode_at(address bcp); |
96 | |
97 private: | |
98 void assert_index_size(int required_size) const { | |
99 #ifdef ASSERT | |
100 int isize = instruction_size() - 1; | |
101 if (isize == 2 && code() == Bytecodes::_iinc) | |
102 isize = 1; | |
103 else if (isize <= 2) | |
104 ; // no change | |
105 else if (code() == Bytecodes::_invokedynamic) | |
106 isize = 4; | |
107 else | |
108 isize = 2; | |
109 assert(isize = required_size, "wrong index size"); | |
110 #endif | |
111 } | |
104 }; | 112 }; |
105 | 113 |
106 inline Bytecode* Bytecode_at(address bcp) { | 114 inline Bytecode* Bytecode_at(address bcp) { |
107 return (Bytecode*)bcp; | 115 return (Bytecode*)bcp; |
108 } | 116 } |
193 // Testers | 201 // Testers |
194 bool is_invokeinterface() const { return adjusted_invoke_code() == Bytecodes::_invokeinterface; } | 202 bool is_invokeinterface() const { return adjusted_invoke_code() == Bytecodes::_invokeinterface; } |
195 bool is_invokevirtual() const { return adjusted_invoke_code() == Bytecodes::_invokevirtual; } | 203 bool is_invokevirtual() const { return adjusted_invoke_code() == Bytecodes::_invokevirtual; } |
196 bool is_invokestatic() const { return adjusted_invoke_code() == Bytecodes::_invokestatic; } | 204 bool is_invokestatic() const { return adjusted_invoke_code() == Bytecodes::_invokestatic; } |
197 bool is_invokespecial() const { return adjusted_invoke_code() == Bytecodes::_invokespecial; } | 205 bool is_invokespecial() const { return adjusted_invoke_code() == Bytecodes::_invokespecial; } |
206 bool is_invokedynamic() const { return adjusted_invoke_code() == Bytecodes::_invokedynamic; } | |
207 | |
208 bool has_giant_index() const { return is_invokedynamic(); } | |
198 | 209 |
199 bool is_valid() const { return is_invokeinterface() || | 210 bool is_valid() const { return is_invokeinterface() || |
200 is_invokevirtual() || | 211 is_invokevirtual() || |
201 is_invokestatic() || | 212 is_invokestatic() || |
202 is_invokespecial(); } | 213 is_invokespecial(); } |