< prev index next >

src/hotspot/share/compiler/methodMatcher.cpp

Print this page

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