8201492: Properly implement non-contiguous generations for Reference discovery
Summary: Collectors like G1 implementing non-contiguous generations previously used an inexact but conservative area for discovery. Concurrent and STW reference processing could discover the same reference multiple times, potentially missing referents during evacuation. So these collectors had to take extra measures while concurrent marking/reference discovery has been running. This change makes discovery exact for G1 (and any collector using non-contiguous generations) so that concurrent discovery and STW discovery discover on strictly disjoint memory areas. This means that the mentioned situation can not occur any more, and extra work is not required any more too.
Reviewed-by: kbarrett, sjohanss
#
# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Oracle designates this
# particular file as subject to the "Classpath" exception as provided
# by Oracle in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
default: all
include $(SPEC)
include MakeBase.gmk
$(eval $(call IncludeCustomExtension, SourceRevision.gmk))
################################################################################
# Keep track of what source revision is used to create the build, by creating
# a tracker file in the output directory. This tracker file is included in the
# image, and can be used to recreate the source revision used.
#
# We're either building directly from a mercurial forest, and if so, use the
# current revision from mercurial. Otherwise, we are building from a source
# bundle. As a part of creating this source bundle, the current mercurial
# revisions of all repos will be stored in a file in the top dir, which is then
# used when creating the tracker file.
STORED_SOURCE_REVISION := $(TOPDIR)/.src-rev
# Are we using mercurial?
ifneq ($(and $(HG), $(wildcard $(TOPDIR)/.hg)), )
# Verify that the entire forest is consistent
$(foreach repo, $(call FindAllReposRel), \
$(if $(wildcard $(TOPDIR)/$(repo)/.hg),, \
$(error Inconsistent revision control: $(repo) is missing .hg directory)) \
)
# Replace "." with "_top" and "/" with "-"
MakeFilenameFromRepo = \
$(strip $(subst .,top, $(subst /,-, $1)))
################################################################################
# SetupGetRevisionForRepo defines a make rule for creating a file containing
# the name of the repository and the output of "hg id" for that repository.
# Argument 1 is the relative path to the repository from the top dir.
#
SetupGetRevisionForRepo = $(NamedParamsMacroTemplate)
define SetupGetRevisionForRepoBody
$1_REPO_PATH := $$(TOPDIR)/$$(strip $1)
$1_FILENAME := $$(call MakeFilenameFromRepo, $1)
$$(SUPPORT_OUTPUTDIR)/src-rev/$$($1_FILENAME): FRC
$$(call MakeDir, $$(@D))
$$(ECHO) $$(strip $1):`$$(HG) id -i --repository $$($1_REPO_PATH)` > $$@
REPO_REVISIONS += $$(SUPPORT_OUTPUTDIR)/src-rev/$$($1_FILENAME)
endef
# Setup rules for all repos. This makes sure all the "hg id" calls are made
# in parallel.
$(foreach repo, $(call FindAllReposRel), \
$(eval $(call SetupGetRevisionForRepo, $(repo))) \
)
# Create a complete source revision output file from all repos
# Param 1: The output file
define CreateSourceRevisionFile
$1: $$(REPO_REVISIONS)
$$(call MakeDir, $$(@D))
$$(ECHO) `$$(CAT) $$(REPO_REVISIONS)` > $$@.tmp
if [ ! -f $$@ ] || [ "`$$(CAT) $$@`" != "`$$(CAT) $$@.tmp`" ]; then \
$$(MV) $$@.tmp $$@ ; \
else \
$$(RM) $$@.tmp ; \
fi
endef
$(eval $(call CreateSourceRevisionFile, $(STORED_SOURCE_REVISION)))
store-source-revision: $(STORED_SOURCE_REVISION)
$(eval $(call CreateSourceRevisionFile, $(SOURCE_REVISION_TRACKER)))
create-source-revision-tracker: $(SOURCE_REVISION_TRACKER)
else
# Not using HG
ifneq ($(wildcard $(STORED_SOURCE_REVISION)), )
# We have a stored source revision (.src-rev)
store-source-revision:
$(call LogInfo, No mercurial configuration present$(COMMA) not updating .src-rev)
$(SOURCE_REVISION_TRACKER): $(STORED_SOURCE_REVISION)
$(install-file)
create-source-revision-tracker: $(SOURCE_REVISION_TRACKER)
else
# We don't have a stored source revision. Can't do anything, really.
store-source-revision:
$(call LogWarn, Error: No mercurial configuration present$(COMMA) cannot create .src-rev)
exit 2
create-source-revision-tracker:
$(call LogWarn, Warning: No mercurial configuration present and no .src-rev)
endif
endif
all: store-source-revision create-source-revision-tracker
FRC: # Force target
.PHONY: all store-source-revision create-source-revision-tracker