1aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin/* 2aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin * Copyright (C) 2015 The Android Open Source Project 3aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin * 4aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin * Licensed under the Apache License, Version 2.0 (the "License"); 5aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin * you may not use this file except in compliance with the License. 6aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin * You may obtain a copy of the License at 7aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin * 8aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin * http://www.apache.org/licenses/LICENSE-2.0 9aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin * 10aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin * Unless required by applicable law or agreed to in writing, software 11aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin * distributed under the License is distributed on an "AS IS" BASIS, 12aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin * See the License for the specific language governing permissions and 14aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin * limitations under the License. 15aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin */ 16aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin#ifndef ART_CMDLINE_CMDLINE_TYPES_H_ 17aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin#define ART_CMDLINE_CMDLINE_TYPES_H_ 18aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 19aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin#define CMDLINE_NDEBUG 1 // Do not output any debugging information for parsing. 20aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 2188b2b80aed15bb1f931cddd40e44ca525ef10018Vladimir Marko#include "memory_representation.h" 2288b2b80aed15bb1f931cddd40e44ca525ef10018Vladimir Marko#include "detail/cmdline_debug_detail.h" 23aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin#include "cmdline_type_parser.h" 24aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 25aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin// Includes for the types that are being specialized 26aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin#include <string> 27aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin#include "unit.h" 28aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin#include "jdwp/jdwp.h" 2988b2b80aed15bb1f931cddd40e44ca525ef10018Vladimir Marko#include "base/logging.h" 3088b2b80aed15bb1f931cddd40e44ca525ef10018Vladimir Marko#include "base/time_utils.h" 3188b2b80aed15bb1f931cddd40e44ca525ef10018Vladimir Marko#include "experimental_flags.h" 32aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin#include "gc/collector_type.h" 33aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin#include "gc/space/large_object_space.h" 34aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin#include "profiler_options.h" 35aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 36aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkinnamespace art { 37aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 38aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin// The default specialization will always fail parsing the type from a string. 39aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin// Provide your own specialization that inherits from CmdlineTypeParser<T> 40aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin// and implements either Parse or ParseAndAppend 41aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin// (only if the argument was defined with ::AppendValues()) but not both. 42aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkintemplate <typename T> 43aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkinstruct CmdlineType : CmdlineTypeParser<T> { 44aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin}; 45aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 46aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin// Specializations for CmdlineType<T> follow: 47aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 48aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin// Parse argument definitions for Unit-typed arguments. 49aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkintemplate <> 50aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkinstruct CmdlineType<Unit> : CmdlineTypeParser<Unit> { 51aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin Result Parse(const std::string& args) { 52aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin if (args == "") { 53aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return Result::Success(Unit{}); // NOLINT [whitespace/braces] [5] 54aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 55aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return Result::Failure("Unexpected extra characters " + args); 56aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 57aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin}; 58aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 59aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkintemplate <> 60aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkinstruct CmdlineType<JDWP::JdwpOptions> : CmdlineTypeParser<JDWP::JdwpOptions> { 613be6e9d904baa13d7cf51dfc6742dea12e766b2eSebastien Hertz /* 623be6e9d904baa13d7cf51dfc6742dea12e766b2eSebastien Hertz * Handle one of the JDWP name/value pairs. 633be6e9d904baa13d7cf51dfc6742dea12e766b2eSebastien Hertz * 643be6e9d904baa13d7cf51dfc6742dea12e766b2eSebastien Hertz * JDWP options are: 653be6e9d904baa13d7cf51dfc6742dea12e766b2eSebastien Hertz * help: if specified, show help message and bail 663be6e9d904baa13d7cf51dfc6742dea12e766b2eSebastien Hertz * transport: may be dt_socket or dt_shmem 673be6e9d904baa13d7cf51dfc6742dea12e766b2eSebastien Hertz * address: for dt_socket, "host:port", or just "port" when listening 683be6e9d904baa13d7cf51dfc6742dea12e766b2eSebastien Hertz * server: if "y", wait for debugger to attach; if "n", attach to debugger 693be6e9d904baa13d7cf51dfc6742dea12e766b2eSebastien Hertz * timeout: how long to wait for debugger to connect / listen 703be6e9d904baa13d7cf51dfc6742dea12e766b2eSebastien Hertz * 713be6e9d904baa13d7cf51dfc6742dea12e766b2eSebastien Hertz * Useful with server=n (these aren't supported yet): 723be6e9d904baa13d7cf51dfc6742dea12e766b2eSebastien Hertz * onthrow=<exception-name>: connect to debugger when exception thrown 733be6e9d904baa13d7cf51dfc6742dea12e766b2eSebastien Hertz * onuncaught=y|n: connect to debugger when uncaught exception thrown 743be6e9d904baa13d7cf51dfc6742dea12e766b2eSebastien Hertz * launch=<command-line>: launch the debugger itself 753be6e9d904baa13d7cf51dfc6742dea12e766b2eSebastien Hertz * 763be6e9d904baa13d7cf51dfc6742dea12e766b2eSebastien Hertz * The "transport" option is required, as is "address" if server=n. 773be6e9d904baa13d7cf51dfc6742dea12e766b2eSebastien Hertz */ 78aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin Result Parse(const std::string& options) { 79aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin VLOG(jdwp) << "ParseJdwpOptions: " << options; 80aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 81aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin if (options == "help") { 82aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return Result::Usage( 83aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin "Example: -Xrunjdwp:transport=dt_socket,address=8000,server=y\n" 84aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin "Example: -Xrunjdwp:transport=dt_socket,address=localhost:6500,server=n\n"); 85aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 86aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 87aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin const std::string s; 88aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 89aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin std::vector<std::string> pairs; 90aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin Split(options, ',', &pairs); 91aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 923be6e9d904baa13d7cf51dfc6742dea12e766b2eSebastien Hertz JDWP::JdwpOptions jdwp_options; 93aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 943be6e9d904baa13d7cf51dfc6742dea12e766b2eSebastien Hertz for (const std::string& jdwp_option : pairs) { 953be6e9d904baa13d7cf51dfc6742dea12e766b2eSebastien Hertz std::string::size_type equals_pos = jdwp_option.find('='); 963be6e9d904baa13d7cf51dfc6742dea12e766b2eSebastien Hertz if (equals_pos == std::string::npos) { 97aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return Result::Failure(s + 983be6e9d904baa13d7cf51dfc6742dea12e766b2eSebastien Hertz "Can't parse JDWP option '" + jdwp_option + "' in '" + options + "'"); 99aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 100aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 101b3b173bbbd1d1cbad555de13c3fa6765f5078bceSebastien Hertz Result parse_attempt = ParseJdwpOption(jdwp_option.substr(0, equals_pos), 102b3b173bbbd1d1cbad555de13c3fa6765f5078bceSebastien Hertz jdwp_option.substr(equals_pos + 1), 103b3b173bbbd1d1cbad555de13c3fa6765f5078bceSebastien Hertz &jdwp_options); 104b3b173bbbd1d1cbad555de13c3fa6765f5078bceSebastien Hertz if (parse_attempt.IsError()) { 105b3b173bbbd1d1cbad555de13c3fa6765f5078bceSebastien Hertz // We fail to parse this JDWP option. 106b3b173bbbd1d1cbad555de13c3fa6765f5078bceSebastien Hertz return parse_attempt; 107aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 108aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 109aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 110aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin if (jdwp_options.transport == JDWP::kJdwpTransportUnknown) { 111aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return Result::Failure(s + "Must specify JDWP transport: " + options); 112aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 113aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin if (!jdwp_options.server && (jdwp_options.host.empty() || jdwp_options.port == 0)) { 114aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return Result::Failure(s + "Must specify JDWP host and port when server=n: " + options); 115aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 116aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 117aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return Result::Success(std::move(jdwp_options)); 118aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 119aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 120b3b173bbbd1d1cbad555de13c3fa6765f5078bceSebastien Hertz Result ParseJdwpOption(const std::string& name, const std::string& value, 121b3b173bbbd1d1cbad555de13c3fa6765f5078bceSebastien Hertz JDWP::JdwpOptions* jdwp_options) { 122aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin if (name == "transport") { 123aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin if (value == "dt_socket") { 1243be6e9d904baa13d7cf51dfc6742dea12e766b2eSebastien Hertz jdwp_options->transport = JDWP::kJdwpTransportSocket; 125aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else if (value == "dt_android_adb") { 1263be6e9d904baa13d7cf51dfc6742dea12e766b2eSebastien Hertz jdwp_options->transport = JDWP::kJdwpTransportAndroidAdb; 127aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else { 128b3b173bbbd1d1cbad555de13c3fa6765f5078bceSebastien Hertz return Result::Failure("JDWP transport not supported: " + value); 129aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 130aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else if (name == "server") { 131aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin if (value == "n") { 1323be6e9d904baa13d7cf51dfc6742dea12e766b2eSebastien Hertz jdwp_options->server = false; 133aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else if (value == "y") { 1343be6e9d904baa13d7cf51dfc6742dea12e766b2eSebastien Hertz jdwp_options->server = true; 135aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else { 136b3b173bbbd1d1cbad555de13c3fa6765f5078bceSebastien Hertz return Result::Failure("JDWP option 'server' must be 'y' or 'n'"); 137aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 138aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else if (name == "suspend") { 139aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin if (value == "n") { 1403be6e9d904baa13d7cf51dfc6742dea12e766b2eSebastien Hertz jdwp_options->suspend = false; 141aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else if (value == "y") { 1423be6e9d904baa13d7cf51dfc6742dea12e766b2eSebastien Hertz jdwp_options->suspend = true; 143aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else { 144b3b173bbbd1d1cbad555de13c3fa6765f5078bceSebastien Hertz return Result::Failure("JDWP option 'suspend' must be 'y' or 'n'"); 145aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 146aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else if (name == "address") { 147aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin /* this is either <port> or <host>:<port> */ 148aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin std::string port_string; 1493be6e9d904baa13d7cf51dfc6742dea12e766b2eSebastien Hertz jdwp_options->host.clear(); 150aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin std::string::size_type colon = value.find(':'); 151aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin if (colon != std::string::npos) { 1523be6e9d904baa13d7cf51dfc6742dea12e766b2eSebastien Hertz jdwp_options->host = value.substr(0, colon); 153aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin port_string = value.substr(colon + 1); 154aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else { 155aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin port_string = value; 156aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 157aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin if (port_string.empty()) { 158b3b173bbbd1d1cbad555de13c3fa6765f5078bceSebastien Hertz return Result::Failure("JDWP address missing port: " + value); 159aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 160aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin char* end; 161aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin uint64_t port = strtoul(port_string.c_str(), &end, 10); 162aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin if (*end != '\0' || port > 0xffff) { 163b3b173bbbd1d1cbad555de13c3fa6765f5078bceSebastien Hertz return Result::Failure("JDWP address has junk in port field: " + value); 164aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 1653be6e9d904baa13d7cf51dfc6742dea12e766b2eSebastien Hertz jdwp_options->port = port; 166aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else if (name == "launch" || name == "onthrow" || name == "oncaught" || name == "timeout") { 167aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin /* valid but unsupported */ 168aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin LOG(INFO) << "Ignoring JDWP option '" << name << "'='" << value << "'"; 169aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else { 170aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin LOG(INFO) << "Ignoring unrecognized JDWP option '" << name << "'='" << value << "'"; 171aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 172aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 173b3b173bbbd1d1cbad555de13c3fa6765f5078bceSebastien Hertz return Result::SuccessNoValue(); 174aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 175aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 176aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin static const char* Name() { return "JdwpOptions"; } 177aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin}; 178aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 179aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkintemplate <size_t Divisor> 180aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkinstruct CmdlineType<Memory<Divisor>> : CmdlineTypeParser<Memory<Divisor>> { 181aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin using typename CmdlineTypeParser<Memory<Divisor>>::Result; 182aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 183aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin Result Parse(const std::string arg) { 184aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin CMDLINE_DEBUG_LOG << "Parsing memory: " << arg << std::endl; 185aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin size_t val = ParseMemoryOption(arg.c_str(), Divisor); 186aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin CMDLINE_DEBUG_LOG << "Memory parsed to size_t value: " << val << std::endl; 187aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 188aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin if (val == 0) { 189aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return Result::Failure(std::string("not a valid memory value, or not divisible by ") 190aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin + std::to_string(Divisor)); 191aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 192aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 193aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return Result::Success(Memory<Divisor>(val)); 194aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 195aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 196aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // Parse a string of the form /[0-9]+[kKmMgG]?/, which is used to specify 197aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // memory sizes. [kK] indicates kilobytes, [mM] megabytes, and 198aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // [gG] gigabytes. 199aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // 200aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // "s" should point just past the "-Xm?" part of the string. 201aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // "div" specifies a divisor, e.g. 1024 if the value must be a multiple 202aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // of 1024. 203aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // 204aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // The spec says the -Xmx and -Xms options must be multiples of 1024. It 205aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // doesn't say anything about -Xss. 206aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // 207aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // Returns 0 (a useless size) if "s" is malformed or specifies a low or 208aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // non-evenly-divisible value. 209aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // 210aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin static size_t ParseMemoryOption(const char* s, size_t div) { 211aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // strtoul accepts a leading [+-], which we don't want, 212aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // so make sure our string starts with a decimal digit. 213aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin if (isdigit(*s)) { 214aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin char* s2; 215aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin size_t val = strtoul(s, &s2, 10); 216aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin if (s2 != s) { 217aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // s2 should be pointing just after the number. 218aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // If this is the end of the string, the user 219aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // has specified a number of bytes. Otherwise, 220aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // there should be exactly one more character 221aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // that specifies a multiplier. 222aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin if (*s2 != '\0') { 223aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // The remainder of the string is either a single multiplier 224aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // character, or nothing to indicate that the value is in 225aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // bytes. 226aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin char c = *s2++; 227aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin if (*s2 == '\0') { 228aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin size_t mul; 229aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin if (c == '\0') { 230aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin mul = 1; 231aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else if (c == 'k' || c == 'K') { 232aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin mul = KB; 233aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else if (c == 'm' || c == 'M') { 234aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin mul = MB; 235aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else if (c == 'g' || c == 'G') { 236aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin mul = GB; 237aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else { 238aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // Unknown multiplier character. 239aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return 0; 240aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 241aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 242aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin if (val <= std::numeric_limits<size_t>::max() / mul) { 243aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin val *= mul; 244aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else { 245aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // Clamp to a multiple of 1024. 246aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin val = std::numeric_limits<size_t>::max() & ~(1024-1); 247aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 248aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else { 249aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // There's more than one character after the numeric part. 250aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return 0; 251aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 252aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 253aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // The man page says that a -Xm value must be a multiple of 1024. 254aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin if (val % div == 0) { 255aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return val; 256aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 257aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 258aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 259aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return 0; 260aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 261aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 262aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin static const char* Name() { return Memory<Divisor>::Name(); } 263aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin}; 264aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 265aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkintemplate <> 266aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkinstruct CmdlineType<double> : CmdlineTypeParser<double> { 267aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin Result Parse(const std::string& str) { 268aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin char* end = nullptr; 269aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin errno = 0; 270aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin double value = strtod(str.c_str(), &end); 271aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 272aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin if (*end != '\0') { 273aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return Result::Failure("Failed to parse double from " + str); 274aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 275aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin if (errno == ERANGE) { 276aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return Result::OutOfRange( 277aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin "Failed to parse double from " + str + "; overflow/underflow occurred"); 278aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 279aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 280aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return Result::Success(value); 281aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 282aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 283aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin static const char* Name() { return "double"; } 284aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin}; 285aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 286aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkintemplate <> 287aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkinstruct CmdlineType<unsigned int> : CmdlineTypeParser<unsigned int> { 288aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin Result Parse(const std::string& str) { 289aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin const char* begin = str.c_str(); 290aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin char* end; 291aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 292aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // Parse into a larger type (long long) because we can't use strtoul 293aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // since it silently converts negative values into unsigned long and doesn't set errno. 294aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin errno = 0; 295aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin long long int result = strtoll(begin, &end, 10); // NOLINT [runtime/int] [4] 296aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin if (begin == end || *end != '\0' || errno == EINVAL) { 297aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return Result::Failure("Failed to parse integer from " + str); 298aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else if ((errno == ERANGE) || // NOLINT [runtime/int] [4] 299aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin result < std::numeric_limits<int>::min() 300aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin || result > std::numeric_limits<unsigned int>::max() || result < 0) { 301aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return Result::OutOfRange( 302aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin "Failed to parse integer from " + str + "; out of unsigned int range"); 303aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 304aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 305aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return Result::Success(static_cast<unsigned int>(result)); 306aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 307aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 308aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin static const char* Name() { return "unsigned integer"; } 309aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin}; 310aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 311aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin// Lightweight nanosecond value type. Allows parser to convert user-input from milliseconds 312aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin// to nanoseconds automatically after parsing. 313aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin// 314aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin// All implicit conversion from uint64_t uses nanoseconds. 315aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkinstruct MillisecondsToNanoseconds { 316aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // Create from nanoseconds. 317aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin MillisecondsToNanoseconds(uint64_t nanoseconds) : nanoseconds_(nanoseconds) { // NOLINT [runtime/explicit] [5] 318aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 319aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 320aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // Create from milliseconds. 321aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin static MillisecondsToNanoseconds FromMilliseconds(unsigned int milliseconds) { 322aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return MillisecondsToNanoseconds(MsToNs(milliseconds)); 323aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 324aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 325aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // Get the underlying nanoseconds value. 326aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin uint64_t GetNanoseconds() const { 327aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return nanoseconds_; 328aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 329aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 330aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // Get the milliseconds value [via a conversion]. Loss of precision will occur. 331aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin uint64_t GetMilliseconds() const { 332aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return NsToMs(nanoseconds_); 333aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 334aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 335aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // Get the underlying nanoseconds value. 336aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin operator uint64_t() const { 337aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return GetNanoseconds(); 338aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 339aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 340aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // Default constructors/copy-constructors. 341aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin MillisecondsToNanoseconds() : nanoseconds_(0ul) {} 342c801f0d79b8c5bf28401a040356b59b2f41520f4Andreas Gampe MillisecondsToNanoseconds(const MillisecondsToNanoseconds&) = default; 343c801f0d79b8c5bf28401a040356b59b2f41520f4Andreas Gampe MillisecondsToNanoseconds(MillisecondsToNanoseconds&&) = default; 344aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 345aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin private: 346aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin uint64_t nanoseconds_; 347aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin}; 348aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 349aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkintemplate <> 350aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkinstruct CmdlineType<MillisecondsToNanoseconds> : CmdlineTypeParser<MillisecondsToNanoseconds> { 351aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin Result Parse(const std::string& str) { 352aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin CmdlineType<unsigned int> uint_parser; 353aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin CmdlineParseResult<unsigned int> res = uint_parser.Parse(str); 354aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 355aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin if (res.IsSuccess()) { 356aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return Result::Success(MillisecondsToNanoseconds::FromMilliseconds(res.GetValue())); 357aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else { 358aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return Result::CastError(res); 359aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 360aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 361aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 362aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin static const char* Name() { return "MillisecondsToNanoseconds"; } 363aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin}; 364aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 365aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkintemplate <> 366aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkinstruct CmdlineType<std::string> : CmdlineTypeParser<std::string> { 367aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin Result Parse(const std::string& args) { 368aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return Result::Success(args); 369aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 370aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 371aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin Result ParseAndAppend(const std::string& args, 372aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin std::string& existing_value) { 373aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin if (existing_value.empty()) { 374aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin existing_value = args; 375aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else { 376aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin existing_value += ' '; 377aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin existing_value += args; 378aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 379aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return Result::SuccessNoValue(); 380aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 381aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin}; 382aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 383aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkintemplate <> 384aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkinstruct CmdlineType<std::vector<std::string>> : CmdlineTypeParser<std::vector<std::string>> { 385aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin Result Parse(const std::string& args) { 386aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin assert(false && "Use AppendValues() for a string vector type"); 387aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return Result::Failure("Unconditional failure: string vector must be appended: " + args); 388aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 389aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 390aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin Result ParseAndAppend(const std::string& args, 391aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin std::vector<std::string>& existing_value) { 392aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin existing_value.push_back(args); 393aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return Result::SuccessNoValue(); 394aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 395aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 396aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin static const char* Name() { return "std::vector<std::string>"; } 397aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin}; 398aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 399aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkintemplate <char Separator> 400aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkinstruct ParseStringList { 401aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin explicit ParseStringList(std::vector<std::string>&& list) : list_(list) {} 402aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 403aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin operator std::vector<std::string>() const { 404aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return list_; 405aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 406aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 407aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin operator std::vector<std::string>&&() && { 408aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return std::move(list_); 409aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 410aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 411aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin size_t Size() const { 412aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return list_.size(); 413aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 414aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 415aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin std::string Join() const { 416aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return art::Join(list_, Separator); 417aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 418aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 419aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin static ParseStringList<Separator> Split(const std::string& str) { 420aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin std::vector<std::string> list; 421aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin art::Split(str, Separator, &list); 422aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return ParseStringList<Separator>(std::move(list)); 423aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 424aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 425aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin ParseStringList() = default; 426c801f0d79b8c5bf28401a040356b59b2f41520f4Andreas Gampe ParseStringList(const ParseStringList&) = default; 427c801f0d79b8c5bf28401a040356b59b2f41520f4Andreas Gampe ParseStringList(ParseStringList&&) = default; 428aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 429aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin private: 430aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin std::vector<std::string> list_; 431aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin}; 432aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 433aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkintemplate <char Separator> 434aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkinstruct CmdlineType<ParseStringList<Separator>> : CmdlineTypeParser<ParseStringList<Separator>> { 435aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin using Result = CmdlineParseResult<ParseStringList<Separator>>; 436aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 437aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin Result Parse(const std::string& args) { 438aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return Result::Success(ParseStringList<Separator>::Split(args)); 439aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 440aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 441aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin static const char* Name() { return "ParseStringList<Separator>"; } 442aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin}; 443aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 444aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkinstatic gc::CollectorType ParseCollectorType(const std::string& option) { 445aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin if (option == "MS" || option == "nonconcurrent") { 446aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return gc::kCollectorTypeMS; 447aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else if (option == "CMS" || option == "concurrent") { 448aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return gc::kCollectorTypeCMS; 449aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else if (option == "SS") { 450aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return gc::kCollectorTypeSS; 451aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else if (option == "GSS") { 452aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return gc::kCollectorTypeGSS; 453aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else if (option == "CC") { 454aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return gc::kCollectorTypeCC; 455aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else if (option == "MC") { 456aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return gc::kCollectorTypeMC; 457aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else { 458aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return gc::kCollectorTypeNone; 459aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 460aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin} 461aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 462aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkinstruct XGcOption { 463aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // These defaults are used when the command line arguments for -Xgc: 464aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // are either omitted completely or partially. 465aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin gc::CollectorType collector_type_ = kUseReadBarrier ? 466aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // If RB is enabled (currently a build-time decision), 467aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // use CC as the default GC. 468aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin gc::kCollectorTypeCC : 469aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin gc::kCollectorTypeDefault; 470aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin bool verify_pre_gc_heap_ = false; 471aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin bool verify_pre_sweeping_heap_ = kIsDebugBuild; 472aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin bool verify_post_gc_heap_ = false; 473aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin bool verify_pre_gc_rosalloc_ = kIsDebugBuild; 474aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin bool verify_pre_sweeping_rosalloc_ = false; 475aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin bool verify_post_gc_rosalloc_ = false; 476310008008c90fea246efd00cb99ee7ded97c5209Mathieu Chartier bool gcstress_ = false; 477aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin}; 478aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 479aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkintemplate <> 480aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkinstruct CmdlineType<XGcOption> : CmdlineTypeParser<XGcOption> { 481aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin Result Parse(const std::string& option) { // -Xgc: already stripped 482aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin XGcOption xgc{}; // NOLINT [readability/braces] [4] 483aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 484aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin std::vector<std::string> gc_options; 485aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin Split(option, ',', &gc_options); 486aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin for (const std::string& gc_option : gc_options) { 487aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin gc::CollectorType collector_type = ParseCollectorType(gc_option); 488aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin if (collector_type != gc::kCollectorTypeNone) { 489aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin xgc.collector_type_ = collector_type; 490aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else if (gc_option == "preverify") { 491aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin xgc.verify_pre_gc_heap_ = true; 492aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else if (gc_option == "nopreverify") { 493aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin xgc.verify_pre_gc_heap_ = false; 494aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else if (gc_option == "presweepingverify") { 495aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin xgc.verify_pre_sweeping_heap_ = true; 496aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else if (gc_option == "nopresweepingverify") { 497aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin xgc.verify_pre_sweeping_heap_ = false; 498aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else if (gc_option == "postverify") { 499aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin xgc.verify_post_gc_heap_ = true; 500aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else if (gc_option == "nopostverify") { 501aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin xgc.verify_post_gc_heap_ = false; 502aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else if (gc_option == "preverify_rosalloc") { 503aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin xgc.verify_pre_gc_rosalloc_ = true; 504aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else if (gc_option == "nopreverify_rosalloc") { 505aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin xgc.verify_pre_gc_rosalloc_ = false; 506aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else if (gc_option == "presweepingverify_rosalloc") { 507aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin xgc.verify_pre_sweeping_rosalloc_ = true; 508aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else if (gc_option == "nopresweepingverify_rosalloc") { 509aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin xgc.verify_pre_sweeping_rosalloc_ = false; 510aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else if (gc_option == "postverify_rosalloc") { 511aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin xgc.verify_post_gc_rosalloc_ = true; 512aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else if (gc_option == "nopostverify_rosalloc") { 513aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin xgc.verify_post_gc_rosalloc_ = false; 514310008008c90fea246efd00cb99ee7ded97c5209Mathieu Chartier } else if (gc_option == "gcstress") { 515310008008c90fea246efd00cb99ee7ded97c5209Mathieu Chartier xgc.gcstress_ = true; 516310008008c90fea246efd00cb99ee7ded97c5209Mathieu Chartier } else if (gc_option == "nogcstress") { 517310008008c90fea246efd00cb99ee7ded97c5209Mathieu Chartier xgc.gcstress_ = false; 518aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else if ((gc_option == "precise") || 519aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin (gc_option == "noprecise") || 520aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin (gc_option == "verifycardtable") || 521aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin (gc_option == "noverifycardtable")) { 522aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // Ignored for backwards compatibility. 523aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else { 524aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return Result::Usage(std::string("Unknown -Xgc option ") + gc_option); 525aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 526aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 527aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 528aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return Result::Success(std::move(xgc)); 529aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 530aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 531aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin static const char* Name() { return "XgcOption"; } 532aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin}; 533aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 534aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkinstruct BackgroundGcOption { 535aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // If background_collector_type_ is kCollectorTypeNone, it defaults to the 536aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // XGcOption::collector_type_ after parsing options. If you set this to 537aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // kCollectorTypeHSpaceCompact then we will do an hspace compaction when 538aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // we transition to background instead of a normal collector transition. 539aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin gc::CollectorType background_collector_type_; 540aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 541aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin BackgroundGcOption(gc::CollectorType background_collector_type) // NOLINT [runtime/explicit] [5] 542aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin : background_collector_type_(background_collector_type) {} 543aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin BackgroundGcOption() 544aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin : background_collector_type_(gc::kCollectorTypeNone) { 545aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 546aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin if (kUseReadBarrier) { 547aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin background_collector_type_ = gc::kCollectorTypeCC; // Disable background compaction for CC. 548aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 549aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 550aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 551aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin operator gc::CollectorType() const { return background_collector_type_; } 552aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin}; 553aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 554aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkintemplate<> 555aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkinstruct CmdlineType<BackgroundGcOption> 556aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin : CmdlineTypeParser<BackgroundGcOption>, private BackgroundGcOption { 557aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin Result Parse(const std::string& substring) { 558aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // Special handling for HSpaceCompact since this is only valid as a background GC type. 559aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin if (substring == "HSpaceCompact") { 560aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin background_collector_type_ = gc::kCollectorTypeHomogeneousSpaceCompact; 561aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else { 562aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin gc::CollectorType collector_type = ParseCollectorType(substring); 563aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin if (collector_type != gc::kCollectorTypeNone) { 564aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin background_collector_type_ = collector_type; 565aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else { 566aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return Result::Failure(); 567aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 568aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 569aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 570aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin BackgroundGcOption res = *this; 571aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return Result::Success(res); 572aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 573aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 574aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin static const char* Name() { return "BackgroundGcOption"; } 575aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin}; 576aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 577aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkintemplate <> 578aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkinstruct CmdlineType<LogVerbosity> : CmdlineTypeParser<LogVerbosity> { 579aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin Result Parse(const std::string& options) { 580aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin LogVerbosity log_verbosity = LogVerbosity(); 581aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 582aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin std::vector<std::string> verbose_options; 583aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin Split(options, ',', &verbose_options); 584aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin for (size_t j = 0; j < verbose_options.size(); ++j) { 585aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin if (verbose_options[j] == "class") { 586aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin log_verbosity.class_linker = true; 587a6e1c126299586932ecd3c1133a55a6f8e1107fcMathieu Chartier } else if (verbose_options[j] == "collector") { 588a6e1c126299586932ecd3c1133a55a6f8e1107fcMathieu Chartier log_verbosity.collector = true; 589aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else if (verbose_options[j] == "compiler") { 590aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin log_verbosity.compiler = true; 591f3d1f94cf730948f8978befa7cf60ab28ff0f281Andreas Gampe } else if (verbose_options[j] == "deopt") { 592f3d1f94cf730948f8978befa7cf60ab28ff0f281Andreas Gampe log_verbosity.deopt = true; 593aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else if (verbose_options[j] == "gc") { 594aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin log_verbosity.gc = true; 595aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else if (verbose_options[j] == "heap") { 596aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin log_verbosity.heap = true; 597aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else if (verbose_options[j] == "jdwp") { 598aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin log_verbosity.jdwp = true; 599e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier } else if (verbose_options[j] == "jit") { 600e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier log_verbosity.jit = true; 601aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else if (verbose_options[j] == "jni") { 602aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin log_verbosity.jni = true; 603aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else if (verbose_options[j] == "monitor") { 604aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin log_verbosity.monitor = true; 60566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } else if (verbose_options[j] == "oat") { 60666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler log_verbosity.oat = true; 607aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else if (verbose_options[j] == "profiler") { 608aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin log_verbosity.profiler = true; 609aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else if (verbose_options[j] == "signals") { 610aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin log_verbosity.signals = true; 611751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang } else if (verbose_options[j] == "simulator") { 612751beff19b36f777d9e3a966d754fd9cfad5d534Phil Wang log_verbosity.simulator = true; 613aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else if (verbose_options[j] == "startup") { 614aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin log_verbosity.startup = true; 615aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else if (verbose_options[j] == "third-party-jni") { 616aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin log_verbosity.third_party_jni = true; 617aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else if (verbose_options[j] == "threads") { 618aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin log_verbosity.threads = true; 619aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else if (verbose_options[j] == "verifier") { 620aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin log_verbosity.verifier = true; 621fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier } else if (verbose_options[j] == "image") { 622fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier log_verbosity.image = true; 623fc6898769ae1ef91ec3e41c0a273401213cb82cdAndreas Gampe } else if (verbose_options[j] == "systrace-locks") { 624fc6898769ae1ef91ec3e41c0a273401213cb82cdAndreas Gampe log_verbosity.systrace_lock_logging = true; 625aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else { 626aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return Result::Usage(std::string("Unknown -verbose option ") + verbose_options[j]); 627aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 628aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 629aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 630aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return Result::Success(log_verbosity); 631aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 632aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 633aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin static const char* Name() { return "LogVerbosity"; } 634aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin}; 635aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 636aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin// TODO: Replace with art::ProfilerOptions for the real thing. 637aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkinstruct TestProfilerOptions { 638aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // Whether or not the applications should be profiled. 639aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin bool enabled_; 640aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // Destination file name where the profiling data will be saved into. 641aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin std::string output_file_name_; 642aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // Generate profile every n seconds. 643aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin uint32_t period_s_; 644aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // Run profile for n seconds. 645aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin uint32_t duration_s_; 646aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // Microseconds between samples. 647aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin uint32_t interval_us_; 648aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // Coefficient to exponential backoff. 649aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin double backoff_coefficient_; 650aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // Whether the profile should start upon app startup or be delayed by some random offset. 651aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin bool start_immediately_; 652aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // Top K% of samples that are considered relevant when deciding if the app should be recompiled. 653aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin double top_k_threshold_; 654aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // How much the top K% samples needs to change in order for the app to be recompiled. 655aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin double top_k_change_threshold_; 656aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // The type of profile data dumped to the disk. 657aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin ProfileDataType profile_type_; 658aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // The max depth of the stack collected by the profiler 659aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin uint32_t max_stack_depth_; 660aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 661aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin TestProfilerOptions() : 662aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin enabled_(false), 663aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin output_file_name_(), 664aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin period_s_(0), 665aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin duration_s_(0), 666aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin interval_us_(0), 667aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin backoff_coefficient_(0), 668aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin start_immediately_(0), 669aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin top_k_threshold_(0), 670aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin top_k_change_threshold_(0), 671aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin profile_type_(ProfileDataType::kProfilerMethod), 672aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin max_stack_depth_(0) { 673aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 674aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 675c801f0d79b8c5bf28401a040356b59b2f41520f4Andreas Gampe TestProfilerOptions(const TestProfilerOptions&) = default; 676c801f0d79b8c5bf28401a040356b59b2f41520f4Andreas Gampe TestProfilerOptions(TestProfilerOptions&&) = default; 677aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin}; 678aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 679aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkinstatic inline std::ostream& operator<<(std::ostream& stream, const TestProfilerOptions& options) { 680aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin stream << "TestProfilerOptions {" << std::endl; 681aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 682aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin#define PRINT_TO_STREAM(field) \ 683aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin stream << #field << ": '" << options.field << "'" << std::endl; 684aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 685aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin PRINT_TO_STREAM(enabled_); 686aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin PRINT_TO_STREAM(output_file_name_); 687aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin PRINT_TO_STREAM(period_s_); 688aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin PRINT_TO_STREAM(duration_s_); 689aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin PRINT_TO_STREAM(interval_us_); 690aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin PRINT_TO_STREAM(backoff_coefficient_); 691aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin PRINT_TO_STREAM(start_immediately_); 692aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin PRINT_TO_STREAM(top_k_threshold_); 693aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin PRINT_TO_STREAM(top_k_change_threshold_); 694aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin PRINT_TO_STREAM(profile_type_); 695aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin PRINT_TO_STREAM(max_stack_depth_); 696aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 697aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin stream << "}"; 698aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 699aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return stream; 700aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin#undef PRINT_TO_STREAM 701aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin} 702aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 703aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkintemplate <> 704aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkinstruct CmdlineType<TestProfilerOptions> : CmdlineTypeParser<TestProfilerOptions> { 705aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin using Result = CmdlineParseResult<TestProfilerOptions>; 706aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 707aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin private: 708aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin using StringResult = CmdlineParseResult<std::string>; 709aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin using DoubleResult = CmdlineParseResult<double>; 710aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 711aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin template <typename T> 712aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin static Result ParseInto(TestProfilerOptions& options, 713aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin T TestProfilerOptions::*pField, 714aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin CmdlineParseResult<T>&& result) { 715aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin assert(pField != nullptr); 716aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 717aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin if (result.IsSuccess()) { 718aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin options.*pField = result.ReleaseValue(); 719aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return Result::SuccessNoValue(); 720aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 721aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 722aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return Result::CastError(result); 723aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 724aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 725aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin template <typename T> 726aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin static Result ParseIntoRangeCheck(TestProfilerOptions& options, 727aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin T TestProfilerOptions::*pField, 728aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin CmdlineParseResult<T>&& result, 729aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin T min, 730aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin T max) { 731aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin if (result.IsSuccess()) { 732aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin const T& value = result.GetValue(); 733aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 734aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin if (value < min || value > max) { 735aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin CmdlineParseResult<T> out_of_range = CmdlineParseResult<T>::OutOfRange(value, min, max); 736aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return Result::CastError(out_of_range); 737aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 738aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 739aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 740aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return ParseInto(options, pField, std::forward<CmdlineParseResult<T>>(result)); 741aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 742aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 743aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin static StringResult ParseStringAfterChar(const std::string& s, char c) { 744aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin std::string parsed_value; 745aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 746aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin std::string::size_type colon = s.find(c); 747aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin if (colon == std::string::npos) { 748aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return StringResult::Usage(std::string() + "Missing char " + c + " in option " + s); 749aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 750aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // Add one to remove the char we were trimming until. 751aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin parsed_value = s.substr(colon + 1); 752aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return StringResult::Success(parsed_value); 753aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 754aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 755aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin static std::string RemovePrefix(const std::string& source) { 756aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin size_t prefix_idx = source.find(":"); 757aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 758aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin if (prefix_idx == std::string::npos) { 759aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return ""; 760aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 761aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 762aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return source.substr(prefix_idx + 1); 763aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 764aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 765aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin public: 766aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin Result ParseAndAppend(const std::string& option, TestProfilerOptions& existing) { 767aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // Special case which doesn't include a wildcard argument definition. 768aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // We pass-it through as-is. 769aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin if (option == "-Xenable-profiler") { 770aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin existing.enabled_ = true; 771aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return Result::SuccessNoValue(); 772aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 773aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 774aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin // The rest of these options are always the wildcard from '-Xprofile-*' 775aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin std::string suffix = RemovePrefix(option); 776aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 777aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin if (StartsWith(option, "filename:")) { 778aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin CmdlineType<std::string> type_parser; 779aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 780aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return ParseInto(existing, 781aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin &TestProfilerOptions::output_file_name_, 782aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin type_parser.Parse(suffix)); 783aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else if (StartsWith(option, "period:")) { 784aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin CmdlineType<unsigned int> type_parser; 785aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 786aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return ParseInto(existing, 787aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin &TestProfilerOptions::period_s_, 788aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin type_parser.Parse(suffix)); 789aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else if (StartsWith(option, "duration:")) { 790aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin CmdlineType<unsigned int> type_parser; 791aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 792aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return ParseInto(existing, 793aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin &TestProfilerOptions::duration_s_, 794aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin type_parser.Parse(suffix)); 795aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else if (StartsWith(option, "interval:")) { 796aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin CmdlineType<unsigned int> type_parser; 797aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 798aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return ParseInto(existing, 799aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin &TestProfilerOptions::interval_us_, 800aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin type_parser.Parse(suffix)); 801aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else if (StartsWith(option, "backoff:")) { 802aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin CmdlineType<double> type_parser; 803aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 804aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return ParseIntoRangeCheck(existing, 805aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin &TestProfilerOptions::backoff_coefficient_, 806aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin type_parser.Parse(suffix), 807aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 1.0, 808aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 10.0); 809aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 810aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else if (option == "start-immediately") { 811aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin existing.start_immediately_ = true; 812aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return Result::SuccessNoValue(); 813aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else if (StartsWith(option, "top-k-threshold:")) { 814aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin CmdlineType<double> type_parser; 815aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 816aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return ParseIntoRangeCheck(existing, 817aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin &TestProfilerOptions::top_k_threshold_, 818aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin type_parser.Parse(suffix), 819aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 0.0, 820aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 100.0); 821aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else if (StartsWith(option, "top-k-change-threshold:")) { 822aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin CmdlineType<double> type_parser; 823aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 824aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return ParseIntoRangeCheck(existing, 825aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin &TestProfilerOptions::top_k_change_threshold_, 826aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin type_parser.Parse(suffix), 827aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 0.0, 828aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 100.0); 829aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else if (option == "type:method") { 830aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin existing.profile_type_ = kProfilerMethod; 831aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return Result::SuccessNoValue(); 832aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else if (option == "type:stack") { 833aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin existing.profile_type_ = kProfilerBoundedStack; 834aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return Result::SuccessNoValue(); 835aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else if (StartsWith(option, "max-stack-depth:")) { 836aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin CmdlineType<unsigned int> type_parser; 837aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 838aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return ParseInto(existing, 839aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin &TestProfilerOptions::max_stack_depth_, 840aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin type_parser.Parse(suffix)); 841aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } else { 842aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin return Result::Failure(std::string("Invalid suboption '") + option + "'"); 843aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 844aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin } 845aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 846aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin static const char* Name() { return "TestProfilerOptions"; } 847aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin static constexpr bool kCanParseBlankless = true; 848aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin}; 849aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 850eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Lighttemplate<> 851eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Lightstruct CmdlineType<ExperimentalFlags> : CmdlineTypeParser<ExperimentalFlags> { 852eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light Result ParseAndAppend(const std::string& option, ExperimentalFlags& existing) { 853eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light if (option == "none") { 8549724c636467d56632a45fdf6353e3d57d1925501Neil Fuller existing = ExperimentalFlags::kNone; 855eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light } else if (option == "lambdas") { 856eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light existing = existing | ExperimentalFlags::kLambdas; 857eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light } else { 858eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light return Result::Failure(std::string("Unknown option '") + option + "'"); 859eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light } 860eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light return Result::SuccessNoValue(); 861eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light } 862eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light 863eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light static const char* Name() { return "ExperimentalFlags"; } 864eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light}; 865aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin 866aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin} // namespace art 867aaebaa0121be3b9d9f13630585304482cbcaeb4bIgor Murashkin#endif // ART_CMDLINE_CMDLINE_TYPES_H_ 868