< prev index next >

src/hotspot/share/compiler/methodMatcher.cpp

Print this page

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");
< prev index next >