README.txt
author jrose
Wed Nov 25 12:52:40 2009 -0800 (3 months ago)
changeset 34 1317d1aa6fdf
parent 297c3f96e3b7f0
permissions -rw-r--r--
include instructions for refreshing patches and sources
        1 OpenJDK Multi-Language VM: The Da Vinci Machine Project
        2 
        3 This is a Mercurial patch repository.
        4 
        5   See http://openjdk.java.net/ for more information about the OpenJDK.
        6 
        7   See http://openjdk.java.net/projects/mlvm/ for more information
        8   about the Da Vinci Machine Project.
        9 
       10   See also the wiki at http://wikis.sun.com/display/mlvm/Home .
       11 
       12 == Organization
       13 
       14 The OpenJDK mlvm/mlvm repository forest is (at present) only a set of patches, not a full set of JDK sources.  The patches apply to some version of the full OpenJDK forest structure.  The structure of the mlvm forest parallels the structure of the full jdk7 sources, but each repository in mvlm is only the .hg/patches directory (of the Mercurial mq extension).  Thus, repositories under mlvm are called "patch repositories" and those under jdk7 are by contrast called "source repositories".
       15 
       16 Commits in the mlvm repositories do not update the full source trees, only the patches.  To make this clear, when a commit occurs in a patch repository, we will refer to it specifically as a "patch commit".
       17 
       18 === Patches
       19 
       20 Make sure you have enabled the Mercurial mq extension with the following lines in your ".hgrc" file:
       21 	[extensions] 
       22 	mq =
       23 
       24 All patch files must end with the suffix ".patch".
       25 
       26 Patches must not have patch headers, since they are easy to lose if patches are regenerated.
       27 
       28 All patches must be in "git" format, without file dates.  To ensure this, add the following lines to your ".hgrc" file:
       29 	[diff]
       30 	nodates=1
       31 	git=1
       32 
       33 A patch file may be accompanied by a similar file with the suffix ".txt".  This file will contain brief comments about the patch, including:
       34 * references to project documentation, if needed
       35 * draft commit comments
       36 * dependencies on other patches
       37 
       38 Patch repositories may also contain scripts and documentation.  All these non-patch files are ignored by the Mercurial patch queue, since they do not appear in the series file.
       39 
       40 Patches may be split.  Files that contribute to a split patch must all have the same prefix up to the first dot.
       41 
       42 Patches may depend on each other.  (For example, invoke dynamic may depend on method handles, which in turn may depend on anonymous classes.)  Such dependencies should be clearly stated.
       43 
       44 The patch sequence is ordered by both stability and by dependency.  If patch B is less stable than patch A, then B should come later in the series.  If B depends on A, it also must come later in the series, and A must not be less stable than B.
       45 
       46 Patches of the same name in multiple patch repositories (hotspot and jdk) are to be applied simultaneously to parallel source repositories.  Their series file elements must be kept exactly in sync.  The documenting text file for a patch does not need to be on both sides, and should not be duplicated.
       47 
       48 === Patch Guards
       49 
       50 The series file contains guard annotations for each patch.  Patches are guarded with Mercurial revision hashes that they are known apply to.  (They may additionally be guarded with OpenJDK release tags or other tags.)  In this way, as the OpenJDK repositories advance, patches can be rebased independently from each other.
       51 
       52 Each patch must have one or more positive guards.  At least one guard must be a twelve-digit hexadecimal mercurial revision hash, such as "7836be3e92d0".  If a patch is guarded by such a revision, it is guaranteed to apply, without rejects, to that particular OpenJDK build.  It will also build successfully (unless it is marked non-buildable, via a #-buildable guard).
       53 
       54 Other tags may be present, especially tags of OpenJDK builds, such as "jdk7-b25".  As it happens, "7836be3e92d0" and "jdk7-b25" refer to the same revision in the hotspot repository.  These symbolic tags are informational and approximate, and (being less accurate than hashes) do not guarantee clean application of patches.
       55 
       56 Each patch must have a negative guard which names that patch with a "slash" prefix.  This allows developers to control individual entries in the patch queue without editing the series file.  Editing the series file is risky, since it is under version control and shared by all developers.  By contrast, the guards file is not under version control.
       57 
       58 The following guards are also significant as negative guards on patches which do not yet have the relevant quality level:
       59 * #-buildable: the patch does not build, or iterferes with the operation of the JVM
       60 * #-testable: the patch fails to have a working test suite
       61 
       62 For normal development, the guards 'buildable' and 'testable' should be present in the guard file, as well as the OpenJDK release in use.
       63 
       64 Example series file contents:
       65 	# base = 05f8c84c5daa in http://hg.openjdk.java.net/bsd-port/bsd-port/hotspot
       66 	anonk.patch #-/anonk #+05f8c84c5daa
       67 	meth.patch  #-/meth  #+05f8c84c5daa
       68 
       69 The 'qselect' command can be used to control these patches:
       70 	hg qselect 05f8c84c5daa  # select both patches
       71 	hg qselect 05f8c84c5daa /meth  # select anonk but not meth
       72 
       73 The first line of each series file must contain a twelve-digit hexadecimal number, which declares the base Mercurial revision for the patch series as a whole.  The script patches/make/current-release.sh will scan this revision automatically.  By convention, the first line of the series file can be a handy human-readable description of that base.  If it were missing, the hexadecimal number would be extracted from the tag on the first patch in the series.
       74 
       75 When any patch is rebased, the commit which updates the patch must also update patch's guard in the series file also.  This should be done a special "rebasing patch commit" which is distinct from actual development.  Actual development occur in patch commits that are *not* rebasing.
       76 
       77 References:
       78 * more on guards: http://hgbook.red-bean.com/hgbookch13.html
       79 * patch rebasing procedures: http://www.selenic.com/mercurial/wiki/index.cgi/MqMerge
       80 * a good summary on rebasing: http://www.selenic.com/pipermail/mercurial/2008-February/017367.html
       81 
       82 === Multi-based Patches
       83 
       84 (This technique is untested; maybe we don't need it.)
       85 
       86 If a patch must be split so as to apply to several OpenJDK builds, the latest patch in the series must be a complete patch for the most recent build, and for each previous build, a temporary patches must simply track the relevant changes up to the most recent build, so as to make the newest patch apply correctly in all cases.
       87 
       88 For example, to support builds 25 and 28 behind build 30 two fixup patches are needed:
       89 	anonk.jdk7-b28.patch #-/anonk #+7836be3e92d0 #+jdk7-b25
       90 	anonk.jdk7-b30.patch #-/anonk #+c14dab40ed9b #+jdk7-b28
       91 	anonk.patch          #-/anonk #+d1605aabd0a1 #+jdk7-b30
       92 
       93 If you have build jdk7-b28, you must set the guards for all three revisions, so that all three patches are enabled.
       94 
       95 Normally this will not be necessary, unless the patch provides functionality which several other patches depend on, and those patches are in different stages of rebasing.
       96 
       97 == Setting Up Your Workspace
       98 
       99 Make a directory which will contain both sets of repositories (patches and full sources), and pull everything there.  Then create symbolic links to the patch directories from the corresponding ".hg" directories of the full sources.
      100 
      101 	$ mkdir davinci
      102 	$ cd davinci
      103         $ hg fclone http://hg.openjdk.java.net/bsd-port/bsd-port sources
      104 	$ hg fclone http://hg.openjdk.java.net/mlvm/mlvm patches
      105 	$ (cd patches/make; gnumake setup)  # will probably fail
      106 	$ (cd patches/make; gnumake force)  # force "hg update" to fix
      107 	$ (cd patches/make; gnumake)
      108 	$ (cd patches/make; gnumake FORCE_VERSIONS=1) # include the force by default
      109 
      110 The "gnumake setup" command is likely to fail, if the source version of each sub-repository is not exactly the same as the version advertised in the first line of its series file.  If it fails, the "force" target cleans up by running "hg update" (a.k.a. "hg checkout") to force the repository back to the required revision.  See the section above on "Patch Guards" to determine the required base revision.
      111 
      112 Instead of using the makefile, the following shell commands will work as well:
      113 	$ bash patches/make/link-patch-dirs.sh sources patches
      114 	+ ln -s ../../../patches/hotspot sources/hotspot/.hg/patches
      115 	+ ln -s ../../../patches/jdk sources/jdk/.hg/patches
      116 	$ ls -il patches/hotspot/series sources/hotspot/.hg/patches/series
      117 	(should be identical files)
      118 	$ export davinci=$(pwd) guards="buildable testable"
      119 	$ sh patches/make/each-patch-repo.sh "hg qselect --pop $guards" \
      120 		'$(sh $davinci/patches/make/current-release.sh)'
      121 	$ sh patches/make/each-patch-repo.sh "hg qselect; hg qunapplied"
      122 	$ sh patches/make/each-patch-repo.sh "hg update -r" \
      123 		'$(sh $davinci/patches/make/current-release.sh)'
      124 	$ sh patches/make/each-patch-repo.sh hg qpush -a
      125 
      126 The last command may produce output about patches being skipped.  This is correct, because the setting of $guards will ensure that only buildable and testable patches will be applied.  It may also produce messages about the patches being already applied, in which case a non-zero exit status is normal.
      127 
      128 If you have not forced the repository to the expected base revision (via "hg update"), the last command may also produce output about failed patch application.  Such failures must be fixed in an ad hoc manner, as you merge the upstream changes with the patch.
      129 
      130 If you have forced the repository, the last command may produce a warning about "working directory not at tip".  This is normal.  It reminds you that you are working with an older version of the software.
      131 
      132 (To apply other sets of patches, adjust the guard settings and/or use qpush to refer to specific desired patches.  Do not make permanent edits to the series file, unless they reflect true changes of development status.)
      133 
      134 === Updating Your Workspace
      135 
      136 If you wish to refresh your source code from the mlvm project, you will have to take the following steps, in order:
      137 * properly dispose of any private changes you may have made
      138 * pop the old mq patches
      139 * update your sources from the bsd-port
      140 * pull new mq patches
      141 * adjust 'qselect' guards to match the new required source revisions
      142 * adjust source revisions (if needed) to match the new patches
      143 * push the new patches
      144 
      145 Example command sequence:
      146         $ sh patches/make/each-patch-repo.sh  hg diff  # display sources
      147         $ sh patches/make/each-patch-repo.sh  hg qpop -a  # remove patches
      148         $ sh patches/make/each-patch-repo.sh  hg pull -u  # pull new sources
      149         $ sh patches/make/each-patch-repo.sh  hg pull -u -R .hg/patches  # pull new patches
      150         # from this point, the guard and patch commands are the same as with a fresh repo
      151 	$ export davinci=$(pwd) guards="buildable testable"
      152 	$ sh patches/make/each-patch-repo.sh "hg qselect --pop $guards" \
      153 		'$(sh $davinci/patches/make/current-release.sh)'  # set new guards
      154 	$ sh patches/make/each-patch-repo.sh "hg qselect; hg qunapplied"
      155 	$ sh patches/make/each-patch-repo.sh "hg update -r" \
      156 		'$(sh $davinci/patches/make/current-release.sh)'  # ensure correct source version
      157        $ sh patches/make/each-patch-repo.sh  hg qpush -a  # push new patches
      158 
      159 == Trouble Shooting
      160 
      161 To verify that the current release is properly checked out, you can use Mercurial commands like these in the source directory:
      162 	cd davinci/sources/hotspot
      163 	hg qpop -a  # following commands assume no patches active
      164 	hg parent  # output should include the 12-digit hash of the working version
      165 	R_CUR=$(hg parent --template '{node|short}\n')
      166 	head -1 < .hg/patches/series # header comment describes main base revision
      167 	R_REQ=$(head -1 < .hg/patches/series | awk '{print $4}')  # should be main base revision
      168 	[ $R_REQ = $R_CUR ] || echo "*** WRONG PATCH BASE"
      169 
      170 The 'checkout' command can be used to reset a clean source repository to the base revision required for patches:
      171 	hg qpop -a  # following commands assume no patches active
      172 	hg checkout $R_REQ
      173 	R_CUR=$(hg parent --template '{node|short}\n')
      174 	[ $R_REQ = $R_CUR ] || echo "*** CHECKOUT FAILED"
      175 	hg qselect buildable testable $R_CUR
      176 	hg qpush -a
      177 	R_QPAR=$(hg log -r qparent --template '{node|short}\n')
      178 	[ $R_REQ = $R_QPAR ] || echo "*** QUEUE PUSH FAILED"
      179