Merge change 20713 into donut

* changes:
  Updated preloaded-classes file.
This commit is contained in:
Android (Google) Code Review
2009-08-11 12:48:36 -07:00
11 changed files with 1582 additions and 312 deletions

View File

@@ -291,6 +291,15 @@ public class ZygoteInit {
} else { } else {
missingClasses += " " + line; missingClasses += " " + line;
} }
} catch (Throwable t) {
Log.e(TAG, "Error preloading " + line + ".", t);
if (t instanceof Error) {
throw (Error) t;
}
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
}
throw new RuntimeException(t);
} }
} }

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -26,7 +26,7 @@ class ClassRank implements Comparator<Operation> {
* Increase this number to add more weight to classes which were loaded * Increase this number to add more weight to classes which were loaded
* earlier. * earlier.
*/ */
static final int SEQUENCE_WEIGHT = 500; // 5 ms static final int SEQUENCE_WEIGHT = 500; // 0.5ms
static final int BUCKET_SIZE = 5; static final int BUCKET_SIZE = 5;

View File

@@ -15,10 +15,7 @@
*/ */
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.*;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
/** /**
* A loaded class. * A loaded class.
@@ -54,7 +51,7 @@ class LoadedClass implements Serializable, Comparable<LoadedClass> {
} }
void measureMemoryUsage() { void measureMemoryUsage() {
this.memoryUsage = MemoryUsage.forClass(name); // this.memoryUsage = MemoryUsage.forClass(name);
} }
int mlt = -1; int mlt = -1;
@@ -102,31 +99,20 @@ class LoadedClass implements Serializable, Comparable<LoadedClass> {
} }
} }
/** /** Returns names of apps that loaded this class. */
* Counts loads by apps. Set<String> applicationNames() {
*/ Set<String> appNames = new HashSet<String>();
int appLoads() { addProcessNames(loads, appNames);
return operationsByApps(loads); addProcessNames(initializations, appNames);
return appNames;
} }
/** private void addProcessNames(List<Operation> ops, Set<String> appNames) {
* Counts inits by apps. for (Operation operation : ops) {
*/
int appInits() {
return operationsByApps(initializations);
}
/**
* Counts number of app operations in the given list.
*/
private static int operationsByApps(List<Operation> operations) {
int byApps = 0;
for (Operation operation : operations) {
if (operation.process.isApplication()) { if (operation.process.isApplication()) {
byApps++; appNames.add(operation.process.name);
} }
} }
return byApps;
} }
public int compareTo(LoadedClass o) { public int compareTo(LoadedClass o) {
@@ -160,4 +146,8 @@ class LoadedClass implements Serializable, Comparable<LoadedClass> {
return false; return false;
} }
public boolean isPreloadable() {
return systemClass && Policy.isPreloadableClass(name);
}
} }

View File

@@ -23,48 +23,33 @@ import java.util.Set;
*/ */
public class Policy { public class Policy {
/**
* No constructor - use static methods only
*/
private Policy() {}
/** /**
* This location (in the build system) of the preloaded-classes file. * This location (in the build system) of the preloaded-classes file.
*/ */
private static final String PRELOADED_CLASS_FILE = "frameworks/base/preloaded-classes"; private static final String PRELOADED_CLASS_FILE
= "frameworks/base/preloaded-classes";
/** /**
* The internal process name of the system process. Note, this also shows up as * Long running services. These are restricted in their contribution to the
* "system_process", e.g. in ddms. * preloader because their launch time is less critical.
*/
private static final String SYSTEM_SERVER_PROCESS_NAME = "system_server";
/**
* Names of non-application processes - these will not be checked for preloaded classes.
*
* TODO: Replace this hardcoded list with a walk up the parent chain looking for zygote.
*/
private static final Set<String> NOT_FROM_ZYGOTE = new HashSet<String>(Arrays.asList(
"zygote",
"dexopt",
"unknown",
SYSTEM_SERVER_PROCESS_NAME,
"com.android.development",
"app_process" // am & other shell commands
));
/**
* Long running services. These are restricted in their contribution to the preloader
* because their launch time is less critical.
*/ */
private static final Set<String> SERVICES = new HashSet<String>(Arrays.asList( private static final Set<String> SERVICES = new HashSet<String>(Arrays.asList(
SYSTEM_SERVER_PROCESS_NAME, "system_server",
"com.android.acore",
// Commented out to make sure DefaultTimeZones gets preloaded.
// "com.android.phone",
"com.google.process.content", "com.google.process.content",
"android.process.media" "android.process.media",
"com.google.process.gapps"
)); ));
/** /**
* Classes which we shouldn't load from the Zygote. * Classes which we shouldn't load from the Zygote.
*/ */
private static final Set<String> EXCLUDED_CLASSES = new HashSet<String>(Arrays.asList( private static final Set<String> EXCLUDED_CLASSES
= new HashSet<String>(Arrays.asList(
// Binders // Binders
"android.app.AlarmManager", "android.app.AlarmManager",
"android.app.SearchManager", "android.app.SearchManager",
@@ -75,14 +60,8 @@ public class Policy {
"android.os.AsyncTask", "android.os.AsyncTask",
"android.pim.ContactsAsyncHelper", "android.pim.ContactsAsyncHelper",
"java.lang.ProcessManager" "java.lang.ProcessManager"
)); ));
/**
* No constructor - use static methods only
*/
private Policy() {}
/** /**
* Returns the path/file name of the preloaded classes file that will be written * Returns the path/file name of the preloaded classes file that will be written
* by WritePreloadedClassFile. * by WritePreloadedClassFile.
@@ -91,13 +70,6 @@ public class Policy {
return PRELOADED_CLASS_FILE; return PRELOADED_CLASS_FILE;
} }
/**
* Reports if a given process name was created from zygote
*/
public static boolean isFromZygote(String processName) {
return !NOT_FROM_ZYGOTE.contains(processName);
}
/** /**
* Reports if the given process name is a "long running" process or service * Reports if the given process name is a "long running" process or service
*/ */

View File

@@ -18,6 +18,9 @@ import java.io.IOException;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.ObjectInputStream; import java.io.ObjectInputStream;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;
import java.util.Set;
import java.util.HashSet;
import java.util.TreeSet;
/** /**
* Prints raw information in CSV format. * Prints raw information in CSV format.
@@ -37,13 +40,14 @@ public class PrintCsv {
+ ",Preloaded" + ",Preloaded"
+ ",Median Load Time (us)" + ",Median Load Time (us)"
+ ",Median Init Time (us)" + ",Median Init Time (us)"
+ ",Process Names"
+ ",Load Count" + ",Load Count"
+ ",Init Count" + ",Init Count");
+ ",Managed Heap (B)" // + ",Managed Heap (B)"
+ ",Native Heap (B)" // + ",Native Heap (B)"
+ ",Managed Pages (kB)" // + ",Managed Pages (kB)"
+ ",Native Pages (kB)" // + ",Native Pages (kB)"
+ ",Other Pages (kB)"); // + ",Other Pages (kB)");
MemoryUsage baseline = root.baseline; MemoryUsage baseline = root.baseline;
@@ -60,10 +64,23 @@ public class PrintCsv {
System.out.print(','); System.out.print(',');
System.out.print(loadedClass.medianInitTimeMicros()); System.out.print(loadedClass.medianInitTimeMicros());
System.out.print(','); System.out.print(',');
System.out.print('"');
Set<String> procNames = new TreeSet<String>();
for (Operation op : loadedClass.loads)
procNames.add(op.process.name);
for (Operation op : loadedClass.initializations)
procNames.add(op.process.name);
for (String name : procNames) {
System.out.print(name + "\n");
}
System.out.print('"');
System.out.print(',');
System.out.print(loadedClass.loads.size()); System.out.print(loadedClass.loads.size());
System.out.print(','); System.out.print(',');
System.out.print(loadedClass.initializations.size()); System.out.print(loadedClass.initializations.size());
/*
if (loadedClass.memoryUsage.isAvailable()) { if (loadedClass.memoryUsage.isAvailable()) {
MemoryUsage subtracted MemoryUsage subtracted
= loadedClass.memoryUsage.subtract(baseline); = loadedClass.memoryUsage.subtract(baseline);
@@ -82,7 +99,7 @@ public class PrintCsv {
} else { } else {
System.out.print(",n/a,n/a,n/a,n/a,n/a"); System.out.print(",n/a,n/a,n/a,n/a,n/a");
} }
*/
System.out.println(); System.out.println();
} }
} }

View File

@@ -14,8 +14,6 @@
* limitations under the License. * limitations under the License.
*/ */
import java.util.Set;
import java.util.HashSet;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.ArrayList; import java.util.ArrayList;
@@ -23,7 +21,6 @@ import java.util.LinkedList;
import java.util.Map; import java.util.Map;
import java.util.HashMap; import java.util.HashMap;
import java.util.Collections; import java.util.Collections;
import java.util.TreeSet;
import java.io.Serializable; import java.io.Serializable;
/** /**
@@ -38,11 +35,6 @@ class Proc implements Serializable {
*/ */
static final int PERCENTAGE_TO_PRELOAD = 75; static final int PERCENTAGE_TO_PRELOAD = 75;
/**
* Maximum number of classes to preload for a given process.
*/
static final int MAX_TO_PRELOAD = 100;
/** Parent process. */ /** Parent process. */
final Proc parent; final Proc parent;
@@ -97,11 +89,9 @@ class Proc implements Serializable {
/** /**
* Returns a list of classes which should be preloaded. * Returns a list of classes which should be preloaded.
*
* @param takeAllClasses forces all classes to be taken (irrespective of ranking)
*/ */
List<LoadedClass> highestRankedClasses(boolean takeAllClasses) { List<LoadedClass> highestRankedClasses() {
if (!isApplication()) { if (!isApplication() || Policy.isService(this.name)) {
return Collections.emptyList(); return Collections.emptyList();
} }
@@ -114,25 +104,13 @@ class Proc implements Serializable {
int timeToSave = totalTimeMicros() * percentageToPreload() / 100; int timeToSave = totalTimeMicros() * percentageToPreload() / 100;
int timeSaved = 0; int timeSaved = 0;
boolean service = Policy.isService(this.name); int count = 0;
List<LoadedClass> highest = new ArrayList<LoadedClass>(); List<LoadedClass> highest = new ArrayList<LoadedClass>();
for (Operation operation : ranked) { for (Operation operation : ranked) {
if (timeSaved >= timeToSave || count++ > 100) {
// These are actual ranking decisions, which can be overridden
if (!takeAllClasses) {
if (highest.size() >= MAX_TO_PRELOAD) {
System.out.println(name + " got "
+ (timeSaved * 100 / timeToSave) + "% through");
break; break;
} }
if (timeSaved >= timeToSave) {
break;
}
}
// The remaining rules apply even to wired-down processes
if (!Policy.isPreloadableClass(operation.loadedClass.name)) { if (!Policy.isPreloadableClass(operation.loadedClass.name)) {
continue; continue;
} }
@@ -141,12 +119,7 @@ class Proc implements Serializable {
continue; continue;
} }
// Only load java.* class for services.
if (!service || operation.loadedClass.name.startsWith("java.")) {
highest.add(operation.loadedClass); highest.add(operation.loadedClass);
}
// For services, still count the time even if it's not in java.*
timeSaved += operation.medianExclusiveTimeMicros(); timeSaved += operation.medianExclusiveTimeMicros();
} }
@@ -166,11 +139,13 @@ class Proc implements Serializable {
/** /**
* Returns true if this process is an app. * Returns true if this process is an app.
*
* TODO: Replace the hardcoded list with a walk up the parent chain looking for zygote.
*/ */
public boolean isApplication() { public boolean isApplication() {
return Policy.isFromZygote(name); if (name.equals("com.android.development")) {
return false;
}
return parent != null && parent.name.equals("zygote");
} }
/** /**

View File

@@ -20,8 +20,6 @@ import java.io.IOException;
import java.io.OutputStreamWriter; import java.io.OutputStreamWriter;
import java.io.Writer; import java.io.Writer;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.TreeSet; import java.util.TreeSet;
@@ -32,71 +30,85 @@ import java.util.TreeSet;
public class WritePreloadedClassFile { public class WritePreloadedClassFile {
public static void main(String[] args) throws IOException, ClassNotFoundException { public static void main(String[] args) throws IOException, ClassNotFoundException {
if (args.length != 1) {
// Process command-line arguments first System.err.println("Usage: WritePreloadedClassFile [compiled log]");
List<String> wiredProcesses = new ArrayList<String>(); System.exit(-1);
String inputFileName = null;
int argOffset = 0;
try {
while ("--preload-all-process".equals(args[argOffset])) {
argOffset++;
wiredProcesses.add(args[argOffset++]);
} }
String rootFile = args[0];
Root root = Root.fromFile(rootFile);
inputFileName = args[argOffset++]; // No classes are preloaded to start.
} catch (RuntimeException e) {
System.err.println("Usage: WritePreloadedClassFile " +
"[--preload-all-process process-name] " +
"[compiled log file]");
System.exit(0);
}
Root root = Root.fromFile(inputFileName);
for (LoadedClass loadedClass : root.loadedClasses.values()) { for (LoadedClass loadedClass : root.loadedClasses.values()) {
loadedClass.preloaded = false; loadedClass.preloaded = false;
} }
// Open preloaded-classes file for output.
Writer out = new BufferedWriter(new OutputStreamWriter( Writer out = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(Policy.getPreloadedClassFileName()), new FileOutputStream(Policy.getPreloadedClassFileName()),
Charset.forName("US-ASCII"))); Charset.forName("US-ASCII")));
out.write("# Classes which are preloaded by com.android.internal.os.ZygoteInit.\n"); out.write("# Classes which are preloaded by com.android.internal.os.ZygoteInit.\n");
out.write("# Automatically generated by /frameworks/base/tools/preload.\n"); out.write("# Automatically generated by /frameworks/base/tools/preload.\n");
out.write("# percent=" + Proc.PERCENTAGE_TO_PRELOAD + ", weight=" out.write("# percent=" + Proc.PERCENTAGE_TO_PRELOAD
+ ClassRank.SEQUENCE_WEIGHT + ", weight=" + ClassRank.SEQUENCE_WEIGHT
+ ", bucket_size=" + ClassRank.BUCKET_SIZE + ", bucket_size=" + ClassRank.BUCKET_SIZE
+ "\n"); + "\n");
for (String wiredProcess : wiredProcesses) {
out.write("# forcing classes loaded by: " + wiredProcess + "\n"); Set<LoadedClass> toPreload = new TreeSet<LoadedClass>();
// Preload all classes that were loaded by at least 2 apps, if both
// apps run at the same time, they'll share memory.
for (LoadedClass loadedClass : root.loadedClasses.values()) {
if (!loadedClass.isPreloadable()) {
continue;
} }
Set<LoadedClass> highestRanked = new TreeSet<LoadedClass>(); Set<String> appNames = loadedClass.applicationNames();
if (appNames.size() > 3) {
toPreload.add(loadedClass);
}
}
// Try to make individual apps start faster by preloading slowest
// classes.
for (Proc proc : root.processes.values()) { for (Proc proc : root.processes.values()) {
// test to see if this is one of the wired-down ("take all classes") processes toPreload.addAll(proc.highestRankedClasses());
boolean isWired = wiredProcesses.contains(proc.name);
List<LoadedClass> highestForProc = proc.highestRankedClasses(isWired);
System.out.println(proc.name + ": " + highestForProc.size());
for (LoadedClass loadedClass : highestForProc) {
loadedClass.preloaded = true;
}
highestRanked.addAll(highestForProc);
} }
for (LoadedClass loadedClass : highestRanked) { System.out.println(toPreload.size() + " classes will be preloaded.");
// Make classes that were already loaded by the zygote explicit.
// This adds minimal overhead but avoid confusion about classes not
// appearing in the list.
addAllClassesFor("zygote", root, toPreload);
for (LoadedClass loadedClass : toPreload) {
out.write(loadedClass.name); out.write(loadedClass.name);
out.write('\n'); out.write('\n');
} }
out.close(); out.close();
System.out.println(highestRanked.size()
+ " classes will be preloaded.");
// Update data to reflect LoadedClass.preloaded changes. // Update data to reflect LoadedClass.preloaded changes.
root.toFile(inputFileName); for (LoadedClass loadedClass : toPreload) {
loadedClass.preloaded = true;
}
root.toFile(rootFile);
}
private static void addAllClassesFor(String packageName, Root root,
Set<LoadedClass> toPreload) {
for (Proc proc : root.processes.values()) {
if (proc.name.equals(packageName)) {
for (Operation operation : proc.operations) {
// TODO: I'm not sure how the zygote loaded classes that
// aren't supposed to be preloadable...
if (operation.loadedClass.isPreloadable()) {
toPreload.add(operation.loadedClass);
}
}
}
}
} }
} }

View File

@@ -1,15 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<module relativePaths="true" type="JAVA_MODULE" version="4"> <module relativePaths="true" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="false"> <component name="NewModuleRootManager" inherit-compiler-output="false">
<output url="file:///tmp/preload/" /> <output url="file:///tmp/preload" />
<output-test url="file:///tmp/preload" />
<exclude-output /> <exclude-output />
<output-test url="file:///tmp/preload/" />
<content url="file://$MODULE_DIR$"> <content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$" isTestSource="false" />
</content> </content>
<orderEntry type="inheritedJdk" /> <orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
<orderEntryProperties />
</component> </component>
</module> </module>

View File

@@ -114,6 +114,7 @@
<option name="ADDITIONAL_OPTIONS_STRING" value="" /> <option name="ADDITIONAL_OPTIONS_STRING" value="" />
<option name="MAXIMUM_HEAP_SIZE" value="128" /> <option name="MAXIMUM_HEAP_SIZE" value="128" />
</component> </component>
<component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
<component name="EntryPointsManager"> <component name="EntryPointsManager">
<entry_points version="2.0" /> <entry_points version="2.0" />
</component> </component>
@@ -125,13 +126,13 @@
<component name="IdProvider" IDEtalkID="D171F99B9178C1675593DC9A76A5CC7E" /> <component name="IdProvider" IDEtalkID="D171F99B9178C1675593DC9A76A5CC7E" />
<component name="InspectionProjectProfileManager"> <component name="InspectionProjectProfileManager">
<option name="PROJECT_PROFILE" value="Project Default" /> <option name="PROJECT_PROFILE" value="Project Default" />
<option name="USE_PROJECT_LEVEL_SETTINGS" value="false" /> <option name="USE_PROJECT_PROFILE" value="true" />
<scopes /> <version value="1.0" />
<profiles> <profiles>
<profile version="1.0" is_locked="false"> <profile version="1.0" is_locked="false">
<option name="myName" value="Project Default" /> <option name="myName" value="Project Default" />
<option name="myLocal" value="false" /> <option name="myLocal" value="false" />
<inspection_tool class="JavaDoc" level="WARNING" enabled="false"> <inspection_tool class="JavaDoc" enabled="false" level="WARNING" enabled_by_default="false">
<option name="TOP_LEVEL_CLASS_OPTIONS"> <option name="TOP_LEVEL_CLASS_OPTIONS">
<value> <value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" /> <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
@@ -160,14 +161,19 @@
<option name="IGNORE_JAVADOC_PERIOD" value="true" /> <option name="IGNORE_JAVADOC_PERIOD" value="true" />
<option name="myAdditionalJavadocTags" value="" /> <option name="myAdditionalJavadocTags" value="" />
</inspection_tool> </inspection_tool>
<inspection_tool class="OnDemandImport" level="WARNING" enabled="true" /> <inspection_tool class="JavaLangImport" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="SamePackageImport" level="WARNING" enabled="true" /> <inspection_tool class="OnDemandImport" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="JavaLangImport" level="WARNING" enabled="true" /> <inspection_tool class="RedundantImport" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="RedundantImport" level="WARNING" enabled="true" /> <inspection_tool class="SamePackageImport" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="UnusedImport" level="WARNING" enabled="true" /> <inspection_tool class="UnusedImport" enabled="true" level="WARNING" enabled_by_default="true" />
</profile> </profile>
</profiles> </profiles>
<list size="0" /> <list size="4">
<item index="0" class="java.lang.String" itemvalue="WARNING" />
<item index="1" class="java.lang.String" itemvalue="SERVER PROBLEM" />
<item index="2" class="java.lang.String" itemvalue="INFO" />
<item index="3" class="java.lang.String" itemvalue="ERROR" />
</list>
</component> </component>
<component name="JavacSettings"> <component name="JavacSettings">
<option name="DEBUGGING_INFO" value="true" /> <option name="DEBUGGING_INFO" value="true" />
@@ -332,13 +338,19 @@
<option name="USE_CLIENT_FILTER" value="true" /> <option name="USE_CLIENT_FILTER" value="true" />
<option name="CLIENT" value="" /> <option name="CLIENT" value="" />
</component> </component>
<component name="ProjectDetails">
<option name="projectName" value="preload" />
</component>
<component name="ProjectFileVersion" converted="true" /> <component name="ProjectFileVersion" converted="true" />
<component name="ProjectKey">
<option name="state" value="project:///Volumes/Android/donut/frameworks/base/tools/preload/preload.ipr" />
</component>
<component name="ProjectModuleManager"> <component name="ProjectModuleManager">
<modules> <modules>
<module fileurl="file://$PROJECT_DIR$/preload.iml" filepath="$PROJECT_DIR$/preload.iml" /> <module fileurl="file://$PROJECT_DIR$/preload.iml" filepath="$PROJECT_DIR$/preload.iml" />
</modules> </modules>
</component> </component>
<component name="ProjectRootManager" version="2" assert-keyword="true" jdk-15="true" project-jdk-name="1.5" project-jdk-type="JavaSDK"> <component name="ProjectRootManager" version="2" languageLevel="JDK_1_5" assert-keyword="true" jdk-15="true" project-jdk-name="1.5" project-jdk-type="JavaSDK">
<output url="file:///tmp/preload" /> <output url="file:///tmp/preload" />
</component> </component>
<component name="RmicSettings"> <component name="RmicSettings">
@@ -374,6 +386,9 @@
<option name="myValidatorValidationEnabled" value="true" /> <option name="myValidatorValidationEnabled" value="true" />
<option name="myReportErrorsAsWarnings" value="true" /> <option name="myReportErrorsAsWarnings" value="true" />
</component> </component>
<component name="SvnBranchConfigurationManager">
<option name="mySupportsUserInfoFilter" value="true" />
</component>
<component name="SvnChangesBrowserSettings"> <component name="SvnChangesBrowserSettings">
<option name="USE_AUTHOR_FIELD" value="true" /> <option name="USE_AUTHOR_FIELD" value="true" />
<option name="AUTHOR" value="" /> <option name="AUTHOR" value="" />
@@ -381,15 +396,6 @@
<option name="USE_PROJECT_SETTINGS" value="true" /> <option name="USE_PROJECT_SETTINGS" value="true" />
<option name="USE_ALTERNATE_LOCATION" value="false" /> <option name="USE_ALTERNATE_LOCATION" value="false" />
</component> </component>
<component name="SvnConfiguration">
<option name="USER" value="" />
<option name="PASSWORD" value="" />
<option name="PROCESS_UNRESOLVED" value="false" />
<option name="LAST_MERGED_REVISION" />
<option name="UPDATE_RUN_STATUS" value="false" />
<option name="UPDATE_RECURSIVELY" value="true" />
<option name="MERGE_DRY_RUN" value="false" />
</component>
<component name="VCS.FileViewConfiguration"> <component name="VCS.FileViewConfiguration">
<option name="SELECTED_STATUSES" value="DEFAULT" /> <option name="SELECTED_STATUSES" value="DEFAULT" />
<option name="SELECTED_COLUMNS" value="DEFAULT" /> <option name="SELECTED_COLUMNS" value="DEFAULT" />