public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [gold patch] Incremental 15/18: Add --incremental-base option.
@ 2011-04-04 23:30 Cary Coutant
  2011-04-25 20:33 ` Cary Coutant
  0 siblings, 1 reply; 7+ messages in thread
From: Cary Coutant @ 2011-04-04 23:30 UTC (permalink / raw)
  To: Ian Lance Taylor, Binutils

[-- Attachment #1: Type: text/plain, Size: 957 bytes --]

This patch adds a --incremental-base option, so that the base file for
the incremental link can be different from the output file. For
simplicity, I simply copy the base file contents to a new output file,
then carry on with a normal incremental link.

-cary


	* gold.cc (queue_initial_tasks): Pass incremental base filename
	to Output_file::open_for_modification.
	* incremental-dump.cc (main): Adjust call to
	Output_file::open_for_modification.
	* incremental.cc (Incremental_inputs::report_command_line):
	Ignore --incremental-base option when comparing command lines.
	* options.h (class General_options): Add --incremental-base.
	* output.cc (Output_file::Output_file):
	(Output_file::open_for_modification): Add base_name parameter;
	copy base file to new file.
	* output.h (Output_file::open_for_modification): Add base_name
	parameter.
	* testsuite/Makefile.am (incremental_test_4): Test
	--incremental-base.
	* testsuite/Makefile.in: Regenerate.

[-- Attachment #2: incr-patch-15.txt --]
[-- Type: text/plain, Size: 7022 bytes --]

Add --incremental-base option.


2011-04-04 Cary Coutant  <ccoutant@google.com>

	* gold.cc (queue_initial_tasks): Pass incremental base filename
	to Output_file::open_for_modification.
	* incremental-dump.cc (main): Adjust call to
	Output_file::open_for_modification.
	* incremental.cc (Incremental_inputs::report_command_line):
	Ignore --incremental-base option when comparing command lines.
	* options.h (class General_options): Add --incremental-base.
	* output.cc (Output_file::Output_file):
	(Output_file::open_for_modification): Add base_name parameter;
	copy base file to new file.
	* output.h (Output_file::open_for_modification): Add base_name
	parameter.
	* testsuite/Makefile.am (incremental_test_4): Test
	--incremental-base.
	* testsuite/Makefile.in: Regenerate.


diff --git a/gold/gold.cc b/gold/gold.cc
index 84008ca..85b2907 100644
--- a/gold/gold.cc
+++ b/gold/gold.cc
@@ -204,7 +204,7 @@ queue_initial_tasks(const General_options& options,
       if (parameters->incremental_update())
 	{
 	  Output_file* of = new Output_file(options.output_file_name());
-	  if (!of->open_for_modification())
+	  if (!of->open_for_modification(options.incremental_base()))
 	    gold_info(_("incremental update not possible: "
 			"cannot open %s"),
 		      options.output_file_name());
diff --git a/gold/incremental-dump.cc b/gold/incremental-dump.cc
index 1887db8..1a3cce9 100644
--- a/gold/incremental-dump.cc
+++ b/gold/incremental-dump.cc
@@ -449,7 +449,7 @@ main(int argc, char** argv)
 
   Output_file* file = new Output_file(filename);
 
-  bool t = file->open_for_modification();
+  bool t = file->open_for_modification(NULL);
   if (!t)
     {
       fprintf(stderr, "%s: open_for_modification(%s): %s\n", argv[0], filename,
diff --git a/gold/incremental.cc b/gold/incremental.cc
index 824608b..817000e 100644
--- a/gold/incremental.cc
+++ b/gold/incremental.cc
@@ -861,6 +861,7 @@ Incremental_inputs::report_command_line(int argc, const char* const* argv)
 	  || strcmp(argv[i], "--incremental-changed") == 0
 	  || strcmp(argv[i], "--incremental-unchanged") == 0
 	  || strcmp(argv[i], "--incremental-unknown") == 0
+	  || is_prefix_of("--incremental-base=", argv[i])
 	  || is_prefix_of("--debug=", argv[i]))
         continue;
 
diff --git a/gold/options.h b/gold/options.h
index 3949690..e272ae7 100644
--- a/gold/options.h
+++ b/gold/options.h
@@ -790,6 +790,11 @@ class General_options
   DEFINE_special(incremental_update, options::TWO_DASHES, '\0',
 		 N_("Do an incremental link; exit if not possible"), NULL);
 
+  DEFINE_string(incremental_base, options::TWO_DASHES, '\0', NULL,
+                N_("Set base file for incremental linking"
+                   " (default is output file)"),
+                N_("FILE"));
+
   DEFINE_special(incremental_changed, options::TWO_DASHES, '\0',
                  N_("Assume files changed"), NULL);
 
diff --git a/gold/output.cc b/gold/output.cc
index f66d471..6af06c5 100644
--- a/gold/output.cc
+++ b/gold/output.cc
@@ -4433,30 +4433,36 @@ Output_file::Output_file(const char* name)
 }
 
 // Try to open an existing file.  Returns false if the file doesn't
-// exist, has a size of 0 or can't be mmapped.
+// exist, has a size of 0 or can't be mmapped.  If BASE_NAME is not
+// NULL, open that file as the base for incremental linking, and
+// copy its contents to the new output file.
 
 bool
-Output_file::open_for_modification()
+Output_file::open_for_modification(const char* base_name)
 {
   // The name "-" means "stdout".
   if (strcmp(this->name_, "-") == 0)
     return false;
 
+  bool use_base_file = base_name != NULL;
+  if (!use_base_file)
+    base_name = this->name_;
+  else if (strcmp(base_name, this->name_) == 0)
+    gold_fatal(_("%s: incremental base and output file name are the same"),
+	       base_name);
+
   // Don't bother opening files with a size of zero.
   struct stat s;
-  if (::stat(this->name_, &s) != 0 || s.st_size == 0)
+  if (::stat(base_name, &s) != 0 || s.st_size == 0)
     return false;
 
-  int o = open_descriptor(-1, this->name_, O_RDWR, 0);
+  int o = open_descriptor(-1, base_name, O_RDWR, 0);
   if (o < 0)
-    gold_fatal(_("%s: open: %s"), this->name_, strerror(errno));
+    gold_fatal(_("%s: open: %s"), base_name, strerror(errno));
+
   this->o_ = o;
   this->file_size_ = s.st_size;
 
-  // If the file can't be mmapped, copying the content to an anonymous
-  // map will probably negate the performance benefits of incremental
-  // linking.  This could be helped by using views and loading only
-  // the necessary parts, but this is not supported as of now.
   if (!this->map_no_anonymous())
     {
       release_descriptor(o, true);
@@ -4465,6 +4471,17 @@ Output_file::open_for_modification()
       return false;
     }
 
+  // If the base file and the output file are different, open a
+  // new output file and copy the contents from the base file.
+  if (use_base_file)
+    {
+      unsigned char* base = this->base_;
+      this->open(s.st_size);
+      memcpy(this->base_, base, s.st_size);
+      ::munmap(base, s.st_size);
+      ::close(o);
+    }
+
   return true;
 }
 
diff --git a/gold/output.h b/gold/output.h
index 54ce4f9..dedf898 100644
--- a/gold/output.h
+++ b/gold/output.h
@@ -4231,9 +4231,10 @@ class Output_file
 
   // Try to open an existing file. Returns false if the file doesn't
   // exist, has a size of 0 or can't be mmaped.  This method is
-  // thread-unsafe.
+  // thread-unsafe.  If BASE_NAME is not NULL, use the contents of
+  // that file as the base for incremental linking.
   bool
-  open_for_modification();
+  open_for_modification(const char* base_name);
 
   // Open the output file.  FILE_SIZE is the final size of the file.
   // If the file already exists, it is deleted/truncated.  This method
diff --git a/gold/testsuite/Makefile.am b/gold/testsuite/Makefile.am
index 90860f1..821a9bb 100644
--- a/gold/testsuite/Makefile.am
+++ b/gold/testsuite/Makefile.am
@@ -1840,13 +1840,15 @@ incremental_test_3: two_file_test_1.o two_file_test_1b_v1.o two_file_test_1b.o \
 	$(CXXLINK) -Wl,--incremental-update -Bgcctestdir/ two_file_test_1.o two_file_test_tmp.o two_file_test_2.o two_file_test_main.o
 
 check_PROGRAMS += incremental_test_4
+MOSTLYCLEANFILES += incremental_test_4.base
 incremental_test_4: two_file_test_1.o two_file_test_1b.o two_file_test_2_v1.o \
 		    two_file_test_2.o two_file_test_main.o gcctestdir/ld
 	cp -f two_file_test_2_v1.o two_file_test_tmp.o
 	$(CXXLINK) -Wl,--incremental-full -Bgcctestdir/ two_file_test_1.o two_file_test_1b.o two_file_test_tmp.o two_file_test_main.o
+	mv -f incremental_test_4 incremental_test_4.base
 	@sleep 1
 	cp -f two_file_test_2.o two_file_test_tmp.o
-	$(CXXLINK) -Wl,--incremental-update -Bgcctestdir/ two_file_test_1.o two_file_test_1b.o two_file_test_tmp.o two_file_test_main.o
+	$(CXXLINK) -Wl,--incremental-update,--incremental-base=incremental_test_4.base -Bgcctestdir/ two_file_test_1.o two_file_test_1b.o two_file_test_tmp.o two_file_test_main.o
 
 endif DEFAULT_TARGET_X86_64
 

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2011-05-24 23:33 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-04-04 23:30 [gold patch] Incremental 15/18: Add --incremental-base option Cary Coutant
2011-04-25 20:33 ` Cary Coutant
2011-05-24 14:59   ` Ian Lance Taylor
2011-05-24 22:20     ` Cary Coutant
2011-05-24 22:54       ` Cary Coutant
2011-05-24 23:08         ` Ian Lance Taylor
2011-05-24 23:33           ` Cary Coutant

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).