156 return dest; 157 } 158 159 char* Method::name_and_sig_as_C_string(Klass* klass, Symbol* method_name, Symbol* signature, char* buf, int size) { 160 Symbol* klass_name = klass->name(); 161 klass_name->as_klass_external_name(buf, size); 162 int len = (int)strlen(buf); 163 164 if (len < size - 1) { 165 buf[len++] = '.'; 166 167 method_name->as_C_string(&(buf[len]), size - len); 168 len = (int)strlen(buf); 169 170 signature->as_C_string(&(buf[len]), size - len); 171 } 172 173 return buf; 174 } 175 176 int Method::fast_exception_handler_bci_for(methodHandle mh, KlassHandle ex_klass, int throw_bci, TRAPS) { 177 // exception table holds quadruple entries of the form (beg_bci, end_bci, handler_bci, klass_index) 178 // access exception table 179 ExceptionTable table(mh()); 180 int length = table.length(); 181 // iterate through all entries sequentially 182 constantPoolHandle pool(THREAD, mh->constants()); 183 for (int i = 0; i < length; i ++) { 184 //reacquire the table in case a GC happened 185 ExceptionTable table(mh()); 186 int beg_bci = table.start_pc(i); 187 int end_bci = table.end_pc(i); 188 assert(beg_bci <= end_bci, "inconsistent exception table"); 189 if (beg_bci <= throw_bci && throw_bci < end_bci) { 190 // exception handler bci range covers throw_bci => investigate further 191 int handler_bci = table.handler_pc(i); 192 int klass_index = table.catch_type_index(i); 193 if (klass_index == 0) { 194 return handler_bci; 195 } else if (ex_klass.is_null()) { 196 return handler_bci; 197 } else { 198 // we know the exception class => get the constraint class 199 // this may require loading of the constraint class; if verification 200 // fails or some other exception occurs, return handler_bci 201 Klass* k = pool->klass_at(klass_index, CHECK_(handler_bci)); 202 KlassHandle klass = KlassHandle(THREAD, k); 203 assert(klass.not_null(), "klass not loaded"); 204 if (ex_klass->is_subtype_of(klass())) { 205 return handler_bci; 206 } 207 } 208 } 209 } 210 211 return -1; 212 } 213 214 void Method::mask_for(int bci, InterpreterOopMap* mask) { 215 216 Thread* myThread = Thread::current(); 217 methodHandle h_this(myThread, this); 218 #if defined(ASSERT) && !INCLUDE_JVMCI 219 bool has_capability = myThread->is_VM_thread() || 220 myThread->is_ConcurrentGC_thread() || 221 myThread->is_GC_task_thread(); 222 223 if (!has_capability) { 224 if (!VerifyStack && !VerifyLastFrame) { 1255 // Test if this method is an internal MH primitive method. 1256 bool Method::is_method_handle_intrinsic() const { 1257 vmIntrinsics::ID iid = intrinsic_id(); 1258 return (MethodHandles::is_signature_polymorphic(iid) && 1259 MethodHandles::is_signature_polymorphic_intrinsic(iid)); 1260 } 1261 1262 bool Method::has_member_arg() const { 1263 vmIntrinsics::ID iid = intrinsic_id(); 1264 return (MethodHandles::is_signature_polymorphic(iid) && 1265 MethodHandles::has_member_arg(iid)); 1266 } 1267 1268 // Make an instance of a signature-polymorphic internal MH primitive. 1269 methodHandle Method::make_method_handle_intrinsic(vmIntrinsics::ID iid, 1270 Symbol* signature, 1271 TRAPS) { 1272 ResourceMark rm; 1273 methodHandle empty; 1274 1275 KlassHandle holder = SystemDictionary::MethodHandle_klass(); 1276 Symbol* name = MethodHandles::signature_polymorphic_intrinsic_name(iid); 1277 assert(iid == MethodHandles::signature_polymorphic_name_id(name), ""); 1278 if (TraceMethodHandles) { 1279 tty->print_cr("make_method_handle_intrinsic MH.%s%s", name->as_C_string(), signature->as_C_string()); 1280 } 1281 1282 // invariant: cp->symbol_at_put is preceded by a refcount increment (more usually a lookup) 1283 name->increment_refcount(); 1284 signature->increment_refcount(); 1285 1286 int cp_length = _imcp_limit; 1287 ClassLoaderData* loader_data = holder->class_loader_data(); 1288 constantPoolHandle cp; 1289 { 1290 ConstantPool* cp_oop = ConstantPool::allocate(loader_data, cp_length, CHECK_(empty)); 1291 cp = constantPoolHandle(THREAD, cp_oop); 1292 } 1293 cp->set_pool_holder(InstanceKlass::cast(holder())); 1294 cp->symbol_at_put(_imcp_invoke_name, name); 1295 cp->symbol_at_put(_imcp_invoke_signature, signature); 1296 cp->set_has_preresolution(); 1297 1298 // decide on access bits: public or not? 1299 int flags_bits = (JVM_ACC_NATIVE | JVM_ACC_SYNTHETIC | JVM_ACC_FINAL); 1300 bool must_be_static = MethodHandles::is_signature_polymorphic_static(iid); 1301 if (must_be_static) flags_bits |= JVM_ACC_STATIC; 1302 assert((flags_bits & JVM_ACC_PUBLIC) == 0, "do not expose these methods"); 1303 1304 methodHandle m; 1305 { 1306 InlineTableSizes sizes; 1307 Method* m_oop = Method::allocate(loader_data, 0, 1308 accessFlags_from(flags_bits), &sizes, 1309 ConstMethod::NORMAL, CHECK_(empty)); 1310 m = methodHandle(THREAD, m_oop); 1311 } 1312 m->set_constants(cp()); 1313 m->set_name_index(_imcp_invoke_name); | 156 return dest; 157 } 158 159 char* Method::name_and_sig_as_C_string(Klass* klass, Symbol* method_name, Symbol* signature, char* buf, int size) { 160 Symbol* klass_name = klass->name(); 161 klass_name->as_klass_external_name(buf, size); 162 int len = (int)strlen(buf); 163 164 if (len < size - 1) { 165 buf[len++] = '.'; 166 167 method_name->as_C_string(&(buf[len]), size - len); 168 len = (int)strlen(buf); 169 170 signature->as_C_string(&(buf[len]), size - len); 171 } 172 173 return buf; 174 } 175 176 int Method::fast_exception_handler_bci_for(methodHandle mh, Klass* ex_klass, int throw_bci, TRAPS) { 177 // exception table holds quadruple entries of the form (beg_bci, end_bci, handler_bci, klass_index) 178 // access exception table 179 ExceptionTable table(mh()); 180 int length = table.length(); 181 // iterate through all entries sequentially 182 constantPoolHandle pool(THREAD, mh->constants()); 183 for (int i = 0; i < length; i ++) { 184 //reacquire the table in case a GC happened 185 ExceptionTable table(mh()); 186 int beg_bci = table.start_pc(i); 187 int end_bci = table.end_pc(i); 188 assert(beg_bci <= end_bci, "inconsistent exception table"); 189 if (beg_bci <= throw_bci && throw_bci < end_bci) { 190 // exception handler bci range covers throw_bci => investigate further 191 int handler_bci = table.handler_pc(i); 192 int klass_index = table.catch_type_index(i); 193 if (klass_index == 0) { 194 return handler_bci; 195 } else if (ex_klass == NULL) { 196 return handler_bci; 197 } else { 198 // we know the exception class => get the constraint class 199 // this may require loading of the constraint class; if verification 200 // fails or some other exception occurs, return handler_bci 201 Klass* k = pool->klass_at(klass_index, CHECK_(handler_bci)); 202 assert(k != NULL, "klass not loaded"); 203 if (ex_klass->is_subtype_of(k)) { 204 return handler_bci; 205 } 206 } 207 } 208 } 209 210 return -1; 211 } 212 213 void Method::mask_for(int bci, InterpreterOopMap* mask) { 214 215 Thread* myThread = Thread::current(); 216 methodHandle h_this(myThread, this); 217 #if defined(ASSERT) && !INCLUDE_JVMCI 218 bool has_capability = myThread->is_VM_thread() || 219 myThread->is_ConcurrentGC_thread() || 220 myThread->is_GC_task_thread(); 221 222 if (!has_capability) { 223 if (!VerifyStack && !VerifyLastFrame) { 1254 // Test if this method is an internal MH primitive method. 1255 bool Method::is_method_handle_intrinsic() const { 1256 vmIntrinsics::ID iid = intrinsic_id(); 1257 return (MethodHandles::is_signature_polymorphic(iid) && 1258 MethodHandles::is_signature_polymorphic_intrinsic(iid)); 1259 } 1260 1261 bool Method::has_member_arg() const { 1262 vmIntrinsics::ID iid = intrinsic_id(); 1263 return (MethodHandles::is_signature_polymorphic(iid) && 1264 MethodHandles::has_member_arg(iid)); 1265 } 1266 1267 // Make an instance of a signature-polymorphic internal MH primitive. 1268 methodHandle Method::make_method_handle_intrinsic(vmIntrinsics::ID iid, 1269 Symbol* signature, 1270 TRAPS) { 1271 ResourceMark rm; 1272 methodHandle empty; 1273 1274 InstanceKlass* holder = SystemDictionary::MethodHandle_klass(); 1275 Symbol* name = MethodHandles::signature_polymorphic_intrinsic_name(iid); 1276 assert(iid == MethodHandles::signature_polymorphic_name_id(name), ""); 1277 if (TraceMethodHandles) { 1278 tty->print_cr("make_method_handle_intrinsic MH.%s%s", name->as_C_string(), signature->as_C_string()); 1279 } 1280 1281 // invariant: cp->symbol_at_put is preceded by a refcount increment (more usually a lookup) 1282 name->increment_refcount(); 1283 signature->increment_refcount(); 1284 1285 int cp_length = _imcp_limit; 1286 ClassLoaderData* loader_data = holder->class_loader_data(); 1287 constantPoolHandle cp; 1288 { 1289 ConstantPool* cp_oop = ConstantPool::allocate(loader_data, cp_length, CHECK_(empty)); 1290 cp = constantPoolHandle(THREAD, cp_oop); 1291 } 1292 cp->set_pool_holder(holder); 1293 cp->symbol_at_put(_imcp_invoke_name, name); 1294 cp->symbol_at_put(_imcp_invoke_signature, signature); 1295 cp->set_has_preresolution(); 1296 1297 // decide on access bits: public or not? 1298 int flags_bits = (JVM_ACC_NATIVE | JVM_ACC_SYNTHETIC | JVM_ACC_FINAL); 1299 bool must_be_static = MethodHandles::is_signature_polymorphic_static(iid); 1300 if (must_be_static) flags_bits |= JVM_ACC_STATIC; 1301 assert((flags_bits & JVM_ACC_PUBLIC) == 0, "do not expose these methods"); 1302 1303 methodHandle m; 1304 { 1305 InlineTableSizes sizes; 1306 Method* m_oop = Method::allocate(loader_data, 0, 1307 accessFlags_from(flags_bits), &sizes, 1308 ConstMethod::NORMAL, CHECK_(empty)); 1309 m = methodHandle(THREAD, m_oop); 1310 } 1311 m->set_constants(cp()); 1312 m->set_name_index(_imcp_invoke_name); |