1.1 --- a/src/share/vm/interpreter/bytecode.hpp Wed Jan 12 13:59:18 2011 -0800 1.2 +++ b/src/share/vm/interpreter/bytecode.hpp Thu Jan 13 22:15:41 2011 -0800 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -38,14 +38,20 @@ 1.11 # include "bytes_zero.hpp" 1.12 #endif 1.13 1.14 -// Base class for different kinds of abstractions working 1.15 -// relative to an objects 'this' pointer. 1.16 +class ciBytecodeStream; 1.17 1.18 -class ThisRelativeObj VALUE_OBJ_CLASS_SPEC { 1.19 - public: 1.20 +// The base class for different kinds of bytecode abstractions. 1.21 +// Provides the primitive operations to manipulate code relative 1.22 +// to the bcp. 1.23 + 1.24 +class Bytecode: public StackObj { 1.25 + protected: 1.26 + const address _bcp; 1.27 + const Bytecodes::Code _code; 1.28 + 1.29 // Address computation 1.30 - address addr_at (int offset) const { return (address)this + offset; } 1.31 - int byte_at (int offset) const { return *(addr_at(offset)); } 1.32 + address addr_at (int offset) const { return (address)_bcp + offset; } 1.33 + u_char byte_at(int offset) const { return *addr_at(offset); } 1.34 address aligned_addr_at (int offset) const { return (address)round_to((intptr_t)addr_at(offset), jintSize); } 1.35 int aligned_offset (int offset) const { return aligned_addr_at(offset) - addr_at(0); } 1.36 1.37 @@ -54,31 +60,20 @@ 1.38 int get_Java_u4_at (int offset) const { return Bytes::get_Java_u4(addr_at(offset)); } 1.39 int get_native_u2_at (int offset) const { return Bytes::get_native_u2(addr_at(offset)); } 1.40 int get_native_u4_at (int offset) const { return Bytes::get_native_u4(addr_at(offset)); } 1.41 -}; 1.42 - 1.43 - 1.44 -// The base class for different kinds of bytecode abstractions. 1.45 -// Provides the primitive operations to manipulate code relative 1.46 -// to an objects 'this' pointer. 1.47 -// FIXME: Make this a ResourceObj, include the enclosing methodOop, and cache the opcode. 1.48 - 1.49 -class Bytecode: public ThisRelativeObj { 1.50 - protected: 1.51 - u_char byte_at(int offset) const { return *addr_at(offset); } 1.52 - bool check_must_rewrite(Bytecodes::Code bc) const; 1.53 1.54 public: 1.55 + Bytecode(methodOop method, address bcp): _bcp(bcp), _code(Bytecodes::code_at(method, addr_at(0))) { 1.56 + assert(method != NULL, "this form requires a valid methodOop"); 1.57 + } 1.58 + // Defined in ciStreams.hpp 1.59 + inline Bytecode(const ciBytecodeStream* stream, address bcp = NULL); 1.60 + 1.61 // Attributes 1.62 - address bcp() const { return addr_at(0); } 1.63 - int instruction_size() const { return Bytecodes::length_at(bcp()); } 1.64 + address bcp() const { return _bcp; } 1.65 + int instruction_size() const { return Bytecodes::length_for_code_at(_code, bcp()); } 1.66 1.67 - // Warning: Use code() with caution on live bytecode streams. 4926272 1.68 - Bytecodes::Code code() const { return Bytecodes::code_at(addr_at(0)); } 1.69 + Bytecodes::Code code() const { return _code; } 1.70 Bytecodes::Code java_code() const { return Bytecodes::java_code(code()); } 1.71 - bool must_rewrite(Bytecodes::Code code) const { return Bytecodes::can_rewrite(code) && check_must_rewrite(code); } 1.72 - 1.73 - // Creation 1.74 - inline friend Bytecode* Bytecode_at(address bcp); 1.75 1.76 // Static functions for parsing bytecodes in place. 1.77 int get_index_u1(Bytecodes::Code bc) const { 1.78 @@ -89,7 +84,7 @@ 1.79 assert_same_format_as(bc, is_wide); assert_index_size(2, bc, is_wide); 1.80 address p = addr_at(is_wide ? 2 : 1); 1.81 if (can_use_native_byte_order(bc, is_wide)) 1.82 - return Bytes::get_native_u2(p); 1.83 + return Bytes::get_native_u2(p); 1.84 else return Bytes::get_Java_u2(p); 1.85 } 1.86 int get_index_u1_cpcache(Bytecodes::Code bc) const { 1.87 @@ -138,20 +133,17 @@ 1.88 } 1.89 }; 1.90 1.91 -inline Bytecode* Bytecode_at(address bcp) { 1.92 - // Warning: Use with caution on live bytecode streams. 4926272 1.93 - return (Bytecode*)bcp; 1.94 -} 1.95 - 1.96 1.97 // Abstractions for lookupswitch bytecode 1.98 +class LookupswitchPair VALUE_OBJ_CLASS_SPEC { 1.99 + private: 1.100 + const address _bcp; 1.101 1.102 -class LookupswitchPair: ThisRelativeObj { 1.103 - private: 1.104 - int _match; 1.105 - int _offset; 1.106 + address addr_at (int offset) const { return _bcp + offset; } 1.107 + int get_Java_u4_at (int offset) const { return Bytes::get_Java_u4(addr_at(offset)); } 1.108 1.109 public: 1.110 + LookupswitchPair(address bcp): _bcp(bcp) {} 1.111 int match() const { return get_Java_u4_at(0 * jintSize); } 1.112 int offset() const { return get_Java_u4_at(1 * jintSize); } 1.113 }; 1.114 @@ -159,26 +151,25 @@ 1.115 1.116 class Bytecode_lookupswitch: public Bytecode { 1.117 public: 1.118 + Bytecode_lookupswitch(methodOop method, address bcp): Bytecode(method, bcp) { verify(); } 1.119 + // Defined in ciStreams.hpp 1.120 + inline Bytecode_lookupswitch(const ciBytecodeStream* stream); 1.121 void verify() const PRODUCT_RETURN; 1.122 1.123 // Attributes 1.124 int default_offset() const { return get_Java_u4_at(aligned_offset(1 + 0*jintSize)); } 1.125 int number_of_pairs() const { return get_Java_u4_at(aligned_offset(1 + 1*jintSize)); } 1.126 - LookupswitchPair* pair_at(int i) const { assert(0 <= i && i < number_of_pairs(), "pair index out of bounds"); 1.127 - return (LookupswitchPair*)aligned_addr_at(1 + (1 + i)*2*jintSize); } 1.128 - // Creation 1.129 - inline friend Bytecode_lookupswitch* Bytecode_lookupswitch_at(address bcp); 1.130 + LookupswitchPair pair_at(int i) const { 1.131 + assert(0 <= i && i < number_of_pairs(), "pair index out of bounds"); 1.132 + return LookupswitchPair(aligned_addr_at(1 + (1 + i)*2*jintSize)); 1.133 + } 1.134 }; 1.135 1.136 -inline Bytecode_lookupswitch* Bytecode_lookupswitch_at(address bcp) { 1.137 - Bytecode_lookupswitch* b = (Bytecode_lookupswitch*)bcp; 1.138 - DEBUG_ONLY(b->verify()); 1.139 - return b; 1.140 -} 1.141 - 1.142 - 1.143 class Bytecode_tableswitch: public Bytecode { 1.144 public: 1.145 + Bytecode_tableswitch(methodOop method, address bcp): Bytecode(method, bcp) { verify(); } 1.146 + // Defined in ciStreams.hpp 1.147 + inline Bytecode_tableswitch(const ciBytecodeStream* stream); 1.148 void verify() const PRODUCT_RETURN; 1.149 1.150 // Attributes 1.151 @@ -187,52 +178,36 @@ 1.152 int high_key() const { return get_Java_u4_at(aligned_offset(1 + 2*jintSize)); } 1.153 int dest_offset_at(int i) const; 1.154 int length() { return high_key()-low_key()+1; } 1.155 - 1.156 - // Creation 1.157 - inline friend Bytecode_tableswitch* Bytecode_tableswitch_at(address bcp); 1.158 }; 1.159 1.160 -inline Bytecode_tableswitch* Bytecode_tableswitch_at(address bcp) { 1.161 - Bytecode_tableswitch* b = (Bytecode_tableswitch*)bcp; 1.162 - DEBUG_ONLY(b->verify()); 1.163 - return b; 1.164 -} 1.165 - 1.166 - 1.167 // Common code for decoding invokes and field references. 1.168 1.169 -class Bytecode_member_ref: public ResourceObj { 1.170 +class Bytecode_member_ref: public Bytecode { 1.171 protected: 1.172 - methodHandle _method; // method containing the bytecode 1.173 - int _bci; // position of the bytecode 1.174 + const methodHandle _method; // method containing the bytecode 1.175 1.176 - Bytecode_member_ref(methodHandle method, int bci) : _method(method), _bci(bci) {} 1.177 + Bytecode_member_ref(methodHandle method, int bci) : Bytecode(method(), method()->bcp_from(bci)), _method(method) {} 1.178 + 1.179 + methodHandle method() const { return _method; } 1.180 1.181 public: 1.182 - // Attributes 1.183 - methodHandle method() const { return _method; } 1.184 - int bci() const { return _bci; } 1.185 - address bcp() const { return _method->bcp_from(bci()); } 1.186 - Bytecode* bytecode() const { return Bytecode_at(bcp()); } 1.187 - 1.188 int index() const; // cache index (loaded from instruction) 1.189 int pool_index() const; // constant pool index 1.190 symbolOop name() const; // returns the name of the method or field 1.191 symbolOop signature() const; // returns the signature of the method or field 1.192 1.193 BasicType result_type(Thread* thread) const; // returns the result type of the getfield or invoke 1.194 - 1.195 - Bytecodes::Code code() const { return Bytecodes::code_at(bcp(), _method()); } 1.196 - Bytecodes::Code java_code() const { return Bytecodes::java_code(code()); } 1.197 }; 1.198 1.199 // Abstraction for invoke_{virtual, static, interface, special} 1.200 1.201 class Bytecode_invoke: public Bytecode_member_ref { 1.202 protected: 1.203 - Bytecode_invoke(methodHandle method, int bci) : Bytecode_member_ref(method, bci) {} 1.204 + // Constructor that skips verification 1.205 + Bytecode_invoke(methodHandle method, int bci, bool unused) : Bytecode_member_ref(method, bci) {} 1.206 1.207 public: 1.208 + Bytecode_invoke(methodHandle method, int bci) : Bytecode_member_ref(method, bci) { verify(); } 1.209 void verify() const; 1.210 1.211 // Attributes 1.212 @@ -253,31 +228,20 @@ 1.213 is_invokespecial() || 1.214 is_invokedynamic(); } 1.215 1.216 - // Creation 1.217 - inline friend Bytecode_invoke* Bytecode_invoke_at(methodHandle method, int bci); 1.218 - 1.219 - // Like Bytecode_invoke_at. Instead it returns NULL if the bci is not at an invoke. 1.220 - inline friend Bytecode_invoke* Bytecode_invoke_at_check(methodHandle method, int bci); 1.221 + // Helper to skip verification. Used is_valid() to check if the result is really an invoke 1.222 + inline friend Bytecode_invoke Bytecode_invoke_check(methodHandle method, int bci); 1.223 }; 1.224 1.225 -inline Bytecode_invoke* Bytecode_invoke_at(methodHandle method, int bci) { 1.226 - Bytecode_invoke* b = new Bytecode_invoke(method, bci); 1.227 - DEBUG_ONLY(b->verify()); 1.228 - return b; 1.229 -} 1.230 - 1.231 -inline Bytecode_invoke* Bytecode_invoke_at_check(methodHandle method, int bci) { 1.232 - Bytecode_invoke* b = new Bytecode_invoke(method, bci); 1.233 - return b->is_valid() ? b : NULL; 1.234 +inline Bytecode_invoke Bytecode_invoke_check(methodHandle method, int bci) { 1.235 + return Bytecode_invoke(method, bci, false); 1.236 } 1.237 1.238 1.239 // Abstraction for all field accesses (put/get field/static) 1.240 class Bytecode_field: public Bytecode_member_ref { 1.241 - protected: 1.242 - Bytecode_field(methodHandle method, int bci) : Bytecode_member_ref(method, bci) {} 1.243 + public: 1.244 + Bytecode_field(methodHandle method, int bci) : Bytecode_member_ref(method, bci) { verify(); } 1.245 1.246 - public: 1.247 // Testers 1.248 bool is_getfield() const { return java_code() == Bytecodes::_getfield; } 1.249 bool is_putfield() const { return java_code() == Bytecodes::_putfield; } 1.250 @@ -292,131 +256,64 @@ 1.251 is_getstatic() || 1.252 is_putstatic(); } 1.253 void verify() const; 1.254 - 1.255 - // Creation 1.256 - inline friend Bytecode_field* Bytecode_field_at(methodHandle method, int bci); 1.257 }; 1.258 1.259 -inline Bytecode_field* Bytecode_field_at(methodHandle method, int bci) { 1.260 - Bytecode_field* b = new Bytecode_field(method, bci); 1.261 - DEBUG_ONLY(b->verify()); 1.262 - return b; 1.263 -} 1.264 - 1.265 - 1.266 // Abstraction for checkcast 1.267 - 1.268 class Bytecode_checkcast: public Bytecode { 1.269 public: 1.270 + Bytecode_checkcast(methodOop method, address bcp): Bytecode(method, bcp) { verify(); } 1.271 void verify() const { assert(Bytecodes::java_code(code()) == Bytecodes::_checkcast, "check checkcast"); } 1.272 1.273 // Returns index 1.274 long index() const { return get_index_u2(Bytecodes::_checkcast); }; 1.275 - 1.276 - // Creation 1.277 - inline friend Bytecode_checkcast* Bytecode_checkcast_at(address bcp); 1.278 }; 1.279 1.280 -inline Bytecode_checkcast* Bytecode_checkcast_at(address bcp) { 1.281 - Bytecode_checkcast* b = (Bytecode_checkcast*)bcp; 1.282 - DEBUG_ONLY(b->verify()); 1.283 - return b; 1.284 -} 1.285 - 1.286 - 1.287 // Abstraction for instanceof 1.288 - 1.289 class Bytecode_instanceof: public Bytecode { 1.290 public: 1.291 + Bytecode_instanceof(methodOop method, address bcp): Bytecode(method, bcp) { verify(); } 1.292 void verify() const { assert(code() == Bytecodes::_instanceof, "check instanceof"); } 1.293 1.294 // Returns index 1.295 long index() const { return get_index_u2(Bytecodes::_instanceof); }; 1.296 - 1.297 - // Creation 1.298 - inline friend Bytecode_instanceof* Bytecode_instanceof_at(address bcp); 1.299 }; 1.300 1.301 -inline Bytecode_instanceof* Bytecode_instanceof_at(address bcp) { 1.302 - Bytecode_instanceof* b = (Bytecode_instanceof*)bcp; 1.303 - DEBUG_ONLY(b->verify()); 1.304 - return b; 1.305 -} 1.306 - 1.307 - 1.308 class Bytecode_new: public Bytecode { 1.309 public: 1.310 + Bytecode_new(methodOop method, address bcp): Bytecode(method, bcp) { verify(); } 1.311 void verify() const { assert(java_code() == Bytecodes::_new, "check new"); } 1.312 1.313 // Returns index 1.314 long index() const { return get_index_u2(Bytecodes::_new); }; 1.315 - 1.316 - // Creation 1.317 - inline friend Bytecode_new* Bytecode_new_at(address bcp); 1.318 }; 1.319 1.320 -inline Bytecode_new* Bytecode_new_at(address bcp) { 1.321 - Bytecode_new* b = (Bytecode_new*)bcp; 1.322 - DEBUG_ONLY(b->verify()); 1.323 - return b; 1.324 -} 1.325 - 1.326 - 1.327 class Bytecode_multianewarray: public Bytecode { 1.328 public: 1.329 + Bytecode_multianewarray(methodOop method, address bcp): Bytecode(method, bcp) { verify(); } 1.330 void verify() const { assert(java_code() == Bytecodes::_multianewarray, "check new"); } 1.331 1.332 // Returns index 1.333 long index() const { return get_index_u2(Bytecodes::_multianewarray); }; 1.334 - 1.335 - // Creation 1.336 - inline friend Bytecode_multianewarray* Bytecode_multianewarray_at(address bcp); 1.337 }; 1.338 1.339 -inline Bytecode_multianewarray* Bytecode_multianewarray_at(address bcp) { 1.340 - Bytecode_multianewarray* b = (Bytecode_multianewarray*)bcp; 1.341 - DEBUG_ONLY(b->verify()); 1.342 - return b; 1.343 -} 1.344 - 1.345 - 1.346 class Bytecode_anewarray: public Bytecode { 1.347 public: 1.348 + Bytecode_anewarray(methodOop method, address bcp): Bytecode(method, bcp) { verify(); } 1.349 void verify() const { assert(java_code() == Bytecodes::_anewarray, "check anewarray"); } 1.350 1.351 // Returns index 1.352 long index() const { return get_index_u2(Bytecodes::_anewarray); }; 1.353 - 1.354 - // Creation 1.355 - inline friend Bytecode_anewarray* Bytecode_anewarray_at(address bcp); 1.356 }; 1.357 1.358 -inline Bytecode_anewarray* Bytecode_anewarray_at(address bcp) { 1.359 - Bytecode_anewarray* b = (Bytecode_anewarray*)bcp; 1.360 - DEBUG_ONLY(b->verify()); 1.361 - return b; 1.362 -} 1.363 - 1.364 - 1.365 // Abstraction for ldc, ldc_w and ldc2_w 1.366 - 1.367 -class Bytecode_loadconstant: public ResourceObj { 1.368 +class Bytecode_loadconstant: public Bytecode { 1.369 private: 1.370 - int _bci; 1.371 - methodHandle _method; 1.372 - 1.373 - Bytecodes::Code code() const { return bytecode()->code(); } 1.374 + const methodHandle _method; 1.375 1.376 int raw_index() const; 1.377 1.378 - Bytecode_loadconstant(methodHandle method, int bci) : _method(method), _bci(bci) {} 1.379 - 1.380 public: 1.381 - // Attributes 1.382 - methodHandle method() const { return _method; } 1.383 - int bci() const { return _bci; } 1.384 - address bcp() const { return _method->bcp_from(bci()); } 1.385 - Bytecode* bytecode() const { return Bytecode_at(bcp()); } 1.386 + Bytecode_loadconstant(methodHandle method, int bci): Bytecode(method(), method->bcp_from(bci)), _method(method) { verify(); } 1.387 1.388 void verify() const { 1.389 assert(_method.not_null(), "must supply method"); 1.390 @@ -437,15 +334,6 @@ 1.391 BasicType result_type() const; // returns the result type of the ldc 1.392 1.393 oop resolve_constant(TRAPS) const; 1.394 - 1.395 - // Creation 1.396 - inline friend Bytecode_loadconstant* Bytecode_loadconstant_at(methodHandle method, int bci); 1.397 }; 1.398 1.399 -inline Bytecode_loadconstant* Bytecode_loadconstant_at(methodHandle method, int bci) { 1.400 - Bytecode_loadconstant* b = new Bytecode_loadconstant(method, bci); 1.401 - DEBUG_ONLY(b->verify()); 1.402 - return b; 1.403 -} 1.404 - 1.405 #endif // SHARE_VM_INTERPRETER_BYTECODE_HPP