269
270 if (!MethodMatcher::canonicalize(line, error_msg)) {
271 assert(error_msg != nullptr, "Message must be set if parsing failed");
272 return;
273 }
274
275 skip_leading_spaces(line, &total_bytes_read);
276 if (*line == '\0') {
277 error_msg = "Method pattern missing from command";
278 return;
279 }
280
281 if (2 == sscanf(line, "%255" RANGESLASH "%*[ ]" "%255" RANGE0 "%n", class_name, method_name, &bytes_read)) {
282 c_match = check_mode(class_name, error_msg);
283 m_match = check_mode(method_name, error_msg);
284
285 // Over-consumption
286 // method_name points to an option type or option name because the method name is not specified by users.
287 // In very rare case, the method name happens to be same as option type/name, so look ahead to make sure
288 // it doesn't show up again.
289 if ((OptionType::Unknown != CompilerOracle::parse_option_type(method_name) ||
290 CompileCommandEnum::Unknown != CompilerOracle::parse_option_name(method_name)) &&
291 *(line + bytes_read) != '\0' &&
292 strstr(line + bytes_read, method_name) == nullptr) {
293 error_msg = "Did not specify any method name";
294 method_name[0] = '\0';
295 return;
296 }
297
298 if ((strchr(class_name, JVM_SIGNATURE_SPECIAL) != nullptr) ||
299 (strchr(class_name, JVM_SIGNATURE_ENDSPECIAL) != nullptr)) {
300 error_msg = "Chars '<' and '>' not allowed in class name";
301 return;
302 }
303
304 if ((strchr(method_name, JVM_SIGNATURE_SPECIAL) != nullptr) ||
305 (strchr(method_name, JVM_SIGNATURE_ENDSPECIAL) != nullptr)) {
306 if (!vmSymbols::object_initializer_name()->equals(method_name) &&
307 !vmSymbols::class_initializer_name()->equals(method_name)) {
308 error_msg = "Chars '<' and '>' only allowed in <init> and <clinit>";
309 return;
310 }
311 }
312
313 if (c_match == MethodMatcher::Unknown || m_match == MethodMatcher::Unknown) {
314 assert(error_msg != nullptr, "Must have been set by check_mode()");
315 return;
316 }
343 matcher->init(c_name, c_match, m_name, m_match, signature);
344 return;
345 } else {
346 error_msg = "Could not parse method pattern";
347 }
348 }
349
350 bool MethodMatcher::matches(const methodHandle& method) const {
351 Symbol* class_name = method->method_holder()->name();
352 Symbol* method_name = method->name();
353 Symbol* signature = method->signature();
354
355 if (match(class_name, this->class_name(), _class_mode) &&
356 match(method_name, this->method_name(), _method_mode) &&
357 ((this->signature() == nullptr) || match(signature, this->signature(), Prefix))) {
358 return true;
359 }
360 return false;
361 }
362
363 void MethodMatcher::print_symbol(outputStream* st, Symbol* h, Mode mode) {
364 if (mode == Suffix || mode == Substring || mode == Any) {
365 st->print("*");
366 }
367 if (mode != Any) {
368 h->print_utf8_on(st);
369 }
370 if (mode == Prefix || mode == Substring) {
371 st->print("*");
372 }
373 }
374
375 void MethodMatcher::print_base(outputStream* st) {
376 ResourceMark rm;
377
378 print_symbol(st, class_name(), _class_mode);
379 st->print(".");
380 print_symbol(st, method_name(), _method_mode);
381 if (signature() != nullptr) {
382 signature()->print_utf8_on(st);
387 assert(error_msg == nullptr, "Don't call here with error_msg already set");
388 BasicMatcher* bm = new BasicMatcher();
389 MethodMatcher::parse_method_pattern(line, error_msg, bm);
390 if (error_msg != nullptr) {
391 delete bm;
392 return nullptr;
393 }
394 if (!expect_trailing_chars) {
395 // check for bad trailing characters
396 int bytes_read = 0;
397 sscanf(line, "%*[ \t]%n", &bytes_read);
398 if (line[bytes_read] != '\0') {
399 error_msg = "Unrecognized trailing text after method pattern";
400 delete bm;
401 return nullptr;
402 }
403 }
404 return bm;
405 }
406
407 bool BasicMatcher::match(const methodHandle& method) {
408 for (BasicMatcher* current = this; current != nullptr; current = current->next()) {
409 if (current->matches(method)) {
410 return true;
411 }
412 }
413 return false;
414 }
415
416 void InlineMatcher::print(outputStream* st) {
417 if (_inline_action == InlineMatcher::force_inline) {
418 st->print("+");
419 } else {
420 st->print("-");
421 }
422 print_base(st);
423 }
424
425 InlineMatcher* InlineMatcher::parse_method_pattern(char* line, const char*& error_msg) {
426 assert(error_msg == nullptr, "Dont call here with error_msg already set");
|
269
270 if (!MethodMatcher::canonicalize(line, error_msg)) {
271 assert(error_msg != nullptr, "Message must be set if parsing failed");
272 return;
273 }
274
275 skip_leading_spaces(line, &total_bytes_read);
276 if (*line == '\0') {
277 error_msg = "Method pattern missing from command";
278 return;
279 }
280
281 if (2 == sscanf(line, "%255" RANGESLASH "%*[ ]" "%255" RANGE0 "%n", class_name, method_name, &bytes_read)) {
282 c_match = check_mode(class_name, error_msg);
283 m_match = check_mode(method_name, error_msg);
284
285 // Over-consumption
286 // method_name points to an option type or option name because the method name is not specified by users.
287 // In very rare case, the method name happens to be same as option type/name, so look ahead to make sure
288 // it doesn't show up again.
289 // !!! FIXME !!! rejects TooManyTrapsAtBCI,CLS::print()V,199 command
290 // if ((OptionType::Unknown != CompilerOracle::parse_option_type(method_name) ||
291 // CompileCommandEnum::Unknown != CompilerOracle::parse_option_name(method_name)) &&
292 // *(line + bytes_read) != '\0' &&
293 // strstr(line + bytes_read, method_name) == nullptr) {
294 // error_msg = "Did not specify any method name";
295 // method_name[0] = '\0';
296 // return;
297 // }
298
299 if ((strchr(class_name, JVM_SIGNATURE_SPECIAL) != nullptr) ||
300 (strchr(class_name, JVM_SIGNATURE_ENDSPECIAL) != nullptr)) {
301 error_msg = "Chars '<' and '>' not allowed in class name";
302 return;
303 }
304
305 if ((strchr(method_name, JVM_SIGNATURE_SPECIAL) != nullptr) ||
306 (strchr(method_name, JVM_SIGNATURE_ENDSPECIAL) != nullptr)) {
307 if (!vmSymbols::object_initializer_name()->equals(method_name) &&
308 !vmSymbols::class_initializer_name()->equals(method_name)) {
309 error_msg = "Chars '<' and '>' only allowed in <init> and <clinit>";
310 return;
311 }
312 }
313
314 if (c_match == MethodMatcher::Unknown || m_match == MethodMatcher::Unknown) {
315 assert(error_msg != nullptr, "Must have been set by check_mode()");
316 return;
317 }
344 matcher->init(c_name, c_match, m_name, m_match, signature);
345 return;
346 } else {
347 error_msg = "Could not parse method pattern";
348 }
349 }
350
351 bool MethodMatcher::matches(const methodHandle& method) const {
352 Symbol* class_name = method->method_holder()->name();
353 Symbol* method_name = method->name();
354 Symbol* signature = method->signature();
355
356 if (match(class_name, this->class_name(), _class_mode) &&
357 match(method_name, this->method_name(), _method_mode) &&
358 ((this->signature() == nullptr) || match(signature, this->signature(), Prefix))) {
359 return true;
360 }
361 return false;
362 }
363
364 bool MethodMatcher::matches(MethodDetails& method_details) const {
365 if (match(method_details.class_name(), this->class_name(), _class_mode) &&
366 match(method_details.method_name(), this->method_name(), _method_mode) &&
367 ((this->signature() == nullptr) || match(method_details.signature(), this->signature(), Prefix))) {
368 return true;
369 }
370 return false;
371 }
372
373 void MethodMatcher::print_symbol(outputStream* st, Symbol* h, Mode mode) {
374 if (mode == Suffix || mode == Substring || mode == Any) {
375 st->print("*");
376 }
377 if (mode != Any) {
378 h->print_utf8_on(st);
379 }
380 if (mode == Prefix || mode == Substring) {
381 st->print("*");
382 }
383 }
384
385 void MethodMatcher::print_base(outputStream* st) {
386 ResourceMark rm;
387
388 print_symbol(st, class_name(), _class_mode);
389 st->print(".");
390 print_symbol(st, method_name(), _method_mode);
391 if (signature() != nullptr) {
392 signature()->print_utf8_on(st);
397 assert(error_msg == nullptr, "Don't call here with error_msg already set");
398 BasicMatcher* bm = new BasicMatcher();
399 MethodMatcher::parse_method_pattern(line, error_msg, bm);
400 if (error_msg != nullptr) {
401 delete bm;
402 return nullptr;
403 }
404 if (!expect_trailing_chars) {
405 // check for bad trailing characters
406 int bytes_read = 0;
407 sscanf(line, "%*[ \t]%n", &bytes_read);
408 if (line[bytes_read] != '\0') {
409 error_msg = "Unrecognized trailing text after method pattern";
410 delete bm;
411 return nullptr;
412 }
413 }
414 return bm;
415 }
416
417 bool BasicMatcher::match(MethodDetails& method_details) {
418 for (BasicMatcher* current = this; current != nullptr; current = current->next()) {
419 if (current->matches(method_details)) {
420 return true;
421 }
422 }
423 return false;
424 }
425
426 bool BasicMatcher::match(const methodHandle& method) {
427 for (BasicMatcher* current = this; current != nullptr; current = current->next()) {
428 if (current->matches(method)) {
429 return true;
430 }
431 }
432 return false;
433 }
434
435 void InlineMatcher::print(outputStream* st) {
436 if (_inline_action == InlineMatcher::force_inline) {
437 st->print("+");
438 } else {
439 st->print("-");
440 }
441 print_base(st);
442 }
443
444 InlineMatcher* InlineMatcher::parse_method_pattern(char* line, const char*& error_msg) {
445 assert(error_msg == nullptr, "Dont call here with error_msg already set");
|