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(); }