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