1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/code/codeBlob.hpp Sat Dec 01 00:00:00 2007 +0000 1.3 @@ -0,0 +1,511 @@ 1.4 +/* 1.5 + * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 1.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 1.24 + * have any questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +// CodeBlob - superclass for all entries in the CodeCache. 1.29 +// 1.30 +// Suptypes are: 1.31 +// nmethod : Compiled Java methods (include method that calls to native code) 1.32 +// RuntimeStub : Call to VM runtime methods 1.33 +// DeoptimizationBlob : Used for deoptimizatation 1.34 +// ExceptionBlob : Used for stack unrolling 1.35 +// SafepointBlob : Used to handle illegal instruction exceptions 1.36 +// 1.37 +// 1.38 +// Layout: 1.39 +// - header 1.40 +// - relocation 1.41 +// - instruction space 1.42 +// - data space 1.43 +class DeoptimizationBlob; 1.44 + 1.45 +class CodeBlob VALUE_OBJ_CLASS_SPEC { 1.46 + 1.47 + friend class VMStructs; 1.48 + 1.49 + private: 1.50 + const char* _name; 1.51 + int _size; // total size of CodeBlob in bytes 1.52 + int _header_size; // size of header (depends on subclass) 1.53 + int _relocation_size; // size of relocation 1.54 + int _instructions_offset; // offset to where instructions region begins 1.55 + int _frame_complete_offset; // instruction offsets in [0.._frame_complete_offset) have 1.56 + // not finished setting up their frame. Beware of pc's in 1.57 + // that range. There is a similar range(s) on returns 1.58 + // which we don't detect. 1.59 + int _data_offset; // offset to where data region begins 1.60 + int _oops_offset; // offset to where embedded oop table begins (inside data) 1.61 + int _oops_length; // number of embedded oops 1.62 + int _frame_size; // size of stack frame 1.63 + OopMapSet* _oop_maps; // OopMap for this CodeBlob 1.64 + CodeComments _comments; 1.65 + 1.66 + friend class OopRecorder; 1.67 + 1.68 + void fix_oop_relocations(address begin, address end, bool initialize_immediates); 1.69 + inline void initialize_immediate_oop(oop* dest, jobject handle); 1.70 + 1.71 + public: 1.72 + // Returns the space needed for CodeBlob 1.73 + static unsigned int allocation_size(CodeBuffer* cb, int header_size); 1.74 + 1.75 + // Creation 1.76 + // a) simple CodeBlob 1.77 + // frame_complete is the offset from the beginning of the instructions 1.78 + // to where the frame setup (from stackwalk viewpoint) is complete. 1.79 + CodeBlob(const char* name, int header_size, int size, int frame_complete, int locs_size); 1.80 + 1.81 + // b) full CodeBlob 1.82 + CodeBlob( 1.83 + const char* name, 1.84 + CodeBuffer* cb, 1.85 + int header_size, 1.86 + int size, 1.87 + int frame_complete, 1.88 + int frame_size, 1.89 + OopMapSet* oop_maps 1.90 + ); 1.91 + 1.92 + // Deletion 1.93 + void flush(); 1.94 + 1.95 + // Typing 1.96 + virtual bool is_buffer_blob() const { return false; } 1.97 + virtual bool is_nmethod() const { return false; } 1.98 + virtual bool is_runtime_stub() const { return false; } 1.99 + virtual bool is_deoptimization_stub() const { return false; } 1.100 + virtual bool is_uncommon_trap_stub() const { return false; } 1.101 + virtual bool is_exception_stub() const { return false; } 1.102 + virtual bool is_safepoint_stub() const { return false; } 1.103 + virtual bool is_adapter_blob() const { return false; } 1.104 + 1.105 + virtual bool is_compiled_by_c2() const { return false; } 1.106 + virtual bool is_compiled_by_c1() const { return false; } 1.107 + 1.108 + // Boundaries 1.109 + address header_begin() const { return (address) this; } 1.110 + address header_end() const { return ((address) this) + _header_size; }; 1.111 + relocInfo* relocation_begin() const { return (relocInfo*) header_end(); }; 1.112 + relocInfo* relocation_end() const { return (relocInfo*)(header_end() + _relocation_size); } 1.113 + address instructions_begin() const { return (address) header_begin() + _instructions_offset; } 1.114 + address instructions_end() const { return (address) header_begin() + _data_offset; } 1.115 + address data_begin() const { return (address) header_begin() + _data_offset; } 1.116 + address data_end() const { return (address) header_begin() + _size; } 1.117 + oop* oops_begin() const { return (oop*) (header_begin() + _oops_offset); } 1.118 + oop* oops_end() const { return oops_begin() + _oops_length; } 1.119 + 1.120 + // Offsets 1.121 + int relocation_offset() const { return _header_size; } 1.122 + int instructions_offset() const { return _instructions_offset; } 1.123 + int data_offset() const { return _data_offset; } 1.124 + int oops_offset() const { return _oops_offset; } 1.125 + 1.126 + // Sizes 1.127 + int size() const { return _size; } 1.128 + int header_size() const { return _header_size; } 1.129 + int relocation_size() const { return (address) relocation_end() - (address) relocation_begin(); } 1.130 + int instructions_size() const { return instructions_end() - instructions_begin(); } 1.131 + int data_size() const { return data_end() - data_begin(); } 1.132 + int oops_size() const { return (address) oops_end() - (address) oops_begin(); } 1.133 + 1.134 + // Containment 1.135 + bool blob_contains(address addr) const { return header_begin() <= addr && addr < data_end(); } 1.136 + bool relocation_contains(relocInfo* addr) const{ return relocation_begin() <= addr && addr < relocation_end(); } 1.137 + bool instructions_contains(address addr) const { return instructions_begin() <= addr && addr < instructions_end(); } 1.138 + bool data_contains(address addr) const { return data_begin() <= addr && addr < data_end(); } 1.139 + bool oops_contains(oop* addr) const { return oops_begin() <= addr && addr < oops_end(); } 1.140 + bool contains(address addr) const { return instructions_contains(addr); } 1.141 + bool is_frame_complete_at(address addr) const { return instructions_contains(addr) && 1.142 + addr >= instructions_begin() + _frame_complete_offset; } 1.143 + 1.144 + // Relocation support 1.145 + void fix_oop_relocations(address begin, address end) { 1.146 + fix_oop_relocations(begin, end, false); 1.147 + } 1.148 + void fix_oop_relocations() { 1.149 + fix_oop_relocations(NULL, NULL, false); 1.150 + } 1.151 + relocInfo::relocType reloc_type_for_address(address pc); 1.152 + bool is_at_poll_return(address pc); 1.153 + bool is_at_poll_or_poll_return(address pc); 1.154 + 1.155 + // Support for oops in scopes and relocs: 1.156 + // Note: index 0 is reserved for null. 1.157 + oop oop_at(int index) const { return index == 0? (oop)NULL: *oop_addr_at(index); } 1.158 + oop* oop_addr_at(int index) const{ // for GC 1.159 + // relocation indexes are biased by 1 (because 0 is reserved) 1.160 + assert(index > 0 && index <= _oops_length, "must be a valid non-zero index"); 1.161 + return &oops_begin()[index-1]; 1.162 + } 1.163 + 1.164 + void copy_oops(GrowableArray<jobject>* oops); 1.165 + 1.166 + // CodeCache support: really only used by the nmethods, but in order to get 1.167 + // asserts and certain bookkeeping to work in the CodeCache they are defined 1.168 + // virtual here. 1.169 + virtual bool is_zombie() const { return false; } 1.170 + virtual bool is_locked_by_vm() const { return false; } 1.171 + 1.172 + virtual bool is_unloaded() const { return false; } 1.173 + virtual bool is_not_entrant() const { return false; } 1.174 + 1.175 + // GC support 1.176 + virtual bool is_alive() const = 0; 1.177 + virtual void do_unloading(BoolObjectClosure* is_alive, 1.178 + OopClosure* keep_alive, 1.179 + bool unloading_occurred); 1.180 + virtual void oops_do(OopClosure* f) = 0; 1.181 + 1.182 + // OopMap for frame 1.183 + OopMapSet* oop_maps() const { return _oop_maps; } 1.184 + void set_oop_maps(OopMapSet* p); 1.185 + OopMap* oop_map_for_return_address(address return_address); 1.186 + virtual void preserve_callee_argument_oops(frame fr, const RegisterMap* reg_map, OopClosure* f) { ShouldNotReachHere(); } 1.187 + 1.188 + // Frame support 1.189 + int frame_size() const { return _frame_size; } 1.190 + void set_frame_size(int size) { _frame_size = size; } 1.191 + 1.192 + // Returns true, if the next frame is responsible for GC'ing oops passed as arguments 1.193 + virtual bool caller_must_gc_arguments(JavaThread* thread) const { return false; } 1.194 + 1.195 + // Naming 1.196 + const char* name() const { return _name; } 1.197 + void set_name(const char* name) { _name = name; } 1.198 + 1.199 + // Debugging 1.200 + virtual void verify(); 1.201 + virtual void print() const PRODUCT_RETURN; 1.202 + virtual void print_value_on(outputStream* st) const PRODUCT_RETURN; 1.203 + 1.204 + // Print the comment associated with offset on stream, if there is one 1.205 + void print_block_comment(outputStream* stream, intptr_t offset) { 1.206 + _comments.print_block_comment(stream, offset); 1.207 + } 1.208 + 1.209 + // Transfer ownership of comments to this CodeBlob 1.210 + void set_comments(CodeComments& comments) { 1.211 + _comments.assign(comments); 1.212 + } 1.213 +}; 1.214 + 1.215 + 1.216 +//---------------------------------------------------------------------------------------------------- 1.217 +// BufferBlob: used to hold non-relocatable machine code such as the interpreter, stubroutines, etc. 1.218 + 1.219 +class BufferBlob: public CodeBlob { 1.220 + friend class VMStructs; 1.221 + private: 1.222 + // Creation support 1.223 + BufferBlob(const char* name, int size); 1.224 + BufferBlob(const char* name, int size, CodeBuffer* cb); 1.225 + 1.226 + void* operator new(size_t s, unsigned size); 1.227 + 1.228 + public: 1.229 + // Creation 1.230 + static BufferBlob* create(const char* name, int buffer_size); 1.231 + static BufferBlob* create(const char* name, CodeBuffer* cb); 1.232 + 1.233 + static void free(BufferBlob* buf); 1.234 + 1.235 + // Typing 1.236 + bool is_buffer_blob() const { return true; } 1.237 + bool is_adapter_blob() const; 1.238 + 1.239 + // GC/Verification support 1.240 + void preserve_callee_argument_oops(frame fr, const RegisterMap* reg_map, OopClosure* f) { /* nothing to do */ } 1.241 + bool is_alive() const { return true; } 1.242 + void do_unloading(BoolObjectClosure* is_alive, 1.243 + OopClosure* keep_alive, 1.244 + bool unloading_occurred) { /* do nothing */ } 1.245 + 1.246 + void oops_do(OopClosure* f) { /* do nothing*/ } 1.247 + 1.248 + void verify(); 1.249 + void print() const PRODUCT_RETURN; 1.250 + void print_value_on(outputStream* st) const PRODUCT_RETURN; 1.251 +}; 1.252 + 1.253 + 1.254 +//---------------------------------------------------------------------------------------------------- 1.255 +// RuntimeStub: describes stubs used by compiled code to call a (static) C++ runtime routine 1.256 + 1.257 +class RuntimeStub: public CodeBlob { 1.258 + friend class VMStructs; 1.259 + private: 1.260 + bool _caller_must_gc_arguments; 1.261 + 1.262 + // Creation support 1.263 + RuntimeStub( 1.264 + const char* name, 1.265 + CodeBuffer* cb, 1.266 + int size, 1.267 + int frame_complete, 1.268 + int frame_size, 1.269 + OopMapSet* oop_maps, 1.270 + bool caller_must_gc_arguments 1.271 + ); 1.272 + 1.273 + void* operator new(size_t s, unsigned size); 1.274 + 1.275 + public: 1.276 + // Creation 1.277 + static RuntimeStub* new_runtime_stub( 1.278 + const char* stub_name, 1.279 + CodeBuffer* cb, 1.280 + int frame_complete, 1.281 + int frame_size, 1.282 + OopMapSet* oop_maps, 1.283 + bool caller_must_gc_arguments 1.284 + ); 1.285 + 1.286 + // Typing 1.287 + bool is_runtime_stub() const { return true; } 1.288 + 1.289 + // GC support 1.290 + bool caller_must_gc_arguments(JavaThread* thread) const { return _caller_must_gc_arguments; } 1.291 + 1.292 + address entry_point() { return instructions_begin(); } 1.293 + 1.294 + // GC/Verification support 1.295 + void preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map, OopClosure* f) { /* nothing to do */ } 1.296 + bool is_alive() const { return true; } 1.297 + void do_unloading(BoolObjectClosure* is_alive, 1.298 + OopClosure* keep_alive, 1.299 + bool unloading_occurred) { /* do nothing */ } 1.300 + void oops_do(OopClosure* f) { /* do-nothing*/ } 1.301 + 1.302 + void verify(); 1.303 + void print() const PRODUCT_RETURN; 1.304 + void print_value_on(outputStream* st) const PRODUCT_RETURN; 1.305 +}; 1.306 + 1.307 + 1.308 +//---------------------------------------------------------------------------------------------------- 1.309 +// Super-class for all blobs that exist in only one instance. Implements default behaviour. 1.310 + 1.311 +class SingletonBlob: public CodeBlob { 1.312 + friend class VMStructs; 1.313 + public: 1.314 + SingletonBlob( 1.315 + const char* name, 1.316 + CodeBuffer* cb, 1.317 + int header_size, 1.318 + int size, 1.319 + int frame_size, 1.320 + OopMapSet* oop_maps 1.321 + ) 1.322 + : CodeBlob(name, cb, header_size, size, CodeOffsets::frame_never_safe, frame_size, oop_maps) 1.323 + {}; 1.324 + 1.325 + bool is_alive() const { return true; } 1.326 + void do_unloading(BoolObjectClosure* is_alive, 1.327 + OopClosure* keep_alive, 1.328 + bool unloading_occurred) { /* do-nothing*/ } 1.329 + 1.330 + void verify(); // does nothing 1.331 + void print() const PRODUCT_RETURN; 1.332 + void print_value_on(outputStream* st) const PRODUCT_RETURN; 1.333 +}; 1.334 + 1.335 + 1.336 +//---------------------------------------------------------------------------------------------------- 1.337 +// DeoptimizationBlob 1.338 + 1.339 +class DeoptimizationBlob: public SingletonBlob { 1.340 + friend class VMStructs; 1.341 + private: 1.342 + int _unpack_offset; 1.343 + int _unpack_with_exception; 1.344 + int _unpack_with_reexecution; 1.345 + 1.346 + int _unpack_with_exception_in_tls; 1.347 + 1.348 + // Creation support 1.349 + DeoptimizationBlob( 1.350 + CodeBuffer* cb, 1.351 + int size, 1.352 + OopMapSet* oop_maps, 1.353 + int unpack_offset, 1.354 + int unpack_with_exception_offset, 1.355 + int unpack_with_reexecution_offset, 1.356 + int frame_size 1.357 + ); 1.358 + 1.359 + void* operator new(size_t s, unsigned size); 1.360 + 1.361 + public: 1.362 + // Creation 1.363 + static DeoptimizationBlob* create( 1.364 + CodeBuffer* cb, 1.365 + OopMapSet* oop_maps, 1.366 + int unpack_offset, 1.367 + int unpack_with_exception_offset, 1.368 + int unpack_with_reexecution_offset, 1.369 + int frame_size 1.370 + ); 1.371 + 1.372 + // Typing 1.373 + bool is_deoptimization_stub() const { return true; } 1.374 + const DeoptimizationBlob *as_deoptimization_stub() const { return this; } 1.375 + bool exception_address_is_unpack_entry(address pc) const { 1.376 + address unpack_pc = unpack(); 1.377 + return (pc == unpack_pc || (pc + frame::pc_return_offset) == unpack_pc); 1.378 + } 1.379 + 1.380 + 1.381 + 1.382 + 1.383 + // GC for args 1.384 + void preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map, OopClosure* f) { /* Nothing to do */ } 1.385 + 1.386 + // Iteration 1.387 + void oops_do(OopClosure* f) {} 1.388 + 1.389 + // Printing 1.390 + void print_value_on(outputStream* st) const PRODUCT_RETURN; 1.391 + 1.392 + address unpack() const { return instructions_begin() + _unpack_offset; } 1.393 + address unpack_with_exception() const { return instructions_begin() + _unpack_with_exception; } 1.394 + address unpack_with_reexecution() const { return instructions_begin() + _unpack_with_reexecution; } 1.395 + 1.396 + // Alternate entry point for C1 where the exception and issuing pc 1.397 + // are in JavaThread::_exception_oop and JavaThread::_exception_pc 1.398 + // instead of being in registers. This is needed because C1 doesn't 1.399 + // model exception paths in a way that keeps these registers free so 1.400 + // there may be live values in those registers during deopt. 1.401 + void set_unpack_with_exception_in_tls_offset(int offset) { 1.402 + _unpack_with_exception_in_tls = offset; 1.403 + assert(contains(instructions_begin() + _unpack_with_exception_in_tls), "must be PC inside codeblob"); 1.404 + } 1.405 + address unpack_with_exception_in_tls() const { return instructions_begin() + _unpack_with_exception_in_tls; } 1.406 +}; 1.407 + 1.408 + 1.409 +//---------------------------------------------------------------------------------------------------- 1.410 +// UncommonTrapBlob (currently only used by Compiler 2) 1.411 + 1.412 +#ifdef COMPILER2 1.413 + 1.414 +class UncommonTrapBlob: public SingletonBlob { 1.415 + friend class VMStructs; 1.416 + private: 1.417 + // Creation support 1.418 + UncommonTrapBlob( 1.419 + CodeBuffer* cb, 1.420 + int size, 1.421 + OopMapSet* oop_maps, 1.422 + int frame_size 1.423 + ); 1.424 + 1.425 + void* operator new(size_t s, unsigned size); 1.426 + 1.427 + public: 1.428 + // Creation 1.429 + static UncommonTrapBlob* create( 1.430 + CodeBuffer* cb, 1.431 + OopMapSet* oop_maps, 1.432 + int frame_size 1.433 + ); 1.434 + 1.435 + // GC for args 1.436 + void preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map, OopClosure* f) { /* nothing to do */ } 1.437 + 1.438 + // Typing 1.439 + bool is_uncommon_trap_stub() const { return true; } 1.440 + 1.441 + // Iteration 1.442 + void oops_do(OopClosure* f) {} 1.443 +}; 1.444 + 1.445 + 1.446 +//---------------------------------------------------------------------------------------------------- 1.447 +// ExceptionBlob: used for exception unwinding in compiled code (currently only used by Compiler 2) 1.448 + 1.449 +class ExceptionBlob: public SingletonBlob { 1.450 + friend class VMStructs; 1.451 + private: 1.452 + // Creation support 1.453 + ExceptionBlob( 1.454 + CodeBuffer* cb, 1.455 + int size, 1.456 + OopMapSet* oop_maps, 1.457 + int frame_size 1.458 + ); 1.459 + 1.460 + void* operator new(size_t s, unsigned size); 1.461 + 1.462 + public: 1.463 + // Creation 1.464 + static ExceptionBlob* create( 1.465 + CodeBuffer* cb, 1.466 + OopMapSet* oop_maps, 1.467 + int frame_size 1.468 + ); 1.469 + 1.470 + // GC for args 1.471 + void preserve_callee_argument_oops(frame fr, const RegisterMap* reg_map, OopClosure* f) { /* nothing to do */ } 1.472 + 1.473 + // Typing 1.474 + bool is_exception_stub() const { return true; } 1.475 + 1.476 + // Iteration 1.477 + void oops_do(OopClosure* f) {} 1.478 +}; 1.479 +#endif // COMPILER2 1.480 + 1.481 + 1.482 +//---------------------------------------------------------------------------------------------------- 1.483 +// SafepointBlob: handles illegal_instruction exceptions during a safepoint 1.484 + 1.485 +class SafepointBlob: public SingletonBlob { 1.486 + friend class VMStructs; 1.487 + private: 1.488 + // Creation support 1.489 + SafepointBlob( 1.490 + CodeBuffer* cb, 1.491 + int size, 1.492 + OopMapSet* oop_maps, 1.493 + int frame_size 1.494 + ); 1.495 + 1.496 + void* operator new(size_t s, unsigned size); 1.497 + 1.498 + public: 1.499 + // Creation 1.500 + static SafepointBlob* create( 1.501 + CodeBuffer* cb, 1.502 + OopMapSet* oop_maps, 1.503 + int frame_size 1.504 + ); 1.505 + 1.506 + // GC for args 1.507 + void preserve_callee_argument_oops(frame fr, const RegisterMap* reg_map, OopClosure* f) { /* nothing to do */ } 1.508 + 1.509 + // Typing 1.510 + bool is_safepoint_stub() const { return true; } 1.511 + 1.512 + // Iteration 1.513 + void oops_do(OopClosure* f) {} 1.514 +};