1.1 --- a/src/share/vm/code/compiledIC.hpp Fri Aug 31 16:39:35 2012 -0700 1.2 +++ b/src/share/vm/code/compiledIC.hpp Sat Sep 01 13:25:18 2012 -0400 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 1997, 2012, 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 @@ -26,9 +26,7 @@ 1.11 #define SHARE_VM_CODE_COMPILEDIC_HPP 1.12 1.13 #include "interpreter/linkResolver.hpp" 1.14 -#include "oops/compiledICHolderKlass.hpp" 1.15 -#include "oops/compiledICHolderOop.hpp" 1.16 -#include "oops/klassOop.hpp" 1.17 +#include "oops/compiledICHolder.hpp" 1.18 #ifdef TARGET_ARCH_x86 1.19 # include "nativeInst_x86.hpp" 1.20 #endif 1.21 @@ -57,36 +55,88 @@ 1.22 // / \ /-<-\ 1.23 // / [2] \ / \ 1.24 // Interpreted ---------> Monomorphic | [3] 1.25 -// (compiledICHolderOop) (klassOop) | 1.26 +// (CompiledICHolder*) (Klass*) | 1.27 // \ / \ / 1.28 // [4] \ / [4] \->-/ 1.29 // \->- Megamorphic -<-/ 1.30 -// (methodOop) 1.31 +// (Method*) 1.32 // 1.33 // The text in paranteses () refere to the value of the inline cache receiver (mov instruction) 1.34 // 1.35 // The numbers in square brackets refere to the kind of transition: 1.36 // [1]: Initial fixup. Receiver it found from debug information 1.37 // [2]: Compilation of a method 1.38 -// [3]: Recompilation of a method (note: only entry is changed. The klassOop must stay the same) 1.39 +// [3]: Recompilation of a method (note: only entry is changed. The Klass* must stay the same) 1.40 // [4]: Inline cache miss. We go directly to megamorphic call. 1.41 // 1.42 // The class automatically inserts transition stubs (using the InlineCacheBuffer) when an MT-unsafe 1.43 // transition is made to a stub. 1.44 // 1.45 class CompiledIC; 1.46 +class ICStub; 1.47 1.48 -class CompiledICInfo { 1.49 - friend class CompiledIC; 1.50 +class CompiledICInfo : public StackObj { 1.51 private: 1.52 address _entry; // entry point for call 1.53 - Handle _cached_oop; // Value of cached_oop (either in stub or inline cache) 1.54 + void* _cached_value; // Value of cached_value (either in stub or inline cache) 1.55 + bool _is_icholder; // Is the cached value a CompiledICHolder* 1.56 bool _is_optimized; // it is an optimized virtual call (i.e., can be statically bound) 1.57 bool _to_interpreter; // Call it to interpreter 1.58 + bool _release_icholder; 1.59 public: 1.60 address entry() const { return _entry; } 1.61 - Handle cached_oop() const { return _cached_oop; } 1.62 + Metadata* cached_metadata() const { assert(!_is_icholder, ""); return (Metadata*)_cached_value; } 1.63 + CompiledICHolder* claim_cached_icholder() { 1.64 + assert(_is_icholder, ""); 1.65 + assert(_cached_value != NULL, "must be non-NULL"); 1.66 + _release_icholder = false; 1.67 + CompiledICHolder* icholder = (CompiledICHolder*)_cached_value; 1.68 + icholder->claim(); 1.69 + return icholder; 1.70 + } 1.71 bool is_optimized() const { return _is_optimized; } 1.72 + bool to_interpreter() const { return _to_interpreter; } 1.73 + 1.74 + void set_compiled_entry(address entry, Klass* klass, bool is_optimized) { 1.75 + _entry = entry; 1.76 + _cached_value = (void*)klass; 1.77 + _to_interpreter = false; 1.78 + _is_icholder = false; 1.79 + _is_optimized = is_optimized; 1.80 + _release_icholder = false; 1.81 + } 1.82 + 1.83 + void set_interpreter_entry(address entry, Method* method) { 1.84 + _entry = entry; 1.85 + _cached_value = (void*)method; 1.86 + _to_interpreter = true; 1.87 + _is_icholder = false; 1.88 + _is_optimized = true; 1.89 + _release_icholder = false; 1.90 + } 1.91 + 1.92 + void set_icholder_entry(address entry, CompiledICHolder* icholder) { 1.93 + _entry = entry; 1.94 + _cached_value = (void*)icholder; 1.95 + _to_interpreter = true; 1.96 + _is_icholder = true; 1.97 + _is_optimized = false; 1.98 + _release_icholder = true; 1.99 + } 1.100 + 1.101 + CompiledICInfo(): _entry(NULL), _cached_value(NULL), _is_icholder(false), 1.102 + _to_interpreter(false), _is_optimized(false), _release_icholder(false) { 1.103 + } 1.104 + ~CompiledICInfo() { 1.105 + // In rare cases the info is computed but not used, so release any 1.106 + // CompiledICHolder* that was created 1.107 + if (_release_icholder) { 1.108 + assert(_is_icholder, "must be"); 1.109 + CompiledICHolder* icholder = (CompiledICHolder*)_cached_value; 1.110 + icholder->claim(); 1.111 + delete icholder; 1.112 + } 1.113 + } 1.114 }; 1.115 1.116 class CompiledIC: public ResourceObj { 1.117 @@ -96,18 +146,32 @@ 1.118 1.119 private: 1.120 NativeCall* _ic_call; // the call instruction 1.121 - oop* _oop_addr; // patchable oop cell for this IC 1.122 - RelocIterator _oops; // iteration over any and all set-oop instructions 1.123 + NativeMovConstReg* _value; // patchable value cell for this IC 1.124 bool _is_optimized; // an optimized virtual call (i.e., no compiled IC) 1.125 1.126 - CompiledIC(NativeCall* ic_call); 1.127 - CompiledIC(Relocation* ic_reloc); // Must be of virtual_call_type/opt_virtual_call_type 1.128 + CompiledIC(nmethod* nm, NativeCall* ic_call); 1.129 + 1.130 + static bool is_icholder_entry(address entry); 1.131 1.132 // low-level inline-cache manipulation. Cannot be accessed directly, since it might not be MT-safe 1.133 // to change an inline-cache. These changes the underlying inline-cache directly. They *newer* make 1.134 // changes to a transition stub. 1.135 - void set_ic_destination(address entry_point); 1.136 - void set_cached_oop(oop cache); 1.137 + void internal_set_ic_destination(address entry_point, bool is_icstub, void* cache, bool is_icholder); 1.138 + void set_ic_destination(ICStub* stub); 1.139 + void set_ic_destination(address entry_point) { 1.140 + assert(_is_optimized, "use set_ic_destination_and_value instead"); 1.141 + internal_set_ic_destination(entry_point, false, NULL, false); 1.142 + } 1.143 + // This only for use by ICStubs where the type of the value isn't known 1.144 + void set_ic_destination_and_value(address entry_point, void* value) { 1.145 + internal_set_ic_destination(entry_point, false, value, is_icholder_entry(entry_point)); 1.146 + } 1.147 + void set_ic_destination_and_value(address entry_point, Metadata* value) { 1.148 + internal_set_ic_destination(entry_point, false, value, false); 1.149 + } 1.150 + void set_ic_destination_and_value(address entry_point, CompiledICHolder* value) { 1.151 + internal_set_ic_destination(entry_point, false, value, true); 1.152 + } 1.153 1.154 // Reads the location of the transition stub. This will fail with an assertion, if no transition stub is 1.155 // associated with the inline cache. 1.156 @@ -116,13 +180,28 @@ 1.157 1.158 public: 1.159 // conversion (machine PC to CompiledIC*) 1.160 - friend CompiledIC* CompiledIC_before(address return_addr); 1.161 - friend CompiledIC* CompiledIC_at(address call_site); 1.162 + friend CompiledIC* CompiledIC_before(nmethod* nm, address return_addr); 1.163 + friend CompiledIC* CompiledIC_at(nmethod* nm, address call_site); 1.164 friend CompiledIC* CompiledIC_at(Relocation* call_site); 1.165 1.166 - // Return the cached_oop/destination associated with this inline cache. If the cache currently points 1.167 + // This is used to release CompiledICHolder*s from nmethods that 1.168 + // are about to be freed. The callsite might contain other stale 1.169 + // values of other kinds so it must be careful. 1.170 + static void cleanup_call_site(virtual_call_Relocation* call_site); 1.171 + static bool is_icholder_call_site(virtual_call_Relocation* call_site); 1.172 + 1.173 + // Return the cached_metadata/destination associated with this inline cache. If the cache currently points 1.174 // to a transition stub, it will read the values from the transition stub. 1.175 - oop cached_oop() const; 1.176 + void* cached_value() const; 1.177 + CompiledICHolder* cached_icholder() const { 1.178 + assert(is_icholder_call(), "must be"); 1.179 + return (CompiledICHolder*) cached_value(); 1.180 + } 1.181 + Metadata* cached_metadata() const { 1.182 + assert(!is_icholder_call(), "must be"); 1.183 + return (Metadata*) cached_value(); 1.184 + } 1.185 + 1.186 address ic_destination() const; 1.187 1.188 bool is_optimized() const { return _is_optimized; } 1.189 @@ -133,6 +212,8 @@ 1.190 bool is_call_to_compiled() const; 1.191 bool is_call_to_interpreted() const; 1.192 1.193 + bool is_icholder_call() const; 1.194 + 1.195 address end_of_call() { return _ic_call->return_address(); } 1.196 1.197 // MT-safe patching of inline caches. Note: Only safe to call is_xxx when holding the CompiledIC_ock 1.198 @@ -144,7 +225,7 @@ 1.199 // They all takes a TRAP argument, since they can cause a GC if the inline-cache buffer is full. 1.200 // 1.201 void set_to_clean(); // Can only be called during a safepoint operation 1.202 - void set_to_monomorphic(const CompiledICInfo& info); 1.203 + void set_to_monomorphic(CompiledICInfo& info); 1.204 void set_to_megamorphic(CallInfo* call_info, Bytecodes::Code bytecode, TRAPS); 1.205 1.206 static void compute_monomorphic_entry(methodHandle method, KlassHandle receiver_klass, 1.207 @@ -159,20 +240,22 @@ 1.208 void verify() PRODUCT_RETURN; 1.209 }; 1.210 1.211 -inline CompiledIC* CompiledIC_before(address return_addr) { 1.212 - CompiledIC* c_ic = new CompiledIC(nativeCall_before(return_addr)); 1.213 +inline CompiledIC* CompiledIC_before(nmethod* nm, address return_addr) { 1.214 + CompiledIC* c_ic = new CompiledIC(nm, nativeCall_before(return_addr)); 1.215 c_ic->verify(); 1.216 return c_ic; 1.217 } 1.218 1.219 -inline CompiledIC* CompiledIC_at(address call_site) { 1.220 - CompiledIC* c_ic = new CompiledIC(nativeCall_at(call_site)); 1.221 +inline CompiledIC* CompiledIC_at(nmethod* nm, address call_site) { 1.222 + CompiledIC* c_ic = new CompiledIC(nm, nativeCall_at(call_site)); 1.223 c_ic->verify(); 1.224 return c_ic; 1.225 } 1.226 1.227 inline CompiledIC* CompiledIC_at(Relocation* call_site) { 1.228 - CompiledIC* c_ic = new CompiledIC(call_site); 1.229 + assert(call_site->type() == relocInfo::virtual_call_type || 1.230 + call_site->type() == relocInfo::opt_virtual_call_type, "wrong reloc. info"); 1.231 + CompiledIC* c_ic = new CompiledIC(call_site->code(), nativeCall_at(call_site->addr())); 1.232 c_ic->verify(); 1.233 return c_ic; 1.234 } 1.235 @@ -191,7 +274,7 @@ 1.236 // 1.237 // Clean: Calls directly to runtime method for fixup 1.238 // Compiled code: Calls directly to compiled code 1.239 -// Interpreted code: Calls to stub that set methodOop reference 1.240 +// Interpreted code: Calls to stub that set Method* reference 1.241 // 1.242 // 1.243 class CompiledStaticCall;