92 JavaThread* thread = JavaThread::current(); 93 RegisterMap reg_map(thread, false); 94 frame runtime_frame = thread->last_frame(); 95 frame caller_frame = runtime_frame.sender(®_map); 96 assert(caller_frame.is_compiled_frame(), "must be compiled"); 97 return caller_frame.is_deoptimized_frame(); 98 } 99 100 // Stress deoptimization 101 static void deopt_caller() { 102 if ( !caller_is_deopted()) { 103 JavaThread* thread = JavaThread::current(); 104 RegisterMap reg_map(thread, false); 105 frame runtime_frame = thread->last_frame(); 106 frame caller_frame = runtime_frame.sender(®_map); 107 Deoptimization::deoptimize_frame(thread, caller_frame.id(), Deoptimization::Reason_constraint); 108 assert(caller_is_deopted(), "Must be deoptimized"); 109 } 110 } 111 112 JRT_BLOCK_ENTRY(void, JVMCIRuntime::new_instance(JavaThread* thread, Klass* klass)) 113 JRT_BLOCK; 114 assert(klass->is_klass(), "not a class"); 115 Handle holder(THREAD, klass->klass_holder()); // keep the klass alive 116 InstanceKlass* ik = InstanceKlass::cast(klass); 117 ik->check_valid_for_instantiation(true, CHECK); 118 // make sure klass is initialized 119 ik->initialize(CHECK); 120 // allocate instance and return via TLS 121 oop obj = ik->allocate_instance(CHECK); 122 thread->set_vm_result(obj); 123 JRT_BLOCK_END; 124 SharedRuntime::on_slowpath_allocation_exit(thread); 125 JRT_END 126 127 JRT_BLOCK_ENTRY(void, JVMCIRuntime::new_array(JavaThread* thread, Klass* array_klass, jint length)) 128 JRT_BLOCK; 129 // Note: no handle for klass needed since they are not used 130 // anymore after new_objArray() and no GC can happen before. 131 // (This may have to change if this code changes!) 132 assert(array_klass->is_klass(), "not a class"); 133 oop obj; 134 if (array_klass->is_typeArray_klass()) { 135 BasicType elt_type = TypeArrayKlass::cast(array_klass)->element_type(); 136 obj = oopFactory::new_typeArray(elt_type, length, CHECK); 137 } else { 138 Handle holder(THREAD, array_klass->klass_holder()); // keep the klass alive 139 Klass* elem_klass = ObjArrayKlass::cast(array_klass)->element_klass(); 140 obj = oopFactory::new_objArray(elem_klass, length, CHECK); 141 } 142 thread->set_vm_result(obj); 143 // This is pretty rare but this runtime patch is stressful to deoptimization 144 // if we deoptimize here so force a deopt to stress the path. 145 if (DeoptimizeALot) { 146 static int deopts = 0; 147 // Alternate between deoptimizing and raising an error (which will also cause a deopt) 148 if (deopts++ % 2 == 0) { 149 ResourceMark rm(THREAD); 150 THROW(vmSymbols::java_lang_OutOfMemoryError()); 151 } else { 152 deopt_caller(); 153 } 154 } 155 JRT_BLOCK_END; 156 SharedRuntime::on_slowpath_allocation_exit(thread); 157 JRT_END 158 159 JRT_ENTRY(void, JVMCIRuntime::new_multi_array(JavaThread* thread, Klass* klass, int rank, jint* dims)) 160 assert(klass->is_klass(), "not a class"); 161 assert(rank >= 1, "rank must be nonzero"); 162 Handle holder(THREAD, klass->klass_holder()); // keep the klass alive 163 oop obj = ArrayKlass::cast(klass)->multi_allocate(rank, dims, CHECK); 164 thread->set_vm_result(obj); 165 JRT_END 166 167 JRT_ENTRY(void, JVMCIRuntime::dynamic_new_array(JavaThread* thread, oopDesc* element_mirror, jint length)) 168 oop obj = Reflection::reflect_new_array(element_mirror, length, CHECK); 169 thread->set_vm_result(obj); 170 JRT_END 171 172 JRT_ENTRY(void, JVMCIRuntime::dynamic_new_instance(JavaThread* thread, oopDesc* type_mirror)) 173 InstanceKlass* klass = InstanceKlass::cast(java_lang_Class::as_Klass(type_mirror)); 174 175 if (klass == NULL) { 176 ResourceMark rm(THREAD); 177 THROW(vmSymbols::java_lang_InstantiationException()); 178 } 179 180 // Create new instance (the receiver) 181 klass->check_valid_for_instantiation(false, CHECK); 182 183 // Make sure klass gets initialized 184 klass->initialize(CHECK); 185 186 oop obj = klass->allocate_instance(CHECK); 187 thread->set_vm_result(obj); 188 JRT_END 189 190 extern void vm_exit(int code); 191 192 // Enter this method from compiled code handler below. This is where we transition 193 // to VM mode. This is done as a helper routine so that the method called directly 194 // from compiled code does not have to transition to VM. This allows the entry 195 // method to see if the nmethod that we have just looked up a handler for has 196 // been deoptimized while we were in the vm. This simplifies the assembly code 197 // cpu directories. 198 // 199 // We are entering here from exception stub (via the entry method below) 200 // If there is a compiled exception handler in this method, we will continue there; 201 // otherwise we will unwind the stack and continue at the caller of top frame method 202 // Note: we enter in Java using a special JRT wrapper. This wrapper allows us to 203 // control the area where we can allow a safepoint. After we exit the safepoint area we can 204 // check to see if the handler we are going to return is now in a nmethod that has | 92 JavaThread* thread = JavaThread::current(); 93 RegisterMap reg_map(thread, false); 94 frame runtime_frame = thread->last_frame(); 95 frame caller_frame = runtime_frame.sender(®_map); 96 assert(caller_frame.is_compiled_frame(), "must be compiled"); 97 return caller_frame.is_deoptimized_frame(); 98 } 99 100 // Stress deoptimization 101 static void deopt_caller() { 102 if ( !caller_is_deopted()) { 103 JavaThread* thread = JavaThread::current(); 104 RegisterMap reg_map(thread, false); 105 frame runtime_frame = thread->last_frame(); 106 frame caller_frame = runtime_frame.sender(®_map); 107 Deoptimization::deoptimize_frame(thread, caller_frame.id(), Deoptimization::Reason_constraint); 108 assert(caller_is_deopted(), "Must be deoptimized"); 109 } 110 } 111 112 // Manages a scope for a JVMCI runtime call that attempts a heap allocation. 113 // If there is a pending exception upon closing the scope and the runtime 114 // call is of the variety where allocation failure returns NULL without an 115 // exception, the following action is taken: 116 // 1. The pending exception is cleared 117 // 2. NULL is written to JavaThread::_vm_result 118 // 3. Checks that an OutOfMemoryError is Universe::out_of_memory_error_retry(). 119 class RetryableAllocationMark: public StackObj { 120 private: 121 JavaThread* _thread; 122 public: 123 RetryableAllocationMark(JavaThread* thread, bool activate) { 124 if (activate) { 125 assert(!thread->in_retryable_allocation(), "retryable allocation scope is non-reentrant"); 126 _thread = thread; 127 _thread->set_in_retryable_allocation(true); 128 } else { 129 _thread = NULL; 130 } 131 } 132 ~RetryableAllocationMark() { 133 if (_thread != NULL) { 134 _thread->set_in_retryable_allocation(false); 135 JavaThread* THREAD = _thread; 136 if (HAS_PENDING_EXCEPTION) { 137 oop ex = PENDING_EXCEPTION; 138 CLEAR_PENDING_EXCEPTION; 139 oop retry_oome = Universe::out_of_memory_error_retry(); 140 if (ex->is_a(retry_oome->klass()) && retry_oome != ex) { 141 ResourceMark rm; 142 fatal("Unexpected exception in scope of retryable allocation: " INTPTR_FORMAT " of type %s", p2i(ex), ex->klass()->external_name()); 143 } 144 _thread->set_vm_result(NULL); 145 } 146 } 147 } 148 }; 149 150 JRT_BLOCK_ENTRY(void, JVMCIRuntime::new_instance_common(JavaThread* thread, Klass* klass, bool null_on_fail)) 151 JRT_BLOCK; 152 assert(klass->is_klass(), "not a class"); 153 Handle holder(THREAD, klass->klass_holder()); // keep the klass alive 154 InstanceKlass* ik = InstanceKlass::cast(klass); 155 { 156 RetryableAllocationMark ram(thread, null_on_fail); 157 ik->check_valid_for_instantiation(true, CHECK); 158 oop obj; 159 if (null_on_fail) { 160 if (!ik->is_initialized()) { 161 // Cannot re-execute class initialization without side effects 162 // so return without attempting the initialization 163 return; 164 } 165 } else { 166 // make sure klass is initialized 167 ik->initialize(CHECK); 168 } 169 // allocate instance and return via TLS 170 obj = ik->allocate_instance(CHECK); 171 thread->set_vm_result(obj); 172 } 173 JRT_BLOCK_END; 174 SharedRuntime::on_slowpath_allocation_exit(thread); 175 JRT_END 176 177 JRT_BLOCK_ENTRY(void, JVMCIRuntime::new_array_common(JavaThread* thread, Klass* array_klass, jint length, bool null_on_fail)) 178 JRT_BLOCK; 179 // Note: no handle for klass needed since they are not used 180 // anymore after new_objArray() and no GC can happen before. 181 // (This may have to change if this code changes!) 182 assert(array_klass->is_klass(), "not a class"); 183 oop obj; 184 if (array_klass->is_typeArray_klass()) { 185 BasicType elt_type = TypeArrayKlass::cast(array_klass)->element_type(); 186 RetryableAllocationMark ram(thread, null_on_fail); 187 obj = oopFactory::new_typeArray(elt_type, length, CHECK); 188 } else { 189 Handle holder(THREAD, array_klass->klass_holder()); // keep the klass alive 190 Klass* elem_klass = ObjArrayKlass::cast(array_klass)->element_klass(); 191 RetryableAllocationMark ram(thread, null_on_fail); 192 obj = oopFactory::new_objArray(elem_klass, length, CHECK); 193 } 194 thread->set_vm_result(obj); 195 // This is pretty rare but this runtime patch is stressful to deoptimization 196 // if we deoptimize here so force a deopt to stress the path. 197 if (DeoptimizeALot) { 198 static int deopts = 0; 199 // Alternate between deoptimizing and raising an error (which will also cause a deopt) 200 if (deopts++ % 2 == 0) { 201 if (null_on_fail) { 202 return; 203 } else { 204 ResourceMark rm(THREAD); 205 THROW(vmSymbols::java_lang_OutOfMemoryError()); 206 } 207 } else { 208 deopt_caller(); 209 } 210 } 211 JRT_BLOCK_END; 212 SharedRuntime::on_slowpath_allocation_exit(thread); 213 JRT_END 214 215 JRT_ENTRY(void, JVMCIRuntime::new_multi_array_common(JavaThread* thread, Klass* klass, int rank, jint* dims, bool null_on_fail)) 216 assert(klass->is_klass(), "not a class"); 217 assert(rank >= 1, "rank must be nonzero"); 218 Handle holder(THREAD, klass->klass_holder()); // keep the klass alive 219 RetryableAllocationMark ram(thread, null_on_fail); 220 oop obj = ArrayKlass::cast(klass)->multi_allocate(rank, dims, CHECK); 221 thread->set_vm_result(obj); 222 JRT_END 223 224 JRT_ENTRY(void, JVMCIRuntime::dynamic_new_array_common(JavaThread* thread, oopDesc* element_mirror, jint length, bool null_on_fail)) 225 RetryableAllocationMark ram(thread, null_on_fail); 226 oop obj = Reflection::reflect_new_array(element_mirror, length, CHECK); 227 thread->set_vm_result(obj); 228 JRT_END 229 230 JRT_ENTRY(void, JVMCIRuntime::dynamic_new_instance_common(JavaThread* thread, oopDesc* type_mirror, bool null_on_fail)) 231 InstanceKlass* klass = InstanceKlass::cast(java_lang_Class::as_Klass(type_mirror)); 232 233 if (klass == NULL) { 234 ResourceMark rm(THREAD); 235 THROW(vmSymbols::java_lang_InstantiationException()); 236 } 237 RetryableAllocationMark ram(thread, null_on_fail); 238 239 // Create new instance (the receiver) 240 klass->check_valid_for_instantiation(false, CHECK); 241 242 if (null_on_fail) { 243 if (!klass->is_initialized()) { 244 // Cannot re-execute class initialization without side effects 245 // so return without attempting the initialization 246 return; 247 } 248 } else { 249 // Make sure klass gets initialized 250 klass->initialize(CHECK); 251 } 252 253 oop obj = klass->allocate_instance(CHECK); 254 thread->set_vm_result(obj); 255 JRT_END 256 257 extern void vm_exit(int code); 258 259 // Enter this method from compiled code handler below. This is where we transition 260 // to VM mode. This is done as a helper routine so that the method called directly 261 // from compiled code does not have to transition to VM. This allows the entry 262 // method to see if the nmethod that we have just looked up a handler for has 263 // been deoptimized while we were in the vm. This simplifies the assembly code 264 // cpu directories. 265 // 266 // We are entering here from exception stub (via the entry method below) 267 // If there is a compiled exception handler in this method, we will continue there; 268 // otherwise we will unwind the stack and continue at the caller of top frame method 269 // Note: we enter in Java using a special JRT wrapper. This wrapper allows us to 270 // control the area where we can allow a safepoint. After we exit the safepoint area we can 271 // check to see if the handler we are going to return is now in a nmethod that has |