diff --git a/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/SaveManager.java b/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/SaveManager.java index b666609579b..2f1505715a7 100644 --- a/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/SaveManager.java +++ b/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/SaveManager.java @@ -66,6 +66,7 @@ import org.eclipse.core.internal.localstore.SafeChunkyOutputStream; import org.eclipse.core.internal.localstore.SafeFileInputStream; import org.eclipse.core.internal.localstore.SafeFileOutputStream; +import org.eclipse.core.internal.runtime.StartupTrace; import org.eclipse.core.internal.utils.IStringPoolParticipant; import org.eclipse.core.internal.utils.Messages; import org.eclipse.core.internal.utils.Policy; @@ -790,6 +791,7 @@ protected void resetSnapshots(IResource resource) throws CoreException { * which were open when it was last saved. */ protected void restore(IProgressMonitor monitor) throws CoreException { + long tRestore = StartupTrace.begin(); if (Policy.DEBUG_RESTORE) { Policy.debug("Restore workspace: starting..."); //$NON-NLS-1$ } @@ -804,29 +806,44 @@ protected void restore(IProgressMonitor monitor) throws CoreException { String msg = Messages.resources_startupProblems; MultiStatus problems = new MultiStatus(ResourcesPlugin.PI_RESOURCES, IResourceStatus.FAILED_READ_METADATA, msg, null); + long t; + t = StartupTrace.begin(); restoreMasterTable(); + StartupTrace.record("SaveManager.restore/restoreMasterTable", t); //$NON-NLS-1$ // restore the saved tree and overlay the snapshots if any + t = StartupTrace.begin(); restoreTree(Policy.subMonitorFor(monitor, 10)); + StartupTrace.record("SaveManager.restore/restoreTree", t); //$NON-NLS-1$ + t = StartupTrace.begin(); restoreSnapshots(Policy.subMonitorFor(monitor, 10)); + StartupTrace.record("SaveManager.restore/restoreSnapshots", t); //$NON-NLS-1$ // tolerate failure for non-critical information // if startup fails, the entire workspace is shot + t = StartupTrace.begin(); try { restoreMarkers(workspace.getRoot(), false, Policy.subMonitorFor(monitor, 10)); } catch (CoreException e) { problems.merge(e.getStatus()); } + StartupTrace.record("SaveManager.restore/restoreMarkers", t); //$NON-NLS-1$ + t = StartupTrace.begin(); try { restoreSyncInfo(workspace.getRoot(), Policy.subMonitorFor(monitor, 10)); } catch (CoreException e) { problems.merge(e.getStatus()); } + StartupTrace.record("SaveManager.restore/restoreSyncInfo", t); //$NON-NLS-1$ // restore meta info last because it might close a project if its description is not readable + t = StartupTrace.begin(); restoreMetaInfo(problems, Policy.subMonitorFor(monitor, 10)); + StartupTrace.record("SaveManager.restore/restoreMetaInfo", t); //$NON-NLS-1$ + t = StartupTrace.begin(); IProject[] roots = workspace.getRoot().getProjects(IContainer.INCLUDE_HIDDEN); for (IProject root : roots) { ((Project) root).startup(); } + StartupTrace.record("SaveManager.restore/project.startup(all)", t); //$NON-NLS-1$ if (!problems.isOK()) { Policy.log(problems); } @@ -835,6 +852,7 @@ protected void restore(IProgressMonitor monitor) throws CoreException { } } finally { monitor.done(); + StartupTrace.record("SaveManager.restore(total)", tRestore); //$NON-NLS-1$ } if (Policy.DEBUG_RESTORE) { Policy.debug("Restore workspace: " + (System.currentTimeMillis() - start) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$ @@ -923,7 +941,9 @@ protected void restoreMarkers(IResource resource, boolean generateDeltas, IProgr MarkerManager markerManager = workspace.getMarkerManager(); // when restoring a project, only load markers if it is open if (resource.isAccessible()) { + long tRoot = StartupTrace.begin(); markerManager.restore(resource, generateDeltas, monitor); + StartupTrace.record("SaveManager.restore/restoreMarkers/readSnapshot", tRoot); //$NON-NLS-1$ } // if we have the workspace root then restore markers for its projects @@ -934,11 +954,13 @@ protected void restoreMarkers(IResource resource, boolean generateDeltas, IProgr return; } IProject[] projects = ((IWorkspaceRoot) resource).getProjects(IContainer.INCLUDE_HIDDEN); + long tLoop = StartupTrace.begin(); for (IProject project : projects) { if (project.isAccessible()) { markerManager.restore(project, generateDeltas, monitor); } } + StartupTrace.record("SaveManager.restore/restoreMarkers/readDelta(count=" + projects.length + ")", tLoop); //$NON-NLS-1$ //$NON-NLS-2$ if (Policy.DEBUG_RESTORE_MARKERS) { Policy.debug("Restore Markers for workspace: " + (System.currentTimeMillis() - start) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$ } @@ -977,6 +999,7 @@ protected void restoreMetaInfo(MultiStatus problems, IProgressMonitor monitor) { } long start = System.currentTimeMillis(); IProject[] roots = workspace.getRoot().getProjects(IContainer.INCLUDE_HIDDEN); + long tLoop = StartupTrace.begin(); for (IProject root : roots) { //fatal to throw exceptions during startup try { @@ -986,6 +1009,7 @@ protected void restoreMetaInfo(MultiStatus problems, IProgressMonitor monitor) { problems.merge(new ResourceStatus(IResourceStatus.FAILED_READ_METADATA, root.getFullPath(), message, e)); } } + StartupTrace.record("SaveManager.restore/restoreMetaInfo/loadMetaInfo(count=" + roots.length + ")", tLoop); //$NON-NLS-1$ //$NON-NLS-2$ if (Policy.DEBUG_RESTORE_METAINFO) { Policy.debug("Restore workspace metainfo: " + (System.currentTimeMillis() - start) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$ } @@ -1160,8 +1184,12 @@ protected void restoreTree(IProgressMonitor monitor) throws CoreException { savedStates = Collections.synchronizedMap(new HashMap<>(10)); return; } + long tOpen = StartupTrace.begin(); try (DataInputStream input = new DataInputStream(new SafeFileInputStream(treeLocation.toOSString(), tempLocation.toOSString(), TREE_BUFFER_SIZE))) { + StartupTrace.record("SaveManager.restore/restoreTree/open DataInputStream", tOpen); //$NON-NLS-1$ + long tRead = StartupTrace.begin(); WorkspaceTreeReader.getReader(workspace, input.readInt()).readTree(input, monitor); + StartupTrace.record("SaveManager.restore/restoreTree/readTree (ElementTreeReader)", tRead); //$NON-NLS-1$ } catch (Exception e) { // "Unknown format" is passed as ResourceException String msg = NLS.bind(Messages.resources_readMeta, treeLocation.toOSString()); throw new ResourceException(IResourceStatus.FAILED_READ_METADATA, treeLocation, msg, e); diff --git a/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/Workspace.java b/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/Workspace.java index 690cb8fe72e..20ac7c5c686 100644 --- a/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/Workspace.java +++ b/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/Workspace.java @@ -65,6 +65,7 @@ import org.eclipse.core.internal.refresh.RefreshManager; import org.eclipse.core.internal.resources.ComputeProjectOrder.Digraph; import org.eclipse.core.internal.resources.ComputeProjectOrder.VertexOrder; +import org.eclipse.core.internal.runtime.StartupTrace; import org.eclipse.core.internal.utils.BitMask; import org.eclipse.core.internal.utils.Messages; import org.eclipse.core.internal.utils.Policy; @@ -2342,6 +2343,7 @@ protected long nextNodeId() { * @see ResourcesPlugin#getWorkspace() */ public IStatus open(IProgressMonitor monitor) throws CoreException { + long tOpen = StartupTrace.begin(); if (!localMetaArea.hasSavedWorkspace()) { localMetaArea.createMetaArea(); } @@ -2359,29 +2361,42 @@ public IStatus open(IProgressMonitor monitor) throws CoreException { // Set explicit workspace encoding if no projects exist in the workspace if (!localMetaArea.hasSavedProjects()) { + long tEnc = StartupTrace.begin(); setExplicitWorkspaceEncoding(); + StartupTrace.record("Workspace.open/setExplicitWorkspaceEncoding", tEnc); //$NON-NLS-1$ } + long tPrefOrder = StartupTrace.begin(); initializePreferenceLookupOrder(); + StartupTrace.record("Workspace.open/initializePreferenceLookupOrder", tPrefOrder); //$NON-NLS-1$ // create root location localMetaArea.locationFor(getRoot()).toFile().mkdirs(); + long tStartup = StartupTrace.begin(); startup(new NullProgressMonitor()); + StartupTrace.record("Workspace.open/startup", tStartup); //$NON-NLS-1$ // restart the notification manager so it is initialized with the right tree + long tNotif = StartupTrace.begin(); notificationManager.startup(null); + StartupTrace.record("Workspace.open/notificationManager.startup(restart)", tNotif); //$NON-NLS-1$ openFlag = true; if (crashed || refreshRequested()) { + long tRefresh = StartupTrace.begin(); try { refreshManager.refresh(getRoot()); } catch (RuntimeException e) { + StartupTrace.record("Workspace.open/crashRecoveryRefresh", tRefresh); //$NON-NLS-1$ + StartupTrace.record("Workspace.open", tOpen); //$NON-NLS-1$ //don't fail entire open if refresh failed, just report as warning return new ResourceStatus(IResourceStatus.INTERNAL_ERROR, IPath.ROOT, Messages.resources_errorMultiRefresh, e); } + StartupTrace.record("Workspace.open/crashRecoveryRefresh", tRefresh); //$NON-NLS-1$ } //finally register a string pool participant stringPoolJob = new StringPoolJob(); stringPoolJob.addStringPoolParticipant(saveManager, getRoot()); + StartupTrace.record("Workspace.open", tOpen); //$NON-NLS-1$ return Status.OK_STATUS; } @@ -2654,45 +2669,76 @@ public String[] sortNatureSet(String[] natureIds) { * Starts all the workspace manager classes. */ protected void startup(IProgressMonitor monitor) throws CoreException { + long tAll = StartupTrace.begin(); // ensure the tree is locked during the startup notification try { + long t; + t = StartupTrace.begin(); _workManager = new WorkManager(this); _workManager.startup(null); + StartupTrace.record("Workspace.startup/WorkManager", t); //$NON-NLS-1$ + t = StartupTrace.begin(); fileSystemManager = new FileSystemResourceManager(this); fileSystemManager.startup(monitor); + StartupTrace.record("Workspace.startup/FileSystemResourceManager", t); //$NON-NLS-1$ + t = StartupTrace.begin(); pathVariableManager = new PathVariableManager(); pathVariableManager.startup(null); + StartupTrace.record("Workspace.startup/PathVariableManager", t); //$NON-NLS-1$ + t = StartupTrace.begin(); natureManager = new NatureManager(this); natureManager.startup(null); + StartupTrace.record("Workspace.startup/NatureManager", t); //$NON-NLS-1$ + t = StartupTrace.begin(); filterManager = new FilterTypeManager(); filterManager.startup(null); + StartupTrace.record("Workspace.startup/FilterTypeManager", t); //$NON-NLS-1$ + t = StartupTrace.begin(); buildManager = new BuildManager(this, getWorkManager().getLock()); buildManager.startup(null); + StartupTrace.record("Workspace.startup/BuildManager", t); //$NON-NLS-1$ + t = StartupTrace.begin(); notificationManager = new NotificationManager(this); notificationManager.startup(null); + StartupTrace.record("Workspace.startup/NotificationManager", t); //$NON-NLS-1$ + t = StartupTrace.begin(); markerManager = new MarkerManager(this); markerManager.startup(null); + StartupTrace.record("Workspace.startup/MarkerManager", t); //$NON-NLS-1$ + t = StartupTrace.begin(); synchronizer = new Synchronizer(this); saveManager = new SaveManager(this); saveManager.startup(null); + StartupTrace.record("Workspace.startup/SaveManager", t); //$NON-NLS-1$ + t = StartupTrace.begin(); propertyManager = new PropertyManager2(this); propertyManager.startup(monitor); + StartupTrace.record("Workspace.startup/PropertyManager2", t); //$NON-NLS-1$ + t = StartupTrace.begin(); charsetManager = new CharsetManager(this); charsetManager.startup(null); + StartupTrace.record("Workspace.startup/CharsetManager", t); //$NON-NLS-1$ + t = StartupTrace.begin(); contentDescriptionManager = new ContentDescriptionManager(this); contentDescriptionManager.startup(null); + StartupTrace.record("Workspace.startup/ContentDescriptionManager", t); //$NON-NLS-1$ //must start after save manager, because (read) access to tree is needed //must start after other managers to avoid potential cyclic dependency on uninitialized managers (see bug 316182) //must start before alias manager (see bug 94829) + t = StartupTrace.begin(); refreshManager = new RefreshManager(this); refreshManager.startup(null); + StartupTrace.record("Workspace.startup/RefreshManager", t); //$NON-NLS-1$ //must start at the end to avoid potential cyclic dependency on other uninitialized managers (see bug 369177) + t = StartupTrace.begin(); aliasManager = new AliasManager(this); aliasManager.startup(null); + StartupTrace.record("Workspace.startup/AliasManager", t); //$NON-NLS-1$ } finally { //unlock tree even in case of failure, otherwise shutdown will also fail treeLocked = null; _workManager.postWorkspaceStartup(); + StartupTrace.record("Workspace.startup(total)", tAll); //$NON-NLS-1$ } } diff --git a/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/resources/IResourceChangeEvent.java b/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/resources/IResourceChangeEvent.java index b4d0d30fb93..2d4ad4be70f 100644 --- a/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/resources/IResourceChangeEvent.java +++ b/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/resources/IResourceChangeEvent.java @@ -18,7 +18,7 @@ /** * Resource change events describe changes to resources. *

- * There are currently five different types of resource change events: + * The following types of resource change events are reported: *