summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dex2oat/dex2oat.cc5
-rw-r--r--dex2oat/linker/elf_writer.h4
-rw-r--r--dex2oat/linker/elf_writer_quick.cc37
3 files changed, 27 insertions, 19 deletions
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index bcc51182b7..09dd6bc6e3 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -2154,7 +2154,10 @@ class Dex2Oat final {
// We need to mirror the layout of the ELF file in the compressed debug-info.
// Therefore PrepareDebugInfo() relies on the SetLoadedSectionSizes() call further above.
debug::DebugInfo debug_info = oat_writer->GetDebugInfo(); // Keep the variable alive.
- elf_writer->PrepareDebugInfo(debug_info); // Processes the data on background thread.
+ // This will perform the compression on background thread while we do other I/O below.
+ // If we hit any ERROR path below, the destructor of this variable will wait for the
+ // task to finish (since it accesses the 'debug_info' above and other 'Dex2Oat' data).
+ std::unique_ptr<ThreadPool> compression_job = elf_writer->PrepareDebugInfo(debug_info);
OutputStream* rodata = rodata_[i];
DCHECK(rodata != nullptr);
diff --git a/dex2oat/linker/elf_writer.h b/dex2oat/linker/elf_writer.h
index 35e3565592..d27d4fa92c 100644
--- a/dex2oat/linker/elf_writer.h
+++ b/dex2oat/linker/elf_writer.h
@@ -18,6 +18,7 @@
#define ART_DEX2OAT_LINKER_ELF_WRITER_H_
#include <stdint.h>
+
#include <cstddef>
#include <string>
#include <vector>
@@ -27,6 +28,7 @@
#include "base/mutex.h"
#include "base/os.h"
#include "debug/debug_info.h"
+#include "thread_pool.h"
namespace art {
@@ -66,7 +68,7 @@ class ElfWriter {
size_t bss_methods_offset,
size_t bss_roots_offset,
size_t dex_section_size) = 0;
- virtual void PrepareDebugInfo(const debug::DebugInfo& debug_info) = 0;
+ virtual std::unique_ptr<ThreadPool> PrepareDebugInfo(const debug::DebugInfo& debug_info) = 0;
virtual OutputStream* StartRoData() = 0;
virtual void EndRoData(OutputStream* rodata) = 0;
virtual OutputStream* StartText() = 0;
diff --git a/dex2oat/linker/elf_writer_quick.cc b/dex2oat/linker/elf_writer_quick.cc
index f87ca6d81e..425f9bd554 100644
--- a/dex2oat/linker/elf_writer_quick.cc
+++ b/dex2oat/linker/elf_writer_quick.cc
@@ -40,21 +40,22 @@ namespace linker {
class DebugInfoTask : public Task {
public:
- DebugInfoTask(InstructionSet isa,
+ DebugInfoTask(ThreadPool* owner,
+ InstructionSet isa,
const InstructionSetFeatures* features,
uint64_t text_section_address,
size_t text_section_size,
uint64_t dex_section_address,
size_t dex_section_size,
const debug::DebugInfo& debug_info)
- : isa_(isa),
+ : owner_(owner),
+ isa_(isa),
instruction_set_features_(features),
text_section_address_(text_section_address),
text_section_size_(text_section_size),
dex_section_address_(dex_section_address),
dex_section_size_(dex_section_size),
- debug_info_(debug_info) {
- }
+ debug_info_(debug_info) {}
void Run(Thread*) override {
result_ = debug::MakeMiniDebugInfo(isa_,
@@ -66,11 +67,13 @@ class DebugInfoTask : public Task {
debug_info_);
}
- std::vector<uint8_t>* GetResult() {
+ std::vector<uint8_t>* WaitAndGetMiniDebugInfo() {
+ owner_->Wait(Thread::Current(), true, false);
return &result_;
}
private:
+ ThreadPool* owner_;
InstructionSet isa_;
const InstructionSetFeatures* instruction_set_features_;
uint64_t text_section_address_;
@@ -97,7 +100,7 @@ class ElfWriterQuick final : public ElfWriter {
size_t bss_methods_offset,
size_t bss_roots_offset,
size_t dex_section_size) override;
- void PrepareDebugInfo(const debug::DebugInfo& debug_info) override;
+ std::unique_ptr<ThreadPool> PrepareDebugInfo(const debug::DebugInfo& debug_info) override;
OutputStream* StartRoData() override;
void EndRoData(OutputStream* rodata) override;
OutputStream* StartText() override;
@@ -127,7 +130,6 @@ class ElfWriterQuick final : public ElfWriter {
std::unique_ptr<BufferedOutputStream> output_stream_;
std::unique_ptr<ElfBuilder<ElfTypes>> builder_;
std::unique_ptr<DebugInfoTask> debug_info_task_;
- std::unique_ptr<ThreadPool> debug_info_thread_pool_;
void ComputeFileBuildId(uint8_t (*build_id)[ElfBuilder<ElfTypes>::kBuildIdLen]);
@@ -245,11 +247,15 @@ void ElfWriterQuick<ElfTypes>::WriteDynamicSection() {
}
template <typename ElfTypes>
-void ElfWriterQuick<ElfTypes>::PrepareDebugInfo(const debug::DebugInfo& debug_info) {
+std::unique_ptr<ThreadPool> ElfWriterQuick<ElfTypes>::PrepareDebugInfo(
+ const debug::DebugInfo& debug_info) {
+ std::unique_ptr<ThreadPool> thread_pool;
if (compiler_options_.GetGenerateMiniDebugInfo()) {
+ thread_pool.reset(ThreadPool::Create("Mini-debug-info writer", 1));
// Prepare the mini-debug-info in background while we do other I/O.
Thread* self = Thread::Current();
debug_info_task_ = std::make_unique<DebugInfoTask>(
+ thread_pool.get(),
builder_->GetIsa(),
compiler_options_.GetInstructionSetFeatures(),
builder_->GetText()->GetAddress(),
@@ -257,24 +263,21 @@ void ElfWriterQuick<ElfTypes>::PrepareDebugInfo(const debug::DebugInfo& debug_in
builder_->GetDex()->Exists() ? builder_->GetDex()->GetAddress() : 0,
dex_section_size_,
debug_info);
- debug_info_thread_pool_.reset(ThreadPool::Create("Mini-debug-info writer", 1));
- debug_info_thread_pool_->AddTask(self, debug_info_task_.get());
- debug_info_thread_pool_->StartWorkers(self);
+ thread_pool->AddTask(self, debug_info_task_.get());
+ thread_pool->StartWorkers(self);
}
+ return thread_pool;
}
template <typename ElfTypes>
void ElfWriterQuick<ElfTypes>::WriteDebugInfo(const debug::DebugInfo& debug_info) {
+ std::unique_ptr<ThreadPool> thread_pool;
if (compiler_options_.GetGenerateMiniDebugInfo()) {
// If mini-debug-info wasn't explicitly created so far, create it now (happens in tests).
if (debug_info_task_ == nullptr) {
- PrepareDebugInfo(debug_info);
+ thread_pool = PrepareDebugInfo(debug_info);
}
- // Wait for the mini-debug-info generation to finish and write it to disk.
- Thread* self = Thread::Current();
- DCHECK(debug_info_thread_pool_ != nullptr);
- debug_info_thread_pool_->Wait(self, true, false);
- builder_->WriteSection(".gnu_debugdata", debug_info_task_->GetResult());
+ builder_->WriteSection(".gnu_debugdata", debug_info_task_->WaitAndGetMiniDebugInfo());
}
// The Strip method expects debug info to be last (mini-debug-info is not stripped).
if (!debug_info.Empty() && compiler_options_.GetGenerateDebugInfo()) {