1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/code/codeBlob.hpp Wed Apr 27 01:25:04 2016 +0800 1.3 @@ -0,0 +1,506 @@ 1.4 +/* 1.5 + * Copyright (c) 1998, 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 + * or visit www.oracle.com if you need additional information or have any 1.24 + * questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +#ifndef SHARE_VM_CODE_CODEBLOB_HPP 1.29 +#define SHARE_VM_CODE_CODEBLOB_HPP 1.30 + 1.31 +#include "asm/codeBuffer.hpp" 1.32 +#include "compiler/oopMap.hpp" 1.33 +#include "runtime/frame.hpp" 1.34 +#include "runtime/handles.hpp" 1.35 + 1.36 +// CodeBlob - superclass for all entries in the CodeCache. 1.37 +// 1.38 +// Suptypes are: 1.39 +// nmethod : Compiled Java methods (include method that calls to native code) 1.40 +// RuntimeStub : Call to VM runtime methods 1.41 +// DeoptimizationBlob : Used for deoptimizatation 1.42 +// ExceptionBlob : Used for stack unrolling 1.43 +// SafepointBlob : Used to handle illegal instruction exceptions 1.44 +// 1.45 +// 1.46 +// Layout: 1.47 +// - header 1.48 +// - relocation 1.49 +// - content space 1.50 +// - instruction space 1.51 +// - data space 1.52 +class DeoptimizationBlob; 1.53 + 1.54 +class CodeBlob VALUE_OBJ_CLASS_SPEC { 1.55 + 1.56 + friend class VMStructs; 1.57 + 1.58 + private: 1.59 + const char* _name; 1.60 + int _size; // total size of CodeBlob in bytes 1.61 + int _header_size; // size of header (depends on subclass) 1.62 + int _relocation_size; // size of relocation 1.63 + int _content_offset; // offset to where content region begins (this includes consts, insts, stubs) 1.64 + int _code_offset; // offset to where instructions region begins (this includes insts, stubs) 1.65 + int _frame_complete_offset; // instruction offsets in [0.._frame_complete_offset) have 1.66 + // not finished setting up their frame. Beware of pc's in 1.67 + // that range. There is a similar range(s) on returns 1.68 + // which we don't detect. 1.69 + int _data_offset; // offset to where data region begins 1.70 + int _frame_size; // size of stack frame 1.71 + OopMapSet* _oop_maps; // OopMap for this CodeBlob 1.72 + CodeStrings _strings; 1.73 + 1.74 + public: 1.75 + // Returns the space needed for CodeBlob 1.76 + static unsigned int allocation_size(CodeBuffer* cb, int header_size); 1.77 + 1.78 + // Creation 1.79 + // a) simple CodeBlob 1.80 + // frame_complete is the offset from the beginning of the instructions 1.81 + // to where the frame setup (from stackwalk viewpoint) is complete. 1.82 + CodeBlob(const char* name, int header_size, int size, int frame_complete, int locs_size); 1.83 + 1.84 + // b) full CodeBlob 1.85 + CodeBlob( 1.86 + const char* name, 1.87 + CodeBuffer* cb, 1.88 + int header_size, 1.89 + int size, 1.90 + int frame_complete, 1.91 + int frame_size, 1.92 + OopMapSet* oop_maps 1.93 + ); 1.94 + 1.95 + // Deletion 1.96 + void flush(); 1.97 + 1.98 + // Typing 1.99 + virtual bool is_buffer_blob() const { return false; } 1.100 + virtual bool is_nmethod() const { return false; } 1.101 + virtual bool is_runtime_stub() const { return false; } 1.102 + virtual bool is_deoptimization_stub() const { return false; } 1.103 + virtual bool is_uncommon_trap_stub() const { return false; } 1.104 + virtual bool is_exception_stub() const { return false; } 1.105 + virtual bool is_safepoint_stub() const { return false; } 1.106 + virtual bool is_adapter_blob() const { return false; } 1.107 + virtual bool is_method_handles_adapter_blob() const { return false; } 1.108 + 1.109 + virtual bool is_compiled_by_c2() const { return false; } 1.110 + virtual bool is_compiled_by_c1() const { return false; } 1.111 + 1.112 + // Casting 1.113 + nmethod* as_nmethod_or_null() { return is_nmethod() ? (nmethod*) this : NULL; } 1.114 + 1.115 + // Boundaries 1.116 + address header_begin() const { return (address) this; } 1.117 + address header_end() const { return ((address) this) + _header_size; }; 1.118 + relocInfo* relocation_begin() const { return (relocInfo*) header_end(); }; 1.119 + relocInfo* relocation_end() const { return (relocInfo*)(header_end() + _relocation_size); } 1.120 + address content_begin() const { return (address) header_begin() + _content_offset; } 1.121 + address content_end() const { return (address) header_begin() + _data_offset; } 1.122 + address code_begin() const { return (address) header_begin() + _code_offset; } 1.123 + address code_end() const { return (address) header_begin() + _data_offset; } 1.124 + address data_begin() const { return (address) header_begin() + _data_offset; } 1.125 + address data_end() const { return (address) header_begin() + _size; } 1.126 + 1.127 + // Offsets 1.128 + int relocation_offset() const { return _header_size; } 1.129 + int content_offset() const { return _content_offset; } 1.130 + int code_offset() const { return _code_offset; } 1.131 + int data_offset() const { return _data_offset; } 1.132 + 1.133 + // Sizes 1.134 + int size() const { return _size; } 1.135 + int header_size() const { return _header_size; } 1.136 + int relocation_size() const { return (address) relocation_end() - (address) relocation_begin(); } 1.137 + int content_size() const { return content_end() - content_begin(); } 1.138 + int code_size() const { return code_end() - code_begin(); } 1.139 + int data_size() const { return data_end() - data_begin(); } 1.140 + 1.141 + // Containment 1.142 + bool blob_contains(address addr) const { return header_begin() <= addr && addr < data_end(); } 1.143 + bool relocation_contains(relocInfo* addr) const{ return relocation_begin() <= addr && addr < relocation_end(); } 1.144 + bool content_contains(address addr) const { return content_begin() <= addr && addr < content_end(); } 1.145 + bool code_contains(address addr) const { return code_begin() <= addr && addr < code_end(); } 1.146 + bool data_contains(address addr) const { return data_begin() <= addr && addr < data_end(); } 1.147 + bool contains(address addr) const { return content_contains(addr); } 1.148 + bool is_frame_complete_at(address addr) const { return code_contains(addr) && 1.149 + addr >= code_begin() + _frame_complete_offset; } 1.150 + 1.151 + // CodeCache support: really only used by the nmethods, but in order to get 1.152 + // asserts and certain bookkeeping to work in the CodeCache they are defined 1.153 + // virtual here. 1.154 + virtual bool is_zombie() const { return false; } 1.155 + virtual bool is_locked_by_vm() const { return false; } 1.156 + 1.157 + virtual bool is_unloaded() const { return false; } 1.158 + virtual bool is_not_entrant() const { return false; } 1.159 + 1.160 + // GC support 1.161 + virtual bool is_alive() const = 0; 1.162 + 1.163 + // OopMap for frame 1.164 + OopMapSet* oop_maps() const { return _oop_maps; } 1.165 + void set_oop_maps(OopMapSet* p); 1.166 + OopMap* oop_map_for_return_address(address return_address); 1.167 + virtual void preserve_callee_argument_oops(frame fr, const RegisterMap* reg_map, OopClosure* f) { ShouldNotReachHere(); } 1.168 + 1.169 + // Frame support 1.170 + int frame_size() const { return _frame_size; } 1.171 + void set_frame_size(int size) { _frame_size = size; } 1.172 + 1.173 + // Returns true, if the next frame is responsible for GC'ing oops passed as arguments 1.174 + virtual bool caller_must_gc_arguments(JavaThread* thread) const { return false; } 1.175 + 1.176 + // Naming 1.177 + const char* name() const { return _name; } 1.178 + void set_name(const char* name) { _name = name; } 1.179 + 1.180 + // Debugging 1.181 + virtual void verify(); 1.182 + void print() const { print_on(tty); } 1.183 + virtual void print_on(outputStream* st) const; 1.184 + virtual void print_value_on(outputStream* st) const; 1.185 + 1.186 + // Deal with Disassembler, VTune, Forte, JvmtiExport, MemoryService. 1.187 + static void trace_new_stub(CodeBlob* blob, const char* name1, const char* name2 = ""); 1.188 + 1.189 + // Print the comment associated with offset on stream, if there is one 1.190 + virtual void print_block_comment(outputStream* stream, address block_begin) const { 1.191 + intptr_t offset = (intptr_t)(block_begin - code_begin()); 1.192 + _strings.print_block_comment(stream, offset); 1.193 + } 1.194 + 1.195 + // Transfer ownership of comments to this CodeBlob 1.196 + void set_strings(CodeStrings& strings) { 1.197 + _strings.assign(strings); 1.198 + } 1.199 +}; 1.200 + 1.201 + 1.202 +//---------------------------------------------------------------------------------------------------- 1.203 +// BufferBlob: used to hold non-relocatable machine code such as the interpreter, stubroutines, etc. 1.204 + 1.205 +class BufferBlob: public CodeBlob { 1.206 + friend class VMStructs; 1.207 + friend class AdapterBlob; 1.208 + friend class MethodHandlesAdapterBlob; 1.209 + 1.210 + private: 1.211 + // Creation support 1.212 + BufferBlob(const char* name, int size); 1.213 + BufferBlob(const char* name, int size, CodeBuffer* cb); 1.214 + 1.215 + void* operator new(size_t s, unsigned size, bool is_critical = false) throw(); 1.216 + 1.217 + public: 1.218 + // Creation 1.219 + static BufferBlob* create(const char* name, int buffer_size); 1.220 + static BufferBlob* create(const char* name, CodeBuffer* cb); 1.221 + 1.222 + static void free(BufferBlob* buf); 1.223 + 1.224 + // Typing 1.225 + virtual bool is_buffer_blob() const { return true; } 1.226 + 1.227 + // GC/Verification support 1.228 + void preserve_callee_argument_oops(frame fr, const RegisterMap* reg_map, OopClosure* f) { /* nothing to do */ } 1.229 + bool is_alive() const { return true; } 1.230 + 1.231 + void verify(); 1.232 + void print_on(outputStream* st) const; 1.233 + void print_value_on(outputStream* st) const; 1.234 +}; 1.235 + 1.236 + 1.237 +//---------------------------------------------------------------------------------------------------- 1.238 +// AdapterBlob: used to hold C2I/I2C adapters 1.239 + 1.240 +class AdapterBlob: public BufferBlob { 1.241 +private: 1.242 + AdapterBlob(int size, CodeBuffer* cb); 1.243 + 1.244 +public: 1.245 + // Creation 1.246 + static AdapterBlob* create(CodeBuffer* cb); 1.247 + 1.248 + // Typing 1.249 + virtual bool is_adapter_blob() const { return true; } 1.250 +}; 1.251 + 1.252 + 1.253 +//---------------------------------------------------------------------------------------------------- 1.254 +// MethodHandlesAdapterBlob: used to hold MethodHandles adapters 1.255 + 1.256 +class MethodHandlesAdapterBlob: public BufferBlob { 1.257 +private: 1.258 + MethodHandlesAdapterBlob(int size) : BufferBlob("MethodHandles adapters", size) {} 1.259 + 1.260 +public: 1.261 + // Creation 1.262 + static MethodHandlesAdapterBlob* create(int buffer_size); 1.263 + 1.264 + // Typing 1.265 + virtual bool is_method_handles_adapter_blob() const { return true; } 1.266 +}; 1.267 + 1.268 + 1.269 +//---------------------------------------------------------------------------------------------------- 1.270 +// RuntimeStub: describes stubs used by compiled code to call a (static) C++ runtime routine 1.271 + 1.272 +class RuntimeStub: public CodeBlob { 1.273 + friend class VMStructs; 1.274 + private: 1.275 + bool _caller_must_gc_arguments; 1.276 + 1.277 + // Creation support 1.278 + RuntimeStub( 1.279 + const char* name, 1.280 + CodeBuffer* cb, 1.281 + int size, 1.282 + int frame_complete, 1.283 + int frame_size, 1.284 + OopMapSet* oop_maps, 1.285 + bool caller_must_gc_arguments 1.286 + ); 1.287 + 1.288 + void* operator new(size_t s, unsigned size) throw(); 1.289 + 1.290 + public: 1.291 + // Creation 1.292 + static RuntimeStub* new_runtime_stub( 1.293 + const char* stub_name, 1.294 + CodeBuffer* cb, 1.295 + int frame_complete, 1.296 + int frame_size, 1.297 + OopMapSet* oop_maps, 1.298 + bool caller_must_gc_arguments 1.299 + ); 1.300 + 1.301 + // Typing 1.302 + bool is_runtime_stub() const { return true; } 1.303 + 1.304 + // GC support 1.305 + bool caller_must_gc_arguments(JavaThread* thread) const { return _caller_must_gc_arguments; } 1.306 + 1.307 + address entry_point() { return code_begin(); } 1.308 + 1.309 + // GC/Verification support 1.310 + void preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map, OopClosure* f) { /* nothing to do */ } 1.311 + bool is_alive() const { return true; } 1.312 + 1.313 + void verify(); 1.314 + void print_on(outputStream* st) const; 1.315 + void print_value_on(outputStream* st) const; 1.316 +}; 1.317 + 1.318 + 1.319 +//---------------------------------------------------------------------------------------------------- 1.320 +// Super-class for all blobs that exist in only one instance. Implements default behaviour. 1.321 + 1.322 +class SingletonBlob: public CodeBlob { 1.323 + friend class VMStructs; 1.324 + 1.325 + protected: 1.326 + void* operator new(size_t s, unsigned size) throw(); 1.327 + 1.328 + public: 1.329 + SingletonBlob( 1.330 + const char* name, 1.331 + CodeBuffer* cb, 1.332 + int header_size, 1.333 + int size, 1.334 + int frame_size, 1.335 + OopMapSet* oop_maps 1.336 + ) 1.337 + : CodeBlob(name, cb, header_size, size, CodeOffsets::frame_never_safe, frame_size, oop_maps) 1.338 + {}; 1.339 + 1.340 + address entry_point() { return code_begin(); } 1.341 + 1.342 + bool is_alive() const { return true; } 1.343 + 1.344 + void verify(); // does nothing 1.345 + void print_on(outputStream* st) const; 1.346 + void print_value_on(outputStream* st) const; 1.347 +}; 1.348 + 1.349 + 1.350 +//---------------------------------------------------------------------------------------------------- 1.351 +// DeoptimizationBlob 1.352 + 1.353 +class DeoptimizationBlob: public SingletonBlob { 1.354 + friend class VMStructs; 1.355 + private: 1.356 + int _unpack_offset; 1.357 + int _unpack_with_exception; 1.358 + int _unpack_with_reexecution; 1.359 + 1.360 + int _unpack_with_exception_in_tls; 1.361 + 1.362 + // Creation support 1.363 + DeoptimizationBlob( 1.364 + CodeBuffer* cb, 1.365 + int size, 1.366 + OopMapSet* oop_maps, 1.367 + int unpack_offset, 1.368 + int unpack_with_exception_offset, 1.369 + int unpack_with_reexecution_offset, 1.370 + int frame_size 1.371 + ); 1.372 + 1.373 + public: 1.374 + // Creation 1.375 + static DeoptimizationBlob* create( 1.376 + CodeBuffer* cb, 1.377 + OopMapSet* oop_maps, 1.378 + int unpack_offset, 1.379 + int unpack_with_exception_offset, 1.380 + int unpack_with_reexecution_offset, 1.381 + int frame_size 1.382 + ); 1.383 + 1.384 + // Typing 1.385 + bool is_deoptimization_stub() const { return true; } 1.386 + bool exception_address_is_unpack_entry(address pc) const { 1.387 + address unpack_pc = unpack(); 1.388 + return (pc == unpack_pc || (pc + frame::pc_return_offset) == unpack_pc); 1.389 + } 1.390 + 1.391 + 1.392 + 1.393 + 1.394 + // GC for args 1.395 + void preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map, OopClosure* f) { /* Nothing to do */ } 1.396 + 1.397 + // Printing 1.398 + void print_value_on(outputStream* st) const; 1.399 + 1.400 + address unpack() const { return code_begin() + _unpack_offset; } 1.401 + address unpack_with_exception() const { return code_begin() + _unpack_with_exception; } 1.402 + address unpack_with_reexecution() const { return code_begin() + _unpack_with_reexecution; } 1.403 + 1.404 + // Alternate entry point for C1 where the exception and issuing pc 1.405 + // are in JavaThread::_exception_oop and JavaThread::_exception_pc 1.406 + // instead of being in registers. This is needed because C1 doesn't 1.407 + // model exception paths in a way that keeps these registers free so 1.408 + // there may be live values in those registers during deopt. 1.409 + void set_unpack_with_exception_in_tls_offset(int offset) { 1.410 + _unpack_with_exception_in_tls = offset; 1.411 + assert(code_contains(code_begin() + _unpack_with_exception_in_tls), "must be PC inside codeblob"); 1.412 + } 1.413 + address unpack_with_exception_in_tls() const { return code_begin() + _unpack_with_exception_in_tls; } 1.414 +}; 1.415 + 1.416 + 1.417 +//---------------------------------------------------------------------------------------------------- 1.418 +// UncommonTrapBlob (currently only used by Compiler 2) 1.419 + 1.420 +#ifdef COMPILER2 1.421 + 1.422 +class UncommonTrapBlob: public SingletonBlob { 1.423 + friend class VMStructs; 1.424 + private: 1.425 + // Creation support 1.426 + UncommonTrapBlob( 1.427 + CodeBuffer* cb, 1.428 + int size, 1.429 + OopMapSet* oop_maps, 1.430 + int frame_size 1.431 + ); 1.432 + 1.433 + public: 1.434 + // Creation 1.435 + static UncommonTrapBlob* create( 1.436 + CodeBuffer* cb, 1.437 + OopMapSet* oop_maps, 1.438 + int frame_size 1.439 + ); 1.440 + 1.441 + // GC for args 1.442 + void preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map, OopClosure* f) { /* nothing to do */ } 1.443 + 1.444 + // Typing 1.445 + bool is_uncommon_trap_stub() const { return true; } 1.446 +}; 1.447 + 1.448 + 1.449 +//---------------------------------------------------------------------------------------------------- 1.450 +// ExceptionBlob: used for exception unwinding in compiled code (currently only used by Compiler 2) 1.451 + 1.452 +class ExceptionBlob: public SingletonBlob { 1.453 + friend class VMStructs; 1.454 + private: 1.455 + // Creation support 1.456 + ExceptionBlob( 1.457 + CodeBuffer* cb, 1.458 + int size, 1.459 + OopMapSet* oop_maps, 1.460 + int frame_size 1.461 + ); 1.462 + 1.463 + public: 1.464 + // Creation 1.465 + static ExceptionBlob* create( 1.466 + CodeBuffer* cb, 1.467 + OopMapSet* oop_maps, 1.468 + int frame_size 1.469 + ); 1.470 + 1.471 + // GC for args 1.472 + void preserve_callee_argument_oops(frame fr, const RegisterMap* reg_map, OopClosure* f) { /* nothing to do */ } 1.473 + 1.474 + // Typing 1.475 + bool is_exception_stub() const { return true; } 1.476 +}; 1.477 +#endif // COMPILER2 1.478 + 1.479 + 1.480 +//---------------------------------------------------------------------------------------------------- 1.481 +// SafepointBlob: handles illegal_instruction exceptions during a safepoint 1.482 + 1.483 +class SafepointBlob: public SingletonBlob { 1.484 + friend class VMStructs; 1.485 + private: 1.486 + // Creation support 1.487 + SafepointBlob( 1.488 + CodeBuffer* cb, 1.489 + int size, 1.490 + OopMapSet* oop_maps, 1.491 + int frame_size 1.492 + ); 1.493 + 1.494 + public: 1.495 + // Creation 1.496 + static SafepointBlob* create( 1.497 + CodeBuffer* cb, 1.498 + OopMapSet* oop_maps, 1.499 + int frame_size 1.500 + ); 1.501 + 1.502 + // GC for args 1.503 + void preserve_callee_argument_oops(frame fr, const RegisterMap* reg_map, OopClosure* f) { /* nothing to do */ } 1.504 + 1.505 + // Typing 1.506 + bool is_safepoint_stub() const { return true; } 1.507 +}; 1.508 + 1.509 +#endif // SHARE_VM_CODE_CODEBLOB_HPP