summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build/Android.bp6
-rw-r--r--dalvikvm/Android.bp3
-rw-r--r--dexlayout/dex_ir.cc24
-rw-r--r--dexlayout/dex_ir.h39
-rw-r--r--dexlayout/dex_verify.cc109
-rw-r--r--dexlayout/dex_verify.h8
-rw-r--r--dexlayout/dexlayout.cc133
-rw-r--r--dexlayout/dexlayout.h8
-rw-r--r--runtime/dex_file-inl.h275
-rw-r--r--runtime/dex_file.cc222
-rw-r--r--runtime/dex_file.h35
-rw-r--r--runtime/gc/heap.cc9
-rw-r--r--runtime/parsed_options.cc2
-rw-r--r--runtime/plugin.cc6
-rw-r--r--runtime/runtime.cc16
-rw-r--r--runtime/signal_catcher.cc2
-rw-r--r--runtime/ti/agent.cc3
-rw-r--r--test/Android.bp33
-rw-r--r--tools/libjdwp_art_failures.txt28
-rw-r--r--tools/wrapagentproperties/wrapagentproperties.cc4
20 files changed, 453 insertions, 512 deletions
diff --git a/build/Android.bp b/build/Android.bp
index ff762dd703..2c959d46f5 100644
--- a/build/Android.bp
+++ b/build/Android.bp
@@ -67,10 +67,6 @@ art_global_defaults {
cflags: [
"-DART_TARGET",
- // Enable missing-noreturn only on non-Mac. As lots of things are not implemented
- // for Apple, it's a pain.
- "-Wmissing-noreturn",
-
// To use oprofile_android --callgraph, uncomment this and recompile with
// mmma -j art
// "-fno-omit-frame-pointer",
@@ -83,7 +79,7 @@ art_global_defaults {
"bionic/libc/private",
],
},
- linux_glibc: {
+ linux: {
cflags: [
// Enable missing-noreturn only on non-Mac. As lots of things are not implemented for
// Apple, it's a pain.
diff --git a/dalvikvm/Android.bp b/dalvikvm/Android.bp
index cca9ac4dbe..c1944fbe59 100644
--- a/dalvikvm/Android.bp
+++ b/dalvikvm/Android.bp
@@ -34,9 +34,8 @@ art_cc_binary {
shared_libs: [
"liblog",
],
- ldflags: ["-Wl,--export-dynamic"],
},
- linux_glibc: {
+ linux: {
ldflags: ["-Wl,--export-dynamic"],
},
},
diff --git a/dexlayout/dex_ir.cc b/dexlayout/dex_ir.cc
index 0c944cee2c..f75eacc2d3 100644
--- a/dexlayout/dex_ir.cc
+++ b/dexlayout/dex_ir.cc
@@ -39,24 +39,6 @@ static uint64_t ReadVarWidth(const uint8_t** data, uint8_t length, bool sign_ext
return value;
}
-static bool GetPositionsCb(void* context, const DexFile::PositionInfo& entry) {
- DebugInfoItem* debug_info = reinterpret_cast<DebugInfoItem*>(context);
- PositionInfoVector& positions = debug_info->GetPositionInfo();
- positions.push_back(std::unique_ptr<PositionInfo>(new PositionInfo(entry.address_, entry.line_)));
- return false;
-}
-
-static void GetLocalsCb(void* context, const DexFile::LocalInfo& entry) {
- DebugInfoItem* debug_info = reinterpret_cast<DebugInfoItem*>(context);
- LocalInfoVector& locals = debug_info->GetLocalInfo();
- const char* name = entry.name_ != nullptr ? entry.name_ : "(null)";
- const char* descriptor = entry.descriptor_ != nullptr ? entry.descriptor_ : "";
- const char* signature = entry.signature_ != nullptr ? entry.signature_ : "";
- locals.push_back(std::unique_ptr<LocalInfo>(
- new LocalInfo(name, descriptor, signature, entry.start_address_, entry.end_address_,
- entry.reg_)));
-}
-
static uint32_t GetDebugInfoStreamSize(const uint8_t* debug_info_stream) {
const uint8_t* stream = debug_info_stream;
DecodeUnsignedLeb128(&stream); // line_start
@@ -694,12 +676,6 @@ MethodItem* Collections::GenerateMethodItem(const DexFile& dex_file, ClassDataIt
}
debug_info = code_item->DebugInfo();
}
- if (debug_info != nullptr) {
- bool is_static = (access_flags & kAccStatic) != 0;
- dex_file.DecodeDebugLocalInfo(
- disk_code_item, is_static, cdii.GetMemberIndex(), GetLocalsCb, debug_info);
- dex_file.DecodeDebugPositionInfo(disk_code_item, GetPositionsCb, debug_info);
- }
return new MethodItem(access_flags, method_id, code_item);
}
diff --git a/dexlayout/dex_ir.h b/dexlayout/dex_ir.h
index 5dcc87dd2e..df3484c012 100644
--- a/dexlayout/dex_ir.h
+++ b/dexlayout/dex_ir.h
@@ -966,39 +966,6 @@ class CodeItem : public Item {
DISALLOW_COPY_AND_ASSIGN(CodeItem);
};
-struct PositionInfo {
- PositionInfo(uint32_t address, uint32_t line) : address_(address), line_(line) { }
-
- uint32_t address_;
- uint32_t line_;
-};
-
-using PositionInfoVector = std::vector<std::unique_ptr<PositionInfo>>;
-
-struct LocalInfo {
- LocalInfo(const char* name,
- const char* descriptor,
- const char* signature,
- uint32_t start_address,
- uint32_t end_address,
- uint16_t reg)
- : name_(name),
- descriptor_(descriptor),
- signature_(signature),
- start_address_(start_address),
- end_address_(end_address),
- reg_(reg) { }
-
- std::string name_;
- std::string descriptor_;
- std::string signature_;
- uint32_t start_address_;
- uint32_t end_address_;
- uint16_t reg_;
-};
-
-using LocalInfoVector = std::vector<std::unique_ptr<LocalInfo>>;
-
class DebugInfoItem : public Item {
public:
DebugInfoItem(uint32_t debug_info_size, uint8_t* debug_info)
@@ -1007,16 +974,10 @@ class DebugInfoItem : public Item {
uint32_t GetDebugInfoSize() const { return debug_info_size_; }
uint8_t* GetDebugInfo() const { return debug_info_.get(); }
- PositionInfoVector& GetPositionInfo() { return positions_; }
- LocalInfoVector& GetLocalInfo() { return locals_; }
-
private:
uint32_t debug_info_size_;
std::unique_ptr<uint8_t[]> debug_info_;
- PositionInfoVector positions_;
- LocalInfoVector locals_;
-
DISALLOW_COPY_AND_ASSIGN(DebugInfoItem);
};
diff --git a/dexlayout/dex_verify.cc b/dexlayout/dex_verify.cc
index 54581292ff..18ddc86e0c 100644
--- a/dexlayout/dex_verify.cc
+++ b/dexlayout/dex_verify.cc
@@ -893,109 +893,24 @@ bool VerifyDebugInfo(dex_ir::DebugInfoItem* orig,
}
return true;
}
- if (!VerifyPositionInfo(orig->GetPositionInfo(),
- output->GetPositionInfo(),
- orig->GetOffset(),
- error_msg)) {
+ // TODO: Test for debug equivalence rather than byte array equality.
+ uint32_t orig_size = orig->GetDebugInfoSize();
+ uint32_t output_size = output->GetDebugInfoSize();
+ if (orig_size != output_size) {
+ *error_msg = "DebugInfoSize disagreed.";
return false;
}
- return VerifyLocalInfo(orig->GetLocalInfo(),
- output->GetLocalInfo(),
- orig->GetOffset(),
- error_msg);
-}
-
-bool VerifyPositionInfo(dex_ir::PositionInfoVector& orig,
- dex_ir::PositionInfoVector& output,
- uint32_t orig_offset,
- std::string* error_msg) {
- if (orig.size() != output.size()) {
- *error_msg = StringPrintf(
- "Mismatched number of positions for debug info at offset %x: %zu vs %zu.",
- orig_offset,
- orig.size(),
- output.size());
+ uint8_t* orig_data = orig->GetDebugInfo();
+ uint8_t* output_data = output->GetDebugInfo();
+ if ((orig_data == nullptr && output_data != nullptr) ||
+ (orig_data != nullptr && output_data == nullptr)) {
+ *error_msg = "DebugInfo null/non-null mismatch.";
return false;
}
- for (size_t i = 0; i < orig.size(); ++i) {
- if (orig[i]->address_ != output[i]->address_) {
- *error_msg = StringPrintf(
- "Mismatched position address for debug info at offset %x: %u vs %u.",
- orig_offset,
- orig[i]->address_,
- output[i]->address_);
- return false;
- }
- if (orig[i]->line_ != output[i]->line_) {
- *error_msg = StringPrintf("Mismatched position line for debug info at offset %x: %u vs %u.",
- orig_offset,
- orig[i]->line_,
- output[i]->line_);
- return false;
- }
- }
- return true;
-}
-
-bool VerifyLocalInfo(dex_ir::LocalInfoVector& orig,
- dex_ir::LocalInfoVector& output,
- uint32_t orig_offset,
- std::string* error_msg) {
- if (orig.size() != output.size()) {
- *error_msg = StringPrintf(
- "Mismatched number of locals for debug info at offset %x: %zu vs %zu.",
- orig_offset,
- orig.size(),
- output.size());
+ if (memcmp(orig_data, output_data, orig_size) != 0) {
+ *error_msg = "DebugInfo bytes mismatch.";
return false;
}
- for (size_t i = 0; i < orig.size(); ++i) {
- if (orig[i]->name_ != output[i]->name_) {
- *error_msg = StringPrintf("Mismatched local name for debug info at offset %x: %s vs %s.",
- orig_offset,
- orig[i]->name_.c_str(),
- output[i]->name_.c_str());
- return false;
- }
- if (orig[i]->descriptor_ != output[i]->descriptor_) {
- *error_msg = StringPrintf(
- "Mismatched local descriptor for debug info at offset %x: %s vs %s.",
- orig_offset,
- orig[i]->descriptor_.c_str(),
- output[i]->descriptor_.c_str());
- return false;
- }
- if (orig[i]->signature_ != output[i]->signature_) {
- *error_msg = StringPrintf("Mismatched local signature for debug info at offset %x: %s vs %s.",
- orig_offset,
- orig[i]->signature_.c_str(),
- output[i]->signature_.c_str());
- return false;
- }
- if (orig[i]->start_address_ != output[i]->start_address_) {
- *error_msg = StringPrintf(
- "Mismatched local start address for debug info at offset %x: %u vs %u.",
- orig_offset,
- orig[i]->start_address_,
- output[i]->start_address_);
- return false;
- }
- if (orig[i]->end_address_ != output[i]->end_address_) {
- *error_msg = StringPrintf(
- "Mismatched local end address for debug info at offset %x: %u vs %u.",
- orig_offset,
- orig[i]->end_address_,
- output[i]->end_address_);
- return false;
- }
- if (orig[i]->reg_ != output[i]->reg_) {
- *error_msg = StringPrintf("Mismatched local reg for debug info at offset %x: %u vs %u.",
- orig_offset,
- orig[i]->reg_,
- output[i]->reg_);
- return false;
- }
- }
return true;
}
diff --git a/dexlayout/dex_verify.h b/dexlayout/dex_verify.h
index 58c95d6947..998939bbce 100644
--- a/dexlayout/dex_verify.h
+++ b/dexlayout/dex_verify.h
@@ -100,14 +100,6 @@ bool VerifyCode(dex_ir::CodeItem* orig, dex_ir::CodeItem* output, std::string* e
bool VerifyDebugInfo(dex_ir::DebugInfoItem* orig,
dex_ir::DebugInfoItem* output,
std::string* error_msg);
-bool VerifyPositionInfo(dex_ir::PositionInfoVector& orig,
- dex_ir::PositionInfoVector& output,
- uint32_t orig_offset,
- std::string* error_msg);
-bool VerifyLocalInfo(dex_ir::LocalInfoVector& orig,
- dex_ir::LocalInfoVector& output,
- uint32_t orig_offset,
- std::string* error_msg);
bool VerifyTries(dex_ir::TryItemVector* orig,
dex_ir::TryItemVector* output,
uint32_t orig_offset,
diff --git a/dexlayout/dexlayout.cc b/dexlayout/dexlayout.cc
index ade00723fd..40449ae8bd 100644
--- a/dexlayout/dexlayout.cc
+++ b/dexlayout/dexlayout.cc
@@ -820,37 +820,6 @@ void DexLayout::DumpCatches(const dex_ir::CodeItem* code) {
}
/*
- * Dumps all positions table entries associated with the code.
- */
-void DexLayout::DumpPositionInfo(const dex_ir::CodeItem* code) {
- dex_ir::DebugInfoItem* debug_info = code->DebugInfo();
- if (debug_info == nullptr) {
- return;
- }
- std::vector<std::unique_ptr<dex_ir::PositionInfo>>& positions = debug_info->GetPositionInfo();
- for (size_t i = 0; i < positions.size(); ++i) {
- fprintf(out_file_, " 0x%04x line=%d\n", positions[i]->address_, positions[i]->line_);
- }
-}
-
-/*
- * Dumps all locals table entries associated with the code.
- */
-void DexLayout::DumpLocalInfo(const dex_ir::CodeItem* code) {
- dex_ir::DebugInfoItem* debug_info = code->DebugInfo();
- if (debug_info == nullptr) {
- return;
- }
- std::vector<std::unique_ptr<dex_ir::LocalInfo>>& locals = debug_info->GetLocalInfo();
- for (size_t i = 0; i < locals.size(); ++i) {
- dex_ir::LocalInfo* entry = locals[i].get();
- fprintf(out_file_, " 0x%04x - 0x%04x reg=%d %s %s %s\n",
- entry->start_address_, entry->end_address_, entry->reg_,
- entry->name_.c_str(), entry->descriptor_.c_str(), entry->signature_.c_str());
- }
-}
-
-/*
* Dumps a single instruction.
*/
void DexLayout::DumpInstruction(const dex_ir::CodeItem* code,
@@ -1093,9 +1062,59 @@ void DexLayout::DumpBytecodes(uint32_t idx, const dex_ir::CodeItem* code, uint32
}
/*
+ * Callback for dumping each positions table entry.
+ */
+static bool DumpPositionsCb(void* context, const DexFile::PositionInfo& entry) {
+ FILE* out_file = reinterpret_cast<FILE*>(context);
+ fprintf(out_file, " 0x%04x line=%d\n", entry.address_, entry.line_);
+ return false;
+}
+
+/*
+ * Callback for dumping locals table entry.
+ */
+static void DumpLocalsCb(void* context, const DexFile::LocalInfo& entry) {
+ const char* signature = entry.signature_ != nullptr ? entry.signature_ : "";
+ FILE* out_file = reinterpret_cast<FILE*>(context);
+ fprintf(out_file, " 0x%04x - 0x%04x reg=%d %s %s %s\n",
+ entry.start_address_, entry.end_address_, entry.reg_,
+ entry.name_, entry.descriptor_, signature);
+}
+
+/*
+ * Lookup functions.
+ */
+static const char* StringDataByIdx(uint32_t idx, dex_ir::Collections& collections) {
+ dex_ir::StringId* string_id = collections.GetStringIdOrNullPtr(idx);
+ if (string_id == nullptr) {
+ return nullptr;
+ }
+ return string_id->Data();
+}
+
+static const char* StringDataByTypeIdx(uint16_t idx, dex_ir::Collections& collections) {
+ dex_ir::TypeId* type_id = collections.GetTypeIdOrNullPtr(idx);
+ if (type_id == nullptr) {
+ return nullptr;
+ }
+ dex_ir::StringId* string_id = type_id->GetStringId();
+ if (string_id == nullptr) {
+ return nullptr;
+ }
+ return string_id->Data();
+}
+
+
+/*
* Dumps code of a method.
*/
-void DexLayout::DumpCode(uint32_t idx, const dex_ir::CodeItem* code, uint32_t code_offset) {
+void DexLayout::DumpCode(uint32_t idx,
+ const dex_ir::CodeItem* code,
+ uint32_t code_offset,
+ const char* declaring_class_descriptor,
+ const char* method_name,
+ bool is_static,
+ const dex_ir::ProtoId* proto) {
fprintf(out_file_, " registers : %d\n", code->RegistersSize());
fprintf(out_file_, " ins : %d\n", code->InsSize());
fprintf(out_file_, " outs : %d\n", code->OutsSize());
@@ -1111,10 +1130,48 @@ void DexLayout::DumpCode(uint32_t idx, const dex_ir::CodeItem* code, uint32_t co
DumpCatches(code);
// Positions and locals table in the debug info.
+ dex_ir::DebugInfoItem* debug_info = code->DebugInfo();
fprintf(out_file_, " positions : \n");
- DumpPositionInfo(code);
+ if (debug_info != nullptr) {
+ DexFile::DecodeDebugPositionInfo(debug_info->GetDebugInfo(),
+ [this](uint32_t idx) {
+ return StringDataByIdx(idx, this->header_->GetCollections());
+ },
+ DumpPositionsCb,
+ out_file_);
+ }
fprintf(out_file_, " locals : \n");
- DumpLocalInfo(code);
+ if (debug_info != nullptr) {
+ std::vector<const char*> arg_descriptors;
+ const dex_ir::TypeList* parameters = proto->Parameters();
+ if (parameters != nullptr) {
+ const dex_ir::TypeIdVector* parameter_type_vector = parameters->GetTypeList();
+ if (parameter_type_vector != nullptr) {
+ for (const dex_ir::TypeId* type_id : *parameter_type_vector) {
+ arg_descriptors.push_back(type_id->GetStringId()->Data());
+ }
+ }
+ }
+ DexFile::DecodeDebugLocalInfo(debug_info->GetDebugInfo(),
+ "DexLayout in-memory",
+ declaring_class_descriptor,
+ arg_descriptors,
+ method_name,
+ is_static,
+ code->RegistersSize(),
+ code->InsSize(),
+ code->InsnsSize(),
+ [this](uint32_t idx) {
+ return StringDataByIdx(idx, this->header_->GetCollections());
+ },
+ [this](uint32_t idx) {
+ return
+ StringDataByTypeIdx(dchecked_integral_cast<uint16_t>(idx),
+ this->header_->GetCollections());
+ },
+ DumpLocalsCb,
+ out_file_);
+ }
}
/*
@@ -1141,7 +1198,13 @@ void DexLayout::DumpMethod(uint32_t idx, uint32_t flags, const dex_ir::CodeItem*
fprintf(out_file_, " code : (none)\n");
} else {
fprintf(out_file_, " code -\n");
- DumpCode(idx, code, code->GetOffset());
+ DumpCode(idx,
+ code,
+ code->GetOffset(),
+ back_descriptor,
+ name,
+ (flags & kAccStatic) != 0,
+ method_id->Proto());
}
if (options_.disassemble_) {
fputc('\n', out_file_);
diff --git a/dexlayout/dexlayout.h b/dexlayout/dexlayout.h
index 9f6e8a4122..180d9bc87c 100644
--- a/dexlayout/dexlayout.h
+++ b/dexlayout/dexlayout.h
@@ -96,7 +96,13 @@ class DexLayout {
void DumpClass(int idx, char** last_package);
void DumpClassAnnotations(int idx);
void DumpClassDef(int idx);
- void DumpCode(uint32_t idx, const dex_ir::CodeItem* code, uint32_t code_offset);
+ void DumpCode(uint32_t idx,
+ const dex_ir::CodeItem* code,
+ uint32_t code_offset,
+ const char* declaring_class_descriptor,
+ const char* method_name,
+ bool is_static,
+ const dex_ir::ProtoId* proto);
void DumpEncodedAnnotation(dex_ir::EncodedAnnotation* annotation);
void DumpEncodedValue(const dex_ir::EncodedValue* data);
void DumpFileHeader();
diff --git a/runtime/dex_file-inl.h b/runtime/dex_file-inl.h
index 1b7c31859c..5dfbd9b6a1 100644
--- a/runtime/dex_file-inl.h
+++ b/runtime/dex_file-inl.h
@@ -18,6 +18,7 @@
#define ART_RUNTIME_DEX_FILE_INL_H_
#include "base/bit_utils.h"
+#include "base/casts.h"
#include "base/logging.h"
#include "base/stringpiece.h"
#include "dex_file.h"
@@ -220,6 +221,280 @@ InvokeType ClassDataItemIterator::GetMethodInvokeType(const DexFile::ClassDef& c
}
}
+template<typename NewLocalCallback, typename IndexToStringData, typename TypeIndexToStringData>
+bool DexFile::DecodeDebugLocalInfo(const uint8_t* stream,
+ const std::string& location,
+ const char* declaring_class_descriptor,
+ const std::vector<const char*>& arg_descriptors,
+ const std::string& method_name,
+ bool is_static,
+ uint16_t registers_size,
+ uint16_t ins_size,
+ uint16_t insns_size_in_code_units,
+ IndexToStringData index_to_string_data,
+ TypeIndexToStringData type_index_to_string_data,
+ NewLocalCallback new_local_callback,
+ void* context) {
+ if (stream == nullptr) {
+ return false;
+ }
+ std::vector<LocalInfo> local_in_reg(registers_size);
+
+ uint16_t arg_reg = registers_size - ins_size;
+ if (!is_static) {
+ const char* descriptor = declaring_class_descriptor;
+ local_in_reg[arg_reg].name_ = "this";
+ local_in_reg[arg_reg].descriptor_ = descriptor;
+ local_in_reg[arg_reg].signature_ = nullptr;
+ local_in_reg[arg_reg].start_address_ = 0;
+ local_in_reg[arg_reg].reg_ = arg_reg;
+ local_in_reg[arg_reg].is_live_ = true;
+ arg_reg++;
+ }
+
+ DecodeUnsignedLeb128(&stream); // Line.
+ uint32_t parameters_size = DecodeUnsignedLeb128(&stream);
+ uint32_t i;
+ if (parameters_size != arg_descriptors.size()) {
+ LOG(ERROR) << "invalid stream - problem with parameter iterator in " << location
+ << " for method " << method_name;
+ return false;
+ }
+ for (i = 0; i < parameters_size && i < arg_descriptors.size(); ++i) {
+ if (arg_reg >= registers_size) {
+ LOG(ERROR) << "invalid stream - arg reg >= reg size (" << arg_reg
+ << " >= " << registers_size << ") in " << location;
+ return false;
+ }
+ uint32_t name_idx = DecodeUnsignedLeb128P1(&stream);
+ const char* descriptor = arg_descriptors[i];
+ local_in_reg[arg_reg].name_ = index_to_string_data(name_idx);
+ local_in_reg[arg_reg].descriptor_ = descriptor;
+ local_in_reg[arg_reg].signature_ = nullptr;
+ local_in_reg[arg_reg].start_address_ = 0;
+ local_in_reg[arg_reg].reg_ = arg_reg;
+ local_in_reg[arg_reg].is_live_ = true;
+ switch (*descriptor) {
+ case 'D':
+ case 'J':
+ arg_reg += 2;
+ break;
+ default:
+ arg_reg += 1;
+ break;
+ }
+ }
+
+ uint32_t address = 0;
+ for (;;) {
+ uint8_t opcode = *stream++;
+ switch (opcode) {
+ case DBG_END_SEQUENCE:
+ // Emit all variables which are still alive at the end of the method.
+ for (uint16_t reg = 0; reg < registers_size; reg++) {
+ if (local_in_reg[reg].is_live_) {
+ local_in_reg[reg].end_address_ = insns_size_in_code_units;
+ new_local_callback(context, local_in_reg[reg]);
+ }
+ }
+ return true;
+ case DBG_ADVANCE_PC:
+ address += DecodeUnsignedLeb128(&stream);
+ break;
+ case DBG_ADVANCE_LINE:
+ DecodeSignedLeb128(&stream); // Line.
+ break;
+ case DBG_START_LOCAL:
+ case DBG_START_LOCAL_EXTENDED: {
+ uint16_t reg = DecodeUnsignedLeb128(&stream);
+ if (reg >= registers_size) {
+ LOG(ERROR) << "invalid stream - reg >= reg size (" << reg << " >= "
+ << registers_size << ") in " << location;
+ return false;
+ }
+
+ uint32_t name_idx = DecodeUnsignedLeb128P1(&stream);
+ uint16_t descriptor_idx = DecodeUnsignedLeb128P1(&stream);
+ uint32_t signature_idx = dex::kDexNoIndex;
+ if (opcode == DBG_START_LOCAL_EXTENDED) {
+ signature_idx = DecodeUnsignedLeb128P1(&stream);
+ }
+
+ // Emit what was previously there, if anything
+ if (local_in_reg[reg].is_live_) {
+ local_in_reg[reg].end_address_ = address;
+ new_local_callback(context, local_in_reg[reg]);
+ }
+
+ local_in_reg[reg].name_ = index_to_string_data(name_idx);
+ local_in_reg[reg].descriptor_ = type_index_to_string_data(descriptor_idx);;
+ local_in_reg[reg].signature_ = index_to_string_data(signature_idx);
+ local_in_reg[reg].start_address_ = address;
+ local_in_reg[reg].reg_ = reg;
+ local_in_reg[reg].is_live_ = true;
+ break;
+ }
+ case DBG_END_LOCAL: {
+ uint16_t reg = DecodeUnsignedLeb128(&stream);
+ if (reg >= registers_size) {
+ LOG(ERROR) << "invalid stream - reg >= reg size (" << reg << " >= "
+ << registers_size << ") in " << location;
+ return false;
+ }
+ // If the register is live, close it properly. Otherwise, closing an already
+ // closed register is sloppy, but harmless if no further action is taken.
+ if (local_in_reg[reg].is_live_) {
+ local_in_reg[reg].end_address_ = address;
+ new_local_callback(context, local_in_reg[reg]);
+ local_in_reg[reg].is_live_ = false;
+ }
+ break;
+ }
+ case DBG_RESTART_LOCAL: {
+ uint16_t reg = DecodeUnsignedLeb128(&stream);
+ if (reg >= registers_size) {
+ LOG(ERROR) << "invalid stream - reg >= reg size (" << reg << " >= "
+ << registers_size << ") in " << location;
+ return false;
+ }
+ // If the register is live, the "restart" is superfluous,
+ // and we don't want to mess with the existing start address.
+ if (!local_in_reg[reg].is_live_) {
+ local_in_reg[reg].start_address_ = address;
+ local_in_reg[reg].is_live_ = true;
+ }
+ break;
+ }
+ case DBG_SET_PROLOGUE_END:
+ case DBG_SET_EPILOGUE_BEGIN:
+ break;
+ case DBG_SET_FILE:
+ DecodeUnsignedLeb128P1(&stream); // name.
+ break;
+ default:
+ address += (opcode - DBG_FIRST_SPECIAL) / DBG_LINE_RANGE;
+ break;
+ }
+ }
+}
+
+template<typename NewLocalCallback>
+bool DexFile::DecodeDebugLocalInfo(const CodeItem* code_item,
+ bool is_static,
+ uint32_t method_idx,
+ NewLocalCallback new_local_callback,
+ void* context) const {
+ if (code_item == nullptr) {
+ return false;
+ }
+ std::vector<const char*> arg_descriptors;
+ DexFileParameterIterator it(*this, GetMethodPrototype(GetMethodId(method_idx)));
+ for (; it.HasNext(); it.Next()) {
+ arg_descriptors.push_back(it.GetDescriptor());
+ }
+ return DecodeDebugLocalInfo(GetDebugInfoStream(code_item),
+ GetLocation(),
+ GetMethodDeclaringClassDescriptor(GetMethodId(method_idx)),
+ arg_descriptors,
+ this->PrettyMethod(method_idx),
+ is_static,
+ code_item->registers_size_,
+ code_item->ins_size_,
+ code_item->insns_size_in_code_units_,
+ [this](uint32_t idx) {
+ return StringDataByIdx(dex::StringIndex(idx));
+ },
+ [this](uint32_t idx) {
+ return StringByTypeIdx(dex::TypeIndex(
+ dchecked_integral_cast<uint16_t>(idx)));
+ },
+ new_local_callback,
+ context);
+}
+
+template<typename DexDebugNewPosition, typename IndexToStringData>
+bool DexFile::DecodeDebugPositionInfo(const uint8_t* stream,
+ IndexToStringData index_to_string_data,
+ DexDebugNewPosition position_functor,
+ void* context) {
+ if (stream == nullptr) {
+ return false;
+ }
+
+ PositionInfo entry = PositionInfo();
+ entry.line_ = DecodeUnsignedLeb128(&stream);
+ uint32_t parameters_size = DecodeUnsignedLeb128(&stream);
+ for (uint32_t i = 0; i < parameters_size; ++i) {
+ DecodeUnsignedLeb128P1(&stream); // Parameter name.
+ }
+
+ for (;;) {
+ uint8_t opcode = *stream++;
+ switch (opcode) {
+ case DBG_END_SEQUENCE:
+ return true; // end of stream.
+ case DBG_ADVANCE_PC:
+ entry.address_ += DecodeUnsignedLeb128(&stream);
+ break;
+ case DBG_ADVANCE_LINE:
+ entry.line_ += DecodeSignedLeb128(&stream);
+ break;
+ case DBG_START_LOCAL:
+ DecodeUnsignedLeb128(&stream); // reg.
+ DecodeUnsignedLeb128P1(&stream); // name.
+ DecodeUnsignedLeb128P1(&stream); // descriptor.
+ break;
+ case DBG_START_LOCAL_EXTENDED:
+ DecodeUnsignedLeb128(&stream); // reg.
+ DecodeUnsignedLeb128P1(&stream); // name.
+ DecodeUnsignedLeb128P1(&stream); // descriptor.
+ DecodeUnsignedLeb128P1(&stream); // signature.
+ break;
+ case DBG_END_LOCAL:
+ case DBG_RESTART_LOCAL:
+ DecodeUnsignedLeb128(&stream); // reg.
+ break;
+ case DBG_SET_PROLOGUE_END:
+ entry.prologue_end_ = true;
+ break;
+ case DBG_SET_EPILOGUE_BEGIN:
+ entry.epilogue_begin_ = true;
+ break;
+ case DBG_SET_FILE: {
+ uint32_t name_idx = DecodeUnsignedLeb128P1(&stream);
+ entry.source_file_ = index_to_string_data(name_idx);
+ break;
+ }
+ default: {
+ int adjopcode = opcode - DBG_FIRST_SPECIAL;
+ entry.address_ += adjopcode / DBG_LINE_RANGE;
+ entry.line_ += DBG_LINE_BASE + (adjopcode % DBG_LINE_RANGE);
+ if (position_functor(context, entry)) {
+ return true; // early exit.
+ }
+ entry.prologue_end_ = false;
+ entry.epilogue_begin_ = false;
+ break;
+ }
+ }
+ }
+}
+
+template<typename DexDebugNewPosition>
+bool DexFile::DecodeDebugPositionInfo(const CodeItem* code_item,
+ DexDebugNewPosition position_functor,
+ void* context) const {
+ if (code_item == nullptr) {
+ return false;
+ }
+ return DecodeDebugPositionInfo(GetDebugInfoStream(code_item),
+ [this](uint32_t idx) {
+ return StringDataByIdx(dex::StringIndex(idx));
+ },
+ position_functor,
+ context);
+}
+
} // namespace art
#endif // ART_RUNTIME_DEX_FILE_INL_H_
diff --git a/runtime/dex_file.cc b/runtime/dex_file.cc
index 08c047d8e9..f2c43f7f87 100644
--- a/runtime/dex_file.cc
+++ b/runtime/dex_file.cc
@@ -537,228 +537,6 @@ int32_t DexFile::FindCatchHandlerOffset(const CodeItem &code_item, uint32_t addr
}
}
-bool DexFile::DecodeDebugLocalInfo(const CodeItem* code_item, bool is_static, uint32_t method_idx,
- DexDebugNewLocalCb local_cb, void* context) const {
- DCHECK(local_cb != nullptr);
- if (code_item == nullptr) {
- return false;
- }
- const uint8_t* stream = GetDebugInfoStream(code_item);
- if (stream == nullptr) {
- return false;
- }
- std::vector<LocalInfo> local_in_reg(code_item->registers_size_);
-
- uint16_t arg_reg = code_item->registers_size_ - code_item->ins_size_;
- if (!is_static) {
- const char* descriptor = GetMethodDeclaringClassDescriptor(GetMethodId(method_idx));
- local_in_reg[arg_reg].name_ = "this";
- local_in_reg[arg_reg].descriptor_ = descriptor;
- local_in_reg[arg_reg].signature_ = nullptr;
- local_in_reg[arg_reg].start_address_ = 0;
- local_in_reg[arg_reg].reg_ = arg_reg;
- local_in_reg[arg_reg].is_live_ = true;
- arg_reg++;
- }
-
- DexFileParameterIterator it(*this, GetMethodPrototype(GetMethodId(method_idx)));
- DecodeUnsignedLeb128(&stream); // Line.
- uint32_t parameters_size = DecodeUnsignedLeb128(&stream);
- uint32_t i;
- for (i = 0; i < parameters_size && it.HasNext(); ++i, it.Next()) {
- if (arg_reg >= code_item->registers_size_) {
- LOG(ERROR) << "invalid stream - arg reg >= reg size (" << arg_reg
- << " >= " << code_item->registers_size_ << ") in " << GetLocation();
- return false;
- }
- uint32_t name_idx = DecodeUnsignedLeb128P1(&stream);
- const char* descriptor = it.GetDescriptor();
- local_in_reg[arg_reg].name_ = StringDataByIdx(dex::StringIndex(name_idx));
- local_in_reg[arg_reg].descriptor_ = descriptor;
- local_in_reg[arg_reg].signature_ = nullptr;
- local_in_reg[arg_reg].start_address_ = 0;
- local_in_reg[arg_reg].reg_ = arg_reg;
- local_in_reg[arg_reg].is_live_ = true;
- switch (*descriptor) {
- case 'D':
- case 'J':
- arg_reg += 2;
- break;
- default:
- arg_reg += 1;
- break;
- }
- }
- if (i != parameters_size || it.HasNext()) {
- LOG(ERROR) << "invalid stream - problem with parameter iterator in " << GetLocation()
- << " for method " << this->PrettyMethod(method_idx);
- return false;
- }
-
- uint32_t address = 0;
- for (;;) {
- uint8_t opcode = *stream++;
- switch (opcode) {
- case DBG_END_SEQUENCE:
- // Emit all variables which are still alive at the end of the method.
- for (uint16_t reg = 0; reg < code_item->registers_size_; reg++) {
- if (local_in_reg[reg].is_live_) {
- local_in_reg[reg].end_address_ = code_item->insns_size_in_code_units_;
- local_cb(context, local_in_reg[reg]);
- }
- }
- return true;
- case DBG_ADVANCE_PC:
- address += DecodeUnsignedLeb128(&stream);
- break;
- case DBG_ADVANCE_LINE:
- DecodeSignedLeb128(&stream); // Line.
- break;
- case DBG_START_LOCAL:
- case DBG_START_LOCAL_EXTENDED: {
- uint16_t reg = DecodeUnsignedLeb128(&stream);
- if (reg >= code_item->registers_size_) {
- LOG(ERROR) << "invalid stream - reg >= reg size (" << reg << " >= "
- << code_item->registers_size_ << ") in " << GetLocation();
- return false;
- }
-
- uint32_t name_idx = DecodeUnsignedLeb128P1(&stream);
- uint16_t descriptor_idx = DecodeUnsignedLeb128P1(&stream);
- uint32_t signature_idx = dex::kDexNoIndex;
- if (opcode == DBG_START_LOCAL_EXTENDED) {
- signature_idx = DecodeUnsignedLeb128P1(&stream);
- }
-
- // Emit what was previously there, if anything
- if (local_in_reg[reg].is_live_) {
- local_in_reg[reg].end_address_ = address;
- local_cb(context, local_in_reg[reg]);
- }
-
- local_in_reg[reg].name_ = StringDataByIdx(dex::StringIndex(name_idx));
- local_in_reg[reg].descriptor_ =
- StringByTypeIdx(dex::TypeIndex(dchecked_integral_cast<uint16_t>(descriptor_idx)));;
- local_in_reg[reg].signature_ = StringDataByIdx(dex::StringIndex(signature_idx));
- local_in_reg[reg].start_address_ = address;
- local_in_reg[reg].reg_ = reg;
- local_in_reg[reg].is_live_ = true;
- break;
- }
- case DBG_END_LOCAL: {
- uint16_t reg = DecodeUnsignedLeb128(&stream);
- if (reg >= code_item->registers_size_) {
- LOG(ERROR) << "invalid stream - reg >= reg size (" << reg << " >= "
- << code_item->registers_size_ << ") in " << GetLocation();
- return false;
- }
- // If the register is live, close it properly. Otherwise, closing an already
- // closed register is sloppy, but harmless if no further action is taken.
- if (local_in_reg[reg].is_live_) {
- local_in_reg[reg].end_address_ = address;
- local_cb(context, local_in_reg[reg]);
- local_in_reg[reg].is_live_ = false;
- }
- break;
- }
- case DBG_RESTART_LOCAL: {
- uint16_t reg = DecodeUnsignedLeb128(&stream);
- if (reg >= code_item->registers_size_) {
- LOG(ERROR) << "invalid stream - reg >= reg size (" << reg << " >= "
- << code_item->registers_size_ << ") in " << GetLocation();
- return false;
- }
- // If the register is live, the "restart" is superfluous,
- // and we don't want to mess with the existing start address.
- if (!local_in_reg[reg].is_live_) {
- local_in_reg[reg].start_address_ = address;
- local_in_reg[reg].is_live_ = true;
- }
- break;
- }
- case DBG_SET_PROLOGUE_END:
- case DBG_SET_EPILOGUE_BEGIN:
- break;
- case DBG_SET_FILE:
- DecodeUnsignedLeb128P1(&stream); // name.
- break;
- default:
- address += (opcode - DBG_FIRST_SPECIAL) / DBG_LINE_RANGE;
- break;
- }
- }
-}
-
-bool DexFile::DecodeDebugPositionInfo(const CodeItem* code_item, DexDebugNewPositionCb position_cb,
- void* context) const {
- DCHECK(position_cb != nullptr);
- if (code_item == nullptr) {
- return false;
- }
- const uint8_t* stream = GetDebugInfoStream(code_item);
- if (stream == nullptr) {
- return false;
- }
-
- PositionInfo entry = PositionInfo();
- entry.line_ = DecodeUnsignedLeb128(&stream);
- uint32_t parameters_size = DecodeUnsignedLeb128(&stream);
- for (uint32_t i = 0; i < parameters_size; ++i) {
- DecodeUnsignedLeb128P1(&stream); // Parameter name.
- }
-
- for (;;) {
- uint8_t opcode = *stream++;
- switch (opcode) {
- case DBG_END_SEQUENCE:
- return true; // end of stream.
- case DBG_ADVANCE_PC:
- entry.address_ += DecodeUnsignedLeb128(&stream);
- break;
- case DBG_ADVANCE_LINE:
- entry.line_ += DecodeSignedLeb128(&stream);
- break;
- case DBG_START_LOCAL:
- DecodeUnsignedLeb128(&stream); // reg.
- DecodeUnsignedLeb128P1(&stream); // name.
- DecodeUnsignedLeb128P1(&stream); // descriptor.
- break;
- case DBG_START_LOCAL_EXTENDED:
- DecodeUnsignedLeb128(&stream); // reg.
- DecodeUnsignedLeb128P1(&stream); // name.
- DecodeUnsignedLeb128P1(&stream); // descriptor.
- DecodeUnsignedLeb128P1(&stream); // signature.
- break;
- case DBG_END_LOCAL:
- case DBG_RESTART_LOCAL:
- DecodeUnsignedLeb128(&stream); // reg.
- break;
- case DBG_SET_PROLOGUE_END:
- entry.prologue_end_ = true;
- break;
- case DBG_SET_EPILOGUE_BEGIN:
- entry.epilogue_begin_ = true;
- break;
- case DBG_SET_FILE: {
- uint32_t name_idx = DecodeUnsignedLeb128P1(&stream);
- entry.source_file_ = StringDataByIdx(dex::StringIndex(name_idx));
- break;
- }
- default: {
- int adjopcode = opcode - DBG_FIRST_SPECIAL;
- entry.address_ += adjopcode / DBG_LINE_RANGE;
- entry.line_ += DBG_LINE_BASE + (adjopcode % DBG_LINE_RANGE);
- if (position_cb(context, entry)) {
- return true; // early exit.
- }
- entry.prologue_end_ = false;
- entry.epilogue_begin_ = false;
- break;
- }
- }
- }
-}
-
bool DexFile::LineNumForPcCb(void* raw_context, const PositionInfo& entry) {
LineNumFromPcContext* context = reinterpret_cast<LineNumFromPcContext*>(raw_context);
diff --git a/runtime/dex_file.h b/runtime/dex_file.h
index 5759684c55..6868d525e2 100644
--- a/runtime/dex_file.h
+++ b/runtime/dex_file.h
@@ -772,10 +772,6 @@ class DexFile {
bool epilogue_begin_ = false;
};
- // Callback for "new position table entry".
- // Returning true causes the decoder to stop early.
- typedef bool (*DexDebugNewPositionCb)(void* context, const PositionInfo& entry);
-
struct LocalInfo {
LocalInfo() = default;
@@ -899,11 +895,36 @@ class DexFile {
};
// Returns false if there is no debugging information or if it cannot be decoded.
- bool DecodeDebugLocalInfo(const CodeItem* code_item, bool is_static, uint32_t method_idx,
- DexDebugNewLocalCb local_cb, void* context) const;
+ template<typename NewLocalCallback, typename IndexToStringData, typename TypeIndexToStringData>
+ static bool DecodeDebugLocalInfo(const uint8_t* stream,
+ const std::string& location,
+ const char* declaring_class_descriptor,
+ const std::vector<const char*>& arg_descriptors,
+ const std::string& method_name,
+ bool is_static,
+ uint16_t registers_size,
+ uint16_t ins_size,
+ uint16_t insns_size_in_code_units,
+ IndexToStringData index_to_string_data,
+ TypeIndexToStringData type_index_to_string_data,
+ NewLocalCallback new_local,
+ void* context);
+ template<typename NewLocalCallback>
+ bool DecodeDebugLocalInfo(const CodeItem* code_item,
+ bool is_static,
+ uint32_t method_idx,
+ NewLocalCallback new_local,
+ void* context) const;
// Returns false if there is no debugging information or if it cannot be decoded.
- bool DecodeDebugPositionInfo(const CodeItem* code_item, DexDebugNewPositionCb position_cb,
+ template<typename DexDebugNewPosition, typename IndexToStringData>
+ static bool DecodeDebugPositionInfo(const uint8_t* stream,
+ IndexToStringData index_to_string_data,
+ DexDebugNewPosition position_functor,
+ void* context);
+ template<typename DexDebugNewPosition>
+ bool DecodeDebugPositionInfo(const CodeItem* code_item,
+ DexDebugNewPosition position_functor,
void* context) const;
const char* GetSourceFile(const ClassDef& class_def) const {
diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc
index 4004af2875..67e8a0d02f 100644
--- a/runtime/gc/heap.cc
+++ b/runtime/gc/heap.cc
@@ -132,10 +132,6 @@ static constexpr uint32_t kAllocSpaceBeginForDeterministicAoT = 0x40000000;
// Dump the rosalloc stats on SIGQUIT.
static constexpr bool kDumpRosAllocStatsOnSigQuit = false;
-// Extra added to the heap growth multiplier. Used to adjust the GC ergonomics for the read barrier
-// config.
-static constexpr double kExtraHeapGrowthMultiplier = kUseReadBarrier ? 1.0 : 0.0;
-
static const char* kRegionSpaceName = "main space (region space)";
// If true, we log all GCs in the both the foreground and background. Used for debugging.
@@ -255,8 +251,7 @@ Heap::Heap(size_t initial_size,
min_free_(min_free),
max_free_(max_free),
target_utilization_(target_utilization),
- foreground_heap_growth_multiplier_(
- foreground_heap_growth_multiplier + kExtraHeapGrowthMultiplier),
+ foreground_heap_growth_multiplier_(foreground_heap_growth_multiplier),
total_wait_time_(0),
verify_object_mode_(kVerifyObjectModeDisabled),
disable_moving_gc_count_(0),
@@ -3428,7 +3423,7 @@ collector::GarbageCollector* Heap::FindCollectorByGcType(collector::GcType gc_ty
double Heap::HeapGrowthMultiplier() const {
// If we don't care about pause times we are background, so return 1.0.
- if (!CareAboutPauseTimes() || IsLowMemoryMode()) {
+ if (!CareAboutPauseTimes()) {
return 1.0;
}
return foreground_heap_growth_multiplier_;
diff --git a/runtime/parsed_options.cc b/runtime/parsed_options.cc
index 9841a95746..71d7b6c34d 100644
--- a/runtime/parsed_options.cc
+++ b/runtime/parsed_options.cc
@@ -121,7 +121,7 @@ std::unique_ptr<RuntimeParser> ParsedOptions::MakeParser(bool ignore_unrecognize
.WithType<double>().WithRange(0.1, 0.9)
.IntoKey(M::HeapTargetUtilization)
.Define("-XX:ForegroundHeapGrowthMultiplier=_")
- .WithType<double>().WithRange(0.1, 1.0)
+ .WithType<double>().WithRange(0.1, 5.0)
.IntoKey(M::ForegroundHeapGrowthMultiplier)
.Define("-XX:ParallelGCThreads=_")
.WithType<unsigned int>()
diff --git a/runtime/plugin.cc b/runtime/plugin.cc
index 731967c738..6aa078771b 100644
--- a/runtime/plugin.cc
+++ b/runtime/plugin.cc
@@ -74,10 +74,8 @@ bool Plugin::Unload() {
LOG(WARNING) << this << " does not include a deinitialization function";
}
dlopen_handle_ = nullptr;
- if (dlclose(handle) != 0) {
- LOG(ERROR) << this << " failed to dlclose: " << dlerror();
- ret = false;
- }
+ // Don't bother to actually dlclose since we are shutting down anyway and there might be small
+ // amounts of processing still being done.
return ret;
}
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 8eb4a07b64..7f2f7895db 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -174,6 +174,11 @@ static constexpr double kLowMemoryMinLoadFactor = 0.5;
static constexpr double kLowMemoryMaxLoadFactor = 0.8;
static constexpr double kNormalMinLoadFactor = 0.4;
static constexpr double kNormalMaxLoadFactor = 0.7;
+
+// Extra added to the default heap growth multiplier. Used to adjust the GC ergonomics for the read
+// barrier config.
+static constexpr double kExtraDefaultHeapGrowthMultiplier = kUseReadBarrier ? 1.0 : 0.0;
+
Runtime* Runtime::instance_ = nullptr;
struct TraceConfig {
@@ -1152,13 +1157,22 @@ bool Runtime::Init(RuntimeArgumentMap&& runtime_options_in) {
// agents_.push_back(lib);
// }
+ float foreground_heap_growth_multiplier;
+ if (is_low_memory_mode_ && !runtime_options.Exists(Opt::ForegroundHeapGrowthMultiplier)) {
+ // If low memory mode, use 1.0 as the multiplier by default.
+ foreground_heap_growth_multiplier = 1.0f;
+ } else {
+ foreground_heap_growth_multiplier =
+ runtime_options.GetOrDefault(Opt::ForegroundHeapGrowthMultiplier) +
+ kExtraDefaultHeapGrowthMultiplier;
+ }
XGcOption xgc_option = runtime_options.GetOrDefault(Opt::GcOption);
heap_ = new gc::Heap(runtime_options.GetOrDefault(Opt::MemoryInitialSize),
runtime_options.GetOrDefault(Opt::HeapGrowthLimit),
runtime_options.GetOrDefault(Opt::HeapMinFree),
runtime_options.GetOrDefault(Opt::HeapMaxFree),
runtime_options.GetOrDefault(Opt::HeapTargetUtilization),
- runtime_options.GetOrDefault(Opt::ForegroundHeapGrowthMultiplier),
+ foreground_heap_growth_multiplier,
runtime_options.GetOrDefault(Opt::MemoryMaximumSize),
runtime_options.GetOrDefault(Opt::NonMovingSpaceCapacity),
runtime_options.GetOrDefault(Opt::Image),
diff --git a/runtime/signal_catcher.cc b/runtime/signal_catcher.cc
index b50879f0a9..a1f14be0f1 100644
--- a/runtime/signal_catcher.cc
+++ b/runtime/signal_catcher.cc
@@ -170,7 +170,7 @@ void SignalCatcher::Output(const std::string& s) {
#if defined(ART_TARGET_ANDROID)
if (use_tombstoned_stack_trace_fd_ && !tombstoned_notify_completion(tombstone_fd)) {
- LOG(WARNING) << "Unable to notify tombstoned of dump completion.";
+ PLOG(WARNING) << "Unable to notify tombstoned of dump completion";
}
#endif
}
diff --git a/runtime/ti/agent.cc b/runtime/ti/agent.cc
index 6ff966678a..20e297c991 100644
--- a/runtime/ti/agent.cc
+++ b/runtime/ti/agent.cc
@@ -113,7 +113,8 @@ void Agent::Unload() {
if (onunload_ != nullptr) {
onunload_(Runtime::Current()->GetJavaVM());
}
- dlclose(dlopen_handle_);
+ // Don't actually dlclose since some agents assume they will never get unloaded. Since this only
+ // happens when the runtime is shutting down anyway this isn't a big deal.
dlopen_handle_ = nullptr;
onload_ = nullptr;
onattach_ = nullptr;
diff --git a/test/Android.bp b/test/Android.bp
index b737345729..16b30f988f 100644
--- a/test/Android.bp
+++ b/test/Android.bp
@@ -74,7 +74,7 @@ art_cc_defaults {
],
target: {
- linux_glibc: {
+ linux: {
ldflags: [
// Allow jni_compiler_test to find Java_MyClassNatives_bar
// within itself using dlopen(NULL, ...).
@@ -83,9 +83,6 @@ art_cc_defaults {
"-Wl,-u,Java_MyClassNatives_bar",
"-Wl,-u,Java_MyClassNatives_sbar",
],
- shared_libs: [
- "libziparchive",
- ],
cflags: [
// gtest issue
"-Wno-used-but-marked-unused",
@@ -93,23 +90,15 @@ art_cc_defaults {
"-Wno-missing-noreturn",
],
},
- android: {
- ldflags: [
- // Allow jni_compiler_test to find Java_MyClassNatives_bar
- // within itself using dlopen(NULL, ...).
- "-Wl,--export-dynamic",
- "-Wl,-u,Java_MyClassNatives_bar",
- "-Wl,-u,Java_MyClassNatives_sbar",
+ host: {
+ shared_libs: [
+ "libziparchive",
],
+ },
+ android: {
shared_libs: [
"liblog",
],
- cflags: [
- // gtest issue
- "-Wno-used-but-marked-unused",
- "-Wno-deprecated",
- "-Wno-missing-noreturn",
- ],
},
},
}
@@ -135,15 +124,7 @@ art_cc_defaults {
android64: {
cflags: ["-DART_TARGET_NATIVETEST_DIR=/data/nativetest64/art"],
},
- android: {
- cflags: [
- // gtest issue
- "-Wno-used-but-marked-unused",
- "-Wno-deprecated",
- "-Wno-missing-noreturn",
- ],
- },
- linux_glibc: {
+ linux: {
cflags: [
// gtest issue
"-Wno-used-but-marked-unused",
diff --git a/tools/libjdwp_art_failures.txt b/tools/libjdwp_art_failures.txt
index bd422e964e..1812177e2f 100644
--- a/tools/libjdwp_art_failures.txt
+++ b/tools/libjdwp_art_failures.txt
@@ -71,34 +71,6 @@
"org.apache.harmony.jpda.tests.jdwp.EventModifiers.InstanceOnlyModifierTest#testMethodExit",
"org.apache.harmony.jpda.tests.jdwp.EventModifiers.InstanceOnlyModifierTest#testMethodExitWithReturnValue" ]
},
-/* TODO Investigate these failures more closely */
-{
- description: "Tests that fail when run on the chromium buildbots against the prebuilt libjdwp.so in certain configurations",
- result: EXEC_FAILED,
- bug: 67497270,
- names: [
- "org.apache.harmony.jpda.tests.jdwp.Events.CombinedEvents003Test#testCombinedEvents003_01",
- "org.apache.harmony.jpda.tests.jdwp.Events.CombinedEventsTest#testCombinedEvents_01",
- "org.apache.harmony.jpda.tests.jdwp.Events.CombinedEventsTest#testCombinedEvents_02",
- "org.apache.harmony.jpda.tests.jdwp.Events.CombinedEventsTest#testCombinedEvents_03",
- "org.apache.harmony.jpda.tests.jdwp.Events.CombinedEventsTest#testCombinedEvents_04",
- "org.apache.harmony.jpda.tests.jdwp.Events.CombinedEventsTest#testCombinedEvents_05",
- "org.apache.harmony.jpda.tests.jdwp.Events.CombinedEventsTest#testCombinedEvents_06",
- "org.apache.harmony.jpda.tests.jdwp.Events.VMDeathTest#testVMDeathEvent",
- "org.apache.harmony.jpda.tests.jdwp.MultiSession.ClassPrepareTest#testClassPrepare001",
- "org.apache.harmony.jpda.tests.jdwp.MultiSession.ExceptionTest#testException001",
- "org.apache.harmony.jpda.tests.jdwp.MultiSession.FieldAccessTest#testFieldAccess001",
- "org.apache.harmony.jpda.tests.jdwp.MultiSession.FieldModificationTest#testFieldModification001",
- "org.apache.harmony.jpda.tests.jdwp.MultiSession.SingleStepTest#testSingleStep001",
- "org.apache.harmony.jpda.tests.jdwp.MultiSession.VMDeathTest#testVMDeathRequest",
- "org.apache.harmony.jpda.tests.jdwp.ReferenceType.SignatureWithGenericTest#testSignatureWithGeneric001",
- "org.apache.harmony.jpda.tests.jdwp.StackFrame.GetValues002Test#testGetValues005_Int2",
- "org.apache.harmony.jpda.tests.jdwp.VirtualMachine.SetDefaultStratumTest#testSetDefaultStratum001",
- "org.apache.harmony.jpda.tests.jdwp.ThreadReference.StatusTest#testStatus001",
- "org.apache.harmony.jpda.tests.jdwp.VirtualMachine.AllClassesTest#testAllClasses002",
- "org.apache.harmony.jpda.tests.jdwp.VirtualMachine.AllClassesWithGenericTest#testAllClassesWithGeneric001"
- ]
-},
/* TODO Categorize these failures more. */
{
description: "Tests that fail on both ART and RI. These tests are likely incorrect",
diff --git a/tools/wrapagentproperties/wrapagentproperties.cc b/tools/wrapagentproperties/wrapagentproperties.cc
index dca627046e..67d5279672 100644
--- a/tools/wrapagentproperties/wrapagentproperties.cc
+++ b/tools/wrapagentproperties/wrapagentproperties.cc
@@ -45,7 +45,6 @@ static std::mutex unload_mutex;
struct Unloader {
AgentUnloadFunction unload;
- void* dlclose_handle;
};
static std::vector<Unloader> unload_functions;
@@ -71,7 +70,6 @@ struct ProxyJavaVM {
std::lock_guard<std::mutex> lk(unload_mutex);
unload_functions.push_back({
reinterpret_cast<AgentUnloadFunction>(dlsym(dlopen_handle, kOnUnload)),
- dlopen_handle
});
}
attach = reinterpret_cast<AgentLoadFunction>(dlsym(dlopen_handle, kOnAttach));
@@ -337,7 +335,7 @@ extern "C" JNIEXPORT void JNICALL Agent_OnUnload(JavaVM* jvm) {
std::lock_guard<std::mutex> lk(unload_mutex);
for (const Unloader& u : unload_functions) {
u.unload(jvm);
- dlclose(u.dlclose_handle);
+ // Don't dlclose since some agents expect to still have code loaded after this.
}
unload_functions.clear();
}