summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler/dex/mir_graph.cc80
-rw-r--r--compiler/dex/quick/arm64/codegen_arm64.h1
-rw-r--r--compiler/dex/quick/arm64/fp_arm64.cc6
-rw-r--r--compiler/dex/quick/arm64/int_arm64.cc26
-rw-r--r--compiler/dex/quick/mir_to_lir.h2
-rw-r--r--compiler/utils/arm64/assembler_arm64.cc24
-rw-r--r--compiler/utils/arm64/assembler_arm64.h28
-rw-r--r--oatdump/oatdump.cc10
-rw-r--r--runtime/debugger.cc5
-rw-r--r--runtime/gc/heap.cc2
-rw-r--r--runtime/parsed_options.cc6
-rw-r--r--runtime/parsed_options.h2
-rw-r--r--runtime/quick_exception_handler.cc5
-rw-r--r--runtime/runtime.cc11
-rw-r--r--runtime/runtime.h7
-rw-r--r--runtime/verifier/method_verifier.cc58
-rw-r--r--runtime/verifier/method_verifier.h9
17 files changed, 144 insertions, 138 deletions
diff --git a/compiler/dex/mir_graph.cc b/compiler/dex/mir_graph.cc
index edfd57fd8a..574b6ea66f 100644
--- a/compiler/dex/mir_graph.cc
+++ b/compiler/dex/mir_graph.cc
@@ -274,7 +274,7 @@ BasicBlock* MIRGraph::SplitBlock(DexOffset code_offset,
*/
BasicBlock* MIRGraph::FindBlock(DexOffset code_offset, bool split, bool create,
BasicBlock** immed_pred_block_p) {
- if (code_offset >= cu_->code_item->insns_size_in_code_units_) {
+ if (code_offset >= current_code_item_->insns_size_in_code_units_) {
return NULL;
}
@@ -348,10 +348,10 @@ bool MIRGraph::IsBadMonitorExitCatch(NarrowDexOffset monitor_exit_offset,
// (We don't want to ignore all monitor-exit catches since one could enclose a synchronized
// block in a try-block and catch the NPE, Error or Throwable and we should let it through;
// even though a throwing monitor-exit certainly indicates a bytecode error.)
- const Instruction* monitor_exit = Instruction::At(cu_->code_item->insns_ + monitor_exit_offset);
+ const Instruction* monitor_exit = Instruction::At(current_code_item_->insns_ + monitor_exit_offset);
DCHECK(monitor_exit->Opcode() == Instruction::MONITOR_EXIT);
int monitor_reg = monitor_exit->VRegA_11x();
- const Instruction* check_insn = Instruction::At(cu_->code_item->insns_ + catch_offset);
+ const Instruction* check_insn = Instruction::At(current_code_item_->insns_ + catch_offset);
DCHECK(check_insn->Opcode() == Instruction::MOVE_EXCEPTION);
if (check_insn->VRegA_11x() == monitor_reg) {
// Unexpected move-exception to the same register. Probably not the pattern we're looking for.
@@ -1228,8 +1228,6 @@ char* MIRGraph::GetDalvikDisassembly(const MIR* mir) {
bool nop = false;
SSARepresentation* ssa_rep = mir->ssa_rep;
Instruction::Format dalvik_format = Instruction::k10x; // Default to no-operand format.
- int defs = (ssa_rep != NULL) ? ssa_rep->num_defs : 0;
- int uses = (ssa_rep != NULL) ? ssa_rep->num_uses : 0;
// Handle special cases.
if ((opcode == kMirOpCheck) || (opcode == kMirOpCheckPart2)) {
@@ -1238,8 +1236,6 @@ char* MIRGraph::GetDalvikDisassembly(const MIR* mir) {
// Recover the original Dex instruction.
insn = mir->meta.throw_insn->dalvikInsn;
ssa_rep = mir->meta.throw_insn->ssa_rep;
- defs = ssa_rep->num_defs;
- uses = ssa_rep->num_uses;
opcode = insn.opcode;
} else if (opcode == kMirOpNop) {
str.append("[");
@@ -1248,6 +1244,8 @@ char* MIRGraph::GetDalvikDisassembly(const MIR* mir) {
opcode = insn.opcode;
nop = true;
}
+ int defs = (ssa_rep != NULL) ? ssa_rep->num_defs : 0;
+ int uses = (ssa_rep != NULL) ? ssa_rep->num_uses : 0;
if (MIR::DecodedInstruction::IsPseudoMirOp(opcode)) {
str.append(extended_mir_op_names_[opcode - kMirOpFirst]);
@@ -1259,40 +1257,21 @@ char* MIRGraph::GetDalvikDisassembly(const MIR* mir) {
if (opcode == kMirOpPhi) {
BasicBlockId* incoming = mir->meta.phi_incoming;
- str.append(StringPrintf(" %s = (%s",
- GetSSANameWithConst(ssa_rep->defs[0], true).c_str(),
- GetSSANameWithConst(ssa_rep->uses[0], true).c_str()));
- str.append(StringPrintf(":%d", incoming[0]));
- int i;
- for (i = 1; i < uses; i++) {
- str.append(StringPrintf(", %s:%d",
- GetSSANameWithConst(ssa_rep->uses[i], true).c_str(),
- incoming[i]));
- }
- str.append(")");
- } else if ((flags & Instruction::kBranch) != 0) {
- // For branches, decode the instructions to print out the branch targets.
- int offset = 0;
- switch (dalvik_format) {
- case Instruction::k21t:
- str.append(StringPrintf(" %s,", GetSSANameWithConst(ssa_rep->uses[0], false).c_str()));
- offset = insn.vB;
- break;
- case Instruction::k22t:
- str.append(StringPrintf(" %s, %s,", GetSSANameWithConst(ssa_rep->uses[0], false).c_str(),
- GetSSANameWithConst(ssa_rep->uses[1], false).c_str()));
- offset = insn.vC;
- break;
- case Instruction::k10t:
- case Instruction::k20t:
- case Instruction::k30t:
- offset = insn.vA;
- break;
- default:
- LOG(FATAL) << "Unexpected branch format " << dalvik_format << " from " << insn.opcode;
+ if (defs > 0 && uses > 0) {
+ str.append(StringPrintf(" %s = (%s",
+ GetSSANameWithConst(ssa_rep->defs[0], true).c_str(),
+ GetSSANameWithConst(ssa_rep->uses[0], true).c_str()));
+ str.append(StringPrintf(":%d", incoming[0]));
+ int i;
+ for (i = 1; i < uses; i++) {
+ str.append(StringPrintf(", %s:%d",
+ GetSSANameWithConst(ssa_rep->uses[i], true).c_str(),
+ incoming[i]));
+ }
+ str.append(")");
+ } else {
+ str.append(StringPrintf(" v%d", mir->dalvikInsn.vA));
}
- str.append(StringPrintf(" 0x%x (%c%x)", mir->offset + offset,
- offset > 0 ? '+' : '-', offset > 0 ? offset : -offset));
} else {
// For invokes-style formats, treat wide regs as a pair of singles.
bool show_singles = ((dalvik_format == Instruction::k35c) ||
@@ -1339,6 +1318,27 @@ char* MIRGraph::GetDalvikDisassembly(const MIR* mir) {
// Nothing left to print.
}
}
+ if ((flags & Instruction::kBranch) != 0) {
+ // For branches, decode the instructions to print out the branch targets.
+ int offset = 0;
+ switch (dalvik_format) {
+ case Instruction::k21t:
+ offset = insn.vB;
+ break;
+ case Instruction::k22t:
+ offset = insn.vC;
+ break;
+ case Instruction::k10t:
+ case Instruction::k20t:
+ case Instruction::k30t:
+ offset = insn.vA;
+ break;
+ default:
+ LOG(FATAL) << "Unexpected branch format " << dalvik_format << " from " << insn.opcode;
+ }
+ str.append(StringPrintf(" 0x%x (%c%x)", mir->offset + offset,
+ offset > 0 ? '+' : '-', offset > 0 ? offset : -offset));
+ }
}
if (nop) {
str.append("]--optimized away");
diff --git a/compiler/dex/quick/arm64/codegen_arm64.h b/compiler/dex/quick/arm64/codegen_arm64.h
index 3e1c18baf4..be10dd702e 100644
--- a/compiler/dex/quick/arm64/codegen_arm64.h
+++ b/compiler/dex/quick/arm64/codegen_arm64.h
@@ -167,6 +167,7 @@ class Arm64Mir2Lir FINAL : public Mir2Lir {
bool GenInlinedRound(CallInfo* info, bool is_double) OVERRIDE;
bool GenInlinedPeek(CallInfo* info, OpSize size) OVERRIDE;
bool GenInlinedPoke(CallInfo* info, OpSize size) OVERRIDE;
+ bool GenInlinedAbsInt(CallInfo* info) OVERRIDE;
bool GenInlinedAbsLong(CallInfo* info) OVERRIDE;
bool GenInlinedArrayCopyCharArray(CallInfo* info) OVERRIDE;
void GenIntToLong(RegLocation rl_dest, RegLocation rl_src) OVERRIDE;
diff --git a/compiler/dex/quick/arm64/fp_arm64.cc b/compiler/dex/quick/arm64/fp_arm64.cc
index d0b2636453..5d63dd0ee2 100644
--- a/compiler/dex/quick/arm64/fp_arm64.cc
+++ b/compiler/dex/quick/arm64/fp_arm64.cc
@@ -353,7 +353,8 @@ bool Arm64Mir2Lir::GenInlinedAbsFloat(CallInfo* info) {
if (reg_class == kFPReg) {
NewLIR2(kA64Fabs2ff, rl_result.reg.GetReg(), rl_src.reg.GetReg());
} else {
- NewLIR4(kA64Ubfm4rrdd, rl_result.reg.GetReg(), rl_src.reg.GetReg(), 0, 30);
+ // Clear the sign bit in an integer register.
+ OpRegRegImm(kOpAnd, rl_result.reg, rl_src.reg, 0x7fffffff);
}
StoreValue(rl_dest, rl_result);
return true;
@@ -371,7 +372,8 @@ bool Arm64Mir2Lir::GenInlinedAbsDouble(CallInfo* info) {
if (reg_class == kFPReg) {
NewLIR2(FWIDE(kA64Fabs2ff), rl_result.reg.GetReg(), rl_src.reg.GetReg());
} else {
- NewLIR4(WIDE(kA64Ubfm4rrdd), rl_result.reg.GetReg(), rl_src.reg.GetReg(), 0, 62);
+ // Clear the sign bit in an integer register.
+ OpRegRegImm64(kOpAnd, rl_result.reg, rl_src.reg, 0x7fffffffffffffff);
}
StoreValueWide(rl_dest, rl_result);
return true;
diff --git a/compiler/dex/quick/arm64/int_arm64.cc b/compiler/dex/quick/arm64/int_arm64.cc
index d1b9c81d09..e4a895e043 100644
--- a/compiler/dex/quick/arm64/int_arm64.cc
+++ b/compiler/dex/quick/arm64/int_arm64.cc
@@ -646,16 +646,32 @@ RegLocation Arm64Mir2Lir::GenDivRem(RegLocation rl_dest, RegStorage r_src1, RegS
return rl_result;
}
+bool Arm64Mir2Lir::GenInlinedAbsInt(CallInfo* info) {
+ RegLocation rl_src = info->args[0];
+ rl_src = LoadValue(rl_src, kCoreReg);
+ RegLocation rl_dest = InlineTarget(info);
+ RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
+
+ // Compare the source value with zero. Write the negated value to the result if
+ // negative, otherwise write the original value.
+ OpRegImm(kOpCmp, rl_src.reg, 0);
+ NewLIR4(kA64Csneg4rrrc, rl_result.reg.GetReg(), rl_src.reg.GetReg(), rl_src.reg.GetReg(),
+ kArmCondPl);
+ StoreValue(rl_dest, rl_result);
+ return true;
+}
+
bool Arm64Mir2Lir::GenInlinedAbsLong(CallInfo* info) {
RegLocation rl_src = info->args[0];
rl_src = LoadValueWide(rl_src, kCoreReg);
RegLocation rl_dest = InlineTargetWide(info);
RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
- RegStorage sign_reg = AllocTempWide();
- // abs(x) = y<=x>>63, (x+y)^y.
- OpRegRegImm(kOpAsr, sign_reg, rl_src.reg, 63);
- OpRegRegReg(kOpAdd, rl_result.reg, rl_src.reg, sign_reg);
- OpRegReg(kOpXor, rl_result.reg, sign_reg);
+
+ // Compare the source value with zero. Write the negated value to the result if
+ // negative, otherwise write the original value.
+ OpRegImm(kOpCmp, rl_src.reg, 0);
+ NewLIR4(WIDE(kA64Csneg4rrrc), rl_result.reg.GetReg(), rl_src.reg.GetReg(),
+ rl_src.reg.GetReg(), kArmCondPl);
StoreValueWide(rl_dest, rl_result);
return true;
}
diff --git a/compiler/dex/quick/mir_to_lir.h b/compiler/dex/quick/mir_to_lir.h
index 573bd9143d..8e737280e0 100644
--- a/compiler/dex/quick/mir_to_lir.h
+++ b/compiler/dex/quick/mir_to_lir.h
@@ -964,7 +964,7 @@ class Mir2Lir : public Backend {
bool GenInlinedStringIsEmptyOrLength(CallInfo* info, bool is_empty);
virtual bool GenInlinedReverseBits(CallInfo* info, OpSize size);
bool GenInlinedReverseBytes(CallInfo* info, OpSize size);
- bool GenInlinedAbsInt(CallInfo* info);
+ virtual bool GenInlinedAbsInt(CallInfo* info);
virtual bool GenInlinedAbsLong(CallInfo* info);
virtual bool GenInlinedAbsFloat(CallInfo* info) = 0;
virtual bool GenInlinedAbsDouble(CallInfo* info) = 0;
diff --git a/compiler/utils/arm64/assembler_arm64.cc b/compiler/utils/arm64/assembler_arm64.cc
index 3f90f21b66..3edf59be2a 100644
--- a/compiler/utils/arm64/assembler_arm64.cc
+++ b/compiler/utils/arm64/assembler_arm64.cc
@@ -21,6 +21,8 @@
#include "thread.h"
#include "utils.h"
+using namespace vixl; // NOLINT(build/namespaces)
+
namespace art {
namespace arm64 {
@@ -75,7 +77,7 @@ void Arm64Assembler::AddConstant(Register rd, int32_t value, Condition cond) {
void Arm64Assembler::AddConstant(Register rd, Register rn, int32_t value,
Condition cond) {
- if ((cond == AL) || (cond == NV)) {
+ if ((cond == al) || (cond == nv)) {
// VIXL macro-assembler handles all variants.
___ Add(reg_x(rd), reg_x(rn), value);
} else {
@@ -85,7 +87,7 @@ void Arm64Assembler::AddConstant(Register rd, Register rn, int32_t value,
temps.Exclude(reg_x(rd), reg_x(rn));
vixl::Register temp = temps.AcquireX();
___ Add(temp, reg_x(rn), value);
- ___ Csel(reg_x(rd), temp, reg_x(rd), COND_OP(cond));
+ ___ Csel(reg_x(rd), temp, reg_x(rd), cond);
}
}
@@ -195,7 +197,7 @@ void Arm64Assembler::StoreSpanning(FrameOffset dest_off, ManagedRegister m_sourc
// Load routines.
void Arm64Assembler::LoadImmediate(Register dest, int32_t value,
Condition cond) {
- if ((cond == AL) || (cond == NV)) {
+ if ((cond == al) || (cond == nv)) {
___ Mov(reg_x(dest), value);
} else {
// temp = value
@@ -205,9 +207,9 @@ void Arm64Assembler::LoadImmediate(Register dest, int32_t value,
temps.Exclude(reg_x(dest));
vixl::Register temp = temps.AcquireX();
___ Mov(temp, value);
- ___ Csel(reg_x(dest), temp, reg_x(dest), COND_OP(cond));
+ ___ Csel(reg_x(dest), temp, reg_x(dest), cond);
} else {
- ___ Csel(reg_x(dest), reg_x(XZR), reg_x(dest), COND_OP(cond));
+ ___ Csel(reg_x(dest), reg_x(XZR), reg_x(dest), cond);
}
}
}
@@ -557,11 +559,11 @@ void Arm64Assembler::CreateHandleScopeEntry(ManagedRegister m_out_reg, FrameOffs
}
___ Cmp(reg_w(in_reg.AsOverlappingCoreRegisterLow()), 0);
if (!out_reg.Equals(in_reg)) {
- LoadImmediate(out_reg.AsCoreRegister(), 0, EQ);
+ LoadImmediate(out_reg.AsCoreRegister(), 0, eq);
}
- AddConstant(out_reg.AsCoreRegister(), SP, handle_scope_offs.Int32Value(), NE);
+ AddConstant(out_reg.AsCoreRegister(), SP, handle_scope_offs.Int32Value(), ne);
} else {
- AddConstant(out_reg.AsCoreRegister(), SP, handle_scope_offs.Int32Value(), AL);
+ AddConstant(out_reg.AsCoreRegister(), SP, handle_scope_offs.Int32Value(), al);
}
}
@@ -577,9 +579,9 @@ void Arm64Assembler::CreateHandleScopeEntry(FrameOffset out_off, FrameOffset han
// e.g. scratch = (scratch == 0) ? 0 : (SP+handle_scope_offset)
___ Cmp(reg_w(scratch.AsOverlappingCoreRegisterLow()), 0);
// Move this logic in add constants with flags.
- AddConstant(scratch.AsCoreRegister(), SP, handle_scope_offset.Int32Value(), NE);
+ AddConstant(scratch.AsCoreRegister(), SP, handle_scope_offset.Int32Value(), ne);
} else {
- AddConstant(scratch.AsCoreRegister(), SP, handle_scope_offset.Int32Value(), AL);
+ AddConstant(scratch.AsCoreRegister(), SP, handle_scope_offset.Int32Value(), al);
}
StoreToOffset(scratch.AsCoreRegister(), SP, out_off.Int32Value());
}
@@ -593,7 +595,7 @@ void Arm64Assembler::LoadReferenceFromHandleScope(ManagedRegister m_out_reg,
vixl::Label exit;
if (!out_reg.Equals(in_reg)) {
// FIXME: Who sets the flags here?
- LoadImmediate(out_reg.AsCoreRegister(), 0, EQ);
+ LoadImmediate(out_reg.AsCoreRegister(), 0, eq);
}
___ Cbz(reg_x(in_reg.AsCoreRegister()), &exit);
LoadFromOffset(out_reg.AsCoreRegister(), in_reg.AsCoreRegister(), 0);
diff --git a/compiler/utils/arm64/assembler_arm64.h b/compiler/utils/arm64/assembler_arm64.h
index ab4999a2bc..788950b0b4 100644
--- a/compiler/utils/arm64/assembler_arm64.h
+++ b/compiler/utils/arm64/assembler_arm64.h
@@ -34,28 +34,6 @@ namespace art {
namespace arm64 {
#define MEM_OP(x...) vixl::MemOperand(x)
-#define COND_OP(x) static_cast<vixl::Condition>(x)
-
-enum Condition {
- kNoCondition = -1,
- EQ = 0,
- NE = 1,
- HS = 2,
- LO = 3,
- MI = 4,
- PL = 5,
- VS = 6,
- VC = 7,
- HI = 8,
- LS = 9,
- GE = 10,
- LT = 11,
- GT = 12,
- LE = 13,
- AL = 14, // Always.
- NV = 15, // Behaves as always/al.
- kMaxCondition = 16,
-};
enum LoadOperandType {
kLoadSignedByte,
@@ -225,15 +203,15 @@ class Arm64Assembler FINAL : public Assembler {
void StoreSToOffset(SRegister source, Register base, int32_t offset);
void StoreDToOffset(DRegister source, Register base, int32_t offset);
- void LoadImmediate(Register dest, int32_t value, Condition cond = AL);
+ void LoadImmediate(Register dest, int32_t value, vixl::Condition cond = vixl::al);
void Load(Arm64ManagedRegister dst, Register src, int32_t src_offset, size_t size);
void LoadWFromOffset(LoadOperandType type, WRegister dest,
Register base, int32_t offset);
void LoadFromOffset(Register dest, Register base, int32_t offset);
void LoadSFromOffset(SRegister dest, Register base, int32_t offset);
void LoadDFromOffset(DRegister dest, Register base, int32_t offset);
- void AddConstant(Register rd, int32_t value, Condition cond = AL);
- void AddConstant(Register rd, Register rn, int32_t value, Condition cond = AL);
+ void AddConstant(Register rd, int32_t value, vixl::Condition cond = vixl::al);
+ void AddConstant(Register rd, Register rn, int32_t value, vixl::Condition cond = vixl::al);
// Vixl buffer.
byte* vixl_buf_;
diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc
index 75bc49b7d4..2114ada055 100644
--- a/oatdump/oatdump.cc
+++ b/oatdump/oatdump.cc
@@ -427,12 +427,13 @@ class OatDumper {
Runtime* runtime = Runtime::Current();
if (runtime != nullptr) {
ScopedObjectAccess soa(Thread::Current());
- StackHandleScope<1> hs(soa.Self());
+ StackHandleScope<2> hs(soa.Self());
Handle<mirror::DexCache> dex_cache(
hs.NewHandle(runtime->GetClassLinker()->FindDexCache(dex_file)));
NullHandle<mirror::ClassLoader> class_loader;
+ Handle<mirror::ArtMethod> method(hs.NewHandle<mirror::ArtMethod>(nullptr));
verifier::MethodVerifier verifier(&dex_file, &dex_cache, &class_loader, &class_def,
- code_item, dex_method_idx, nullptr, method_access_flags,
+ code_item, dex_method_idx, method, method_access_flags,
true, true, true);
verifier.Verify();
DumpCode(*indent2_os, &verifier, oat_method, code_item);
@@ -698,12 +699,13 @@ class OatDumper {
uint32_t method_access_flags) {
if ((method_access_flags & kAccNative) == 0) {
ScopedObjectAccess soa(Thread::Current());
- StackHandleScope<2> hs(soa.Self());
+ StackHandleScope<3> hs(soa.Self());
Handle<mirror::DexCache> dex_cache(
hs.NewHandle(Runtime::Current()->GetClassLinker()->FindDexCache(*dex_file)));
auto class_loader(hs.NewHandle<mirror::ClassLoader>(nullptr));
+ Handle<mirror::ArtMethod> method(hs.NewHandle<mirror::ArtMethod>(nullptr));
verifier::MethodVerifier::VerifyMethodAndDump(os, dex_method_idx, dex_file, dex_cache,
- class_loader, &class_def, code_item, nullptr,
+ class_loader, &class_def, code_item, method,
method_access_flags);
}
}
diff --git a/runtime/debugger.cc b/runtime/debugger.cc
index 6d2f21e1e5..5b00a37f07 100644
--- a/runtime/debugger.cc
+++ b/runtime/debugger.cc
@@ -3031,12 +3031,13 @@ static bool IsMethodPossiblyInlined(Thread* self, mirror::ArtMethod* m)
// should never be null. We could just check we never encounter this case.
return false;
}
- StackHandleScope<2> hs(self);
+ StackHandleScope<3> hs(self);
mirror::Class* declaring_class = m->GetDeclaringClass();
Handle<mirror::DexCache> dex_cache(hs.NewHandle(declaring_class->GetDexCache()));
Handle<mirror::ClassLoader> class_loader(hs.NewHandle(declaring_class->GetClassLoader()));
+ Handle<mirror::ArtMethod> method(hs.NewHandle(m));
verifier::MethodVerifier verifier(dex_cache->GetDexFile(), &dex_cache, &class_loader,
- &m->GetClassDef(), code_item, m->GetDexMethodIndex(), m,
+ &m->GetClassDef(), code_item, m->GetDexMethodIndex(), method,
m->GetAccessFlags(), false, true, false);
// Note: we don't need to verify the method.
return InlineMethodAnalyser::AnalyseMethodCode(&verifier, nullptr);
diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc
index f0b7685acf..1e01164287 100644
--- a/runtime/gc/heap.cc
+++ b/runtime/gc/heap.cc
@@ -224,7 +224,7 @@ Heap::Heap(size_t initial_size, size_t growth_limit, size_t min_free, size_t max
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
*/
bool support_homogeneous_space_compaction =
- background_collector_type == gc::kCollectorTypeHomogeneousSpaceCompact ||
+ background_collector_type_ == gc::kCollectorTypeHomogeneousSpaceCompact ||
use_homogeneous_space_compaction_for_oom;
// We may use the same space the main space for the non moving space if we don't need to compact
// from the main space.
diff --git a/runtime/parsed_options.cc b/runtime/parsed_options.cc
index 26360d77e2..9757ad9a9e 100644
--- a/runtime/parsed_options.cc
+++ b/runtime/parsed_options.cc
@@ -394,10 +394,6 @@ bool ParsedOptions::Parse(const RuntimeOptions& options, bool ignore_unrecognize
} else if (option == "-XX:IgnoreMaxFootprint") {
ignore_max_footprint_ = true;
} else if (option == "-XX:LowMemoryMode") {
- if (background_collector_type_ == gc::kCollectorTypeHomogeneousSpaceCompact) {
- // Use semispace instead of homogenous space compact for low memory mode.
- background_collector_type_ = gc::kCollectorTypeSS;
- }
low_memory_mode_ = true;
// TODO Might want to turn off must_relocate here.
} else if (option == "-XX:UseTLAB") {
@@ -613,7 +609,7 @@ bool ParsedOptions::Parse(const RuntimeOptions& options, bool ignore_unrecognize
return false;
}
} else if (StartsWith(option, "-XX:NativeBridge=")) {
- if (!ParseStringAfterChar(option, '=', &native_bridge_library_path_)) {
+ if (!ParseStringAfterChar(option, '=', &native_bridge_library_filename_)) {
return false;
}
} else if (StartsWith(option, "-ea") ||
diff --git a/runtime/parsed_options.h b/runtime/parsed_options.h
index 1afd610a53..5c71f9895c 100644
--- a/runtime/parsed_options.h
+++ b/runtime/parsed_options.h
@@ -46,7 +46,7 @@ class ParsedOptions {
bool check_jni_;
bool force_copy_;
std::string jni_trace_;
- std::string native_bridge_library_path_;
+ std::string native_bridge_library_filename_;
CompilerCallbacks* compiler_callbacks_;
bool is_zygote_;
bool must_relocate_;
diff --git a/runtime/quick_exception_handler.cc b/runtime/quick_exception_handler.cc
index 98eeda7263..1e933a2b8c 100644
--- a/runtime/quick_exception_handler.cc
+++ b/runtime/quick_exception_handler.cc
@@ -206,12 +206,13 @@ class DeoptimizeStackVisitor FINAL : public StackVisitor {
const Instruction* inst = Instruction::At(code_item->insns_ + dex_pc);
uint32_t new_dex_pc = dex_pc + inst->SizeInCodeUnits();
ShadowFrame* new_frame = ShadowFrame::Create(num_regs, nullptr, m, new_dex_pc);
- StackHandleScope<2> hs(self_);
+ StackHandleScope<3> hs(self_);
mirror::Class* declaring_class = m->GetDeclaringClass();
Handle<mirror::DexCache> h_dex_cache(hs.NewHandle(declaring_class->GetDexCache()));
Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(declaring_class->GetClassLoader()));
+ Handle<mirror::ArtMethod> h_method(hs.NewHandle(m));
verifier::MethodVerifier verifier(h_dex_cache->GetDexFile(), &h_dex_cache, &h_class_loader,
- &m->GetClassDef(), code_item, m->GetDexMethodIndex(), m,
+ &m->GetClassDef(), code_item, m->GetDexMethodIndex(), h_method,
m->GetAccessFlags(), false, true, true);
verifier.Verify();
const std::vector<int32_t> kinds(verifier.DescribeVRegs(dex_pc));
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index ee8cbe1c62..84df444be2 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -712,11 +712,12 @@ bool Runtime::Init(const RuntimeOptions& raw_options, bool ignore_unrecognized)
self->ClearException();
// Look for a native bridge.
- native_bridge_library_path_ = options->native_bridge_library_path_;
- if (!native_bridge_library_path_.empty()) {
- android::SetupNativeBridge(native_bridge_library_path_.c_str(), &native_bridge_art_callbacks_);
- VLOG(startup) << "Runtime::Setup native bridge library: " << native_bridge_library_path_;
- }
+ native_bridge_library_filename_ = options->native_bridge_library_filename_;
+ android::SetupNativeBridge(native_bridge_library_filename_.c_str(), &native_bridge_art_callbacks_);
+ VLOG(startup) << "Runtime::Setup native bridge library: "
+ << (native_bridge_library_filename_.empty() ?
+ "(empty)" : native_bridge_library_filename_);
+
VLOG(startup) << "Runtime::Init exiting";
return true;
}
diff --git a/runtime/runtime.h b/runtime/runtime.h
index 34ccdcb3da..259691adc1 100644
--- a/runtime/runtime.h
+++ b/runtime/runtime.h
@@ -617,13 +617,14 @@ class Runtime {
bool implicit_so_checks_; // StackOverflow checks are implicit.
bool implicit_suspend_checks_; // Thread suspension checks are implicit.
- // The path to the native bridge library. If this is not empty the native bridge will be
- // initialized and loaded from the pointed path.
+ // The filename to the native bridge library. If this is not empty the native bridge will be
+ // initialized and loaded from the given file (initialized and available). An empty value means
+ // that there's no native bridge (initialized but not available).
//
// The native bridge allows running native code compiled for a foreign ISA. The way it works is,
// if standard dlopen fails to load native library associated with native activity, it calls to
// the native bridge to load it and then gets the trampoline for the entry to native activity.
- std::string native_bridge_library_path_;
+ std::string native_bridge_library_filename_;
// Native bridge library runtime callbacks. They represent the runtime interface to native bridge.
//
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index ce2ec54aab..60194532a6 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -138,6 +138,7 @@ MethodVerifier::FailureKind MethodVerifier::VerifyClass(const DexFile* dex_file,
while (it.HasNextStaticField() || it.HasNextInstanceField()) {
it.Next();
}
+ Thread* self = Thread::Current();
size_t error_count = 0;
bool hard_fail = false;
ClassLinker* linker = Runtime::Current()->GetClassLinker();
@@ -156,17 +157,19 @@ MethodVerifier::FailureKind MethodVerifier::VerifyClass(const DexFile* dex_file,
linker->ResolveMethod(*dex_file, method_idx, dex_cache, class_loader,
NullHandle<mirror::ArtMethod>(), type);
if (method == NULL) {
- DCHECK(Thread::Current()->IsExceptionPending());
+ DCHECK(self->IsExceptionPending());
// We couldn't resolve the method, but continue regardless.
- Thread::Current()->ClearException();
+ self->ClearException();
}
+ StackHandleScope<1> hs(self);
+ Handle<mirror::ArtMethod> h_method(hs.NewHandle(method));
MethodVerifier::FailureKind result = VerifyMethod(method_idx,
dex_file,
dex_cache,
class_loader,
class_def,
it.GetMethodCodeItem(),
- method,
+ h_method,
it.GetMemberAccessFlags(),
allow_soft_failures,
false);
@@ -200,17 +203,19 @@ MethodVerifier::FailureKind MethodVerifier::VerifyClass(const DexFile* dex_file,
linker->ResolveMethod(*dex_file, method_idx, dex_cache, class_loader,
NullHandle<mirror::ArtMethod>(), type);
if (method == NULL) {
- DCHECK(Thread::Current()->IsExceptionPending());
+ DCHECK(self->IsExceptionPending());
// We couldn't resolve the method, but continue regardless.
- Thread::Current()->ClearException();
+ self->ClearException();
}
+ StackHandleScope<1> hs(self);
+ Handle<mirror::ArtMethod> h_method(hs.NewHandle(method));
MethodVerifier::FailureKind result = VerifyMethod(method_idx,
dex_file,
dex_cache,
class_loader,
class_def,
it.GetMethodCodeItem(),
- method,
+ h_method,
it.GetMemberAccessFlags(),
allow_soft_failures,
false);
@@ -242,7 +247,7 @@ MethodVerifier::FailureKind MethodVerifier::VerifyMethod(uint32_t method_idx,
Handle<mirror::ClassLoader> class_loader,
const DexFile::ClassDef* class_def,
const DexFile::CodeItem* code_item,
- mirror::ArtMethod* method,
+ Handle<mirror::ArtMethod> method,
uint32_t method_access_flags,
bool allow_soft_failures,
bool need_precise_constants) {
@@ -250,8 +255,8 @@ MethodVerifier::FailureKind MethodVerifier::VerifyMethod(uint32_t method_idx,
uint64_t start_ns = NanoTime();
MethodVerifier verifier(dex_file, &dex_cache, &class_loader, class_def, code_item,
- method_idx, method, method_access_flags, true, allow_soft_failures,
- need_precise_constants);
+ method_idx, method, method_access_flags, true, allow_soft_failures,
+ need_precise_constants);
if (verifier.Verify()) {
// Verification completed, however failures may be pending that didn't cause the verification
// to hard fail.
@@ -289,7 +294,7 @@ void MethodVerifier::VerifyMethodAndDump(std::ostream& os, uint32_t dex_method_i
Handle<mirror::ClassLoader> class_loader,
const DexFile::ClassDef* class_def,
const DexFile::CodeItem* code_item,
- mirror::ArtMethod* method,
+ Handle<mirror::ArtMethod> method,
uint32_t method_access_flags) {
MethodVerifier verifier(dex_file, &dex_cache, &class_loader, class_def, code_item,
dex_method_idx, method, method_access_flags, true, true, true);
@@ -303,7 +308,7 @@ MethodVerifier::MethodVerifier(const DexFile* dex_file, Handle<mirror::DexCache>
Handle<mirror::ClassLoader>* class_loader,
const DexFile::ClassDef* class_def,
const DexFile::CodeItem* code_item, uint32_t dex_method_idx,
- mirror::ArtMethod* method, uint32_t method_access_flags,
+ Handle<mirror::ArtMethod> method, uint32_t method_access_flags,
bool can_load_classes, bool allow_soft_failures,
bool need_precise_constants)
: reg_types_(can_load_classes),
@@ -340,12 +345,13 @@ MethodVerifier::~MethodVerifier() {
void MethodVerifier::FindLocksAtDexPc(mirror::ArtMethod* m, uint32_t dex_pc,
std::vector<uint32_t>* monitor_enter_dex_pcs) {
- StackHandleScope<2> hs(Thread::Current());
+ StackHandleScope<3> hs(Thread::Current());
Handle<mirror::DexCache> dex_cache(hs.NewHandle(m->GetDexCache()));
Handle<mirror::ClassLoader> class_loader(hs.NewHandle(m->GetClassLoader()));
+ Handle<mirror::ArtMethod> method(hs.NewHandle(m));
MethodVerifier verifier(m->GetDexFile(), &dex_cache, &class_loader, &m->GetClassDef(),
- m->GetCodeItem(), m->GetDexMethodIndex(), m, m->GetAccessFlags(), false,
- true, false);
+ m->GetCodeItem(), m->GetDexMethodIndex(), method, m->GetAccessFlags(),
+ false, true, false);
verifier.interesting_dex_pc_ = dex_pc;
verifier.monitor_enter_dex_pcs_ = monitor_enter_dex_pcs;
verifier.FindLocksAtDexPc();
@@ -364,12 +370,13 @@ void MethodVerifier::FindLocksAtDexPc() {
mirror::ArtField* MethodVerifier::FindAccessedFieldAtDexPc(mirror::ArtMethod* m,
uint32_t dex_pc) {
- StackHandleScope<2> hs(Thread::Current());
+ StackHandleScope<3> hs(Thread::Current());
Handle<mirror::DexCache> dex_cache(hs.NewHandle(m->GetDexCache()));
Handle<mirror::ClassLoader> class_loader(hs.NewHandle(m->GetClassLoader()));
+ Handle<mirror::ArtMethod> method(hs.NewHandle(m));
MethodVerifier verifier(m->GetDexFile(), &dex_cache, &class_loader, &m->GetClassDef(),
- m->GetCodeItem(), m->GetDexMethodIndex(), m, m->GetAccessFlags(), true,
- true, false);
+ m->GetCodeItem(), m->GetDexMethodIndex(), method, m->GetAccessFlags(),
+ true, true, false);
return verifier.FindAccessedFieldAtDexPc(dex_pc);
}
@@ -394,12 +401,13 @@ mirror::ArtField* MethodVerifier::FindAccessedFieldAtDexPc(uint32_t dex_pc) {
mirror::ArtMethod* MethodVerifier::FindInvokedMethodAtDexPc(mirror::ArtMethod* m,
uint32_t dex_pc) {
- StackHandleScope<2> hs(Thread::Current());
+ StackHandleScope<3> hs(Thread::Current());
Handle<mirror::DexCache> dex_cache(hs.NewHandle(m->GetDexCache()));
Handle<mirror::ClassLoader> class_loader(hs.NewHandle(m->GetClassLoader()));
+ Handle<mirror::ArtMethod> method(hs.NewHandle(m));
MethodVerifier verifier(m->GetDexFile(), &dex_cache, &class_loader, &m->GetClassDef(),
- m->GetCodeItem(), m->GetDexMethodIndex(), m, m->GetAccessFlags(), true,
- true, false);
+ m->GetCodeItem(), m->GetDexMethodIndex(), method, m->GetAccessFlags(),
+ true, true, false);
return verifier.FindInvokedMethodAtDexPc(dex_pc);
}
@@ -4022,14 +4030,10 @@ InstructionFlags* MethodVerifier::CurrentInsnFlags() {
RegType& MethodVerifier::GetMethodReturnType() {
if (return_type_ == nullptr) {
- if (mirror_method_ != NULL) {
+ if (mirror_method_.Get() != nullptr) {
Thread* self = Thread::Current();
- StackHandleScope<1> hs(self);
mirror::Class* return_type_class;
- {
- HandleWrapper<mirror::ArtMethod> h_mirror_method(hs.NewHandleWrapper(&mirror_method_));
- return_type_class = MethodHelper(h_mirror_method).GetReturnType(can_load_classes_);
- }
+ return_type_class = MethodHelper(mirror_method_).GetReturnType(can_load_classes_);
if (return_type_class != nullptr) {
return_type_ = &reg_types_.FromClass(mirror_method_->GetReturnTypeDescriptor(),
return_type_class,
@@ -4055,7 +4059,7 @@ RegType& MethodVerifier::GetDeclaringClass() {
const DexFile::MethodId& method_id = dex_file_->GetMethodId(dex_method_idx_);
const char* descriptor
= dex_file_->GetTypeDescriptor(dex_file_->GetTypeId(method_id.class_idx_));
- if (mirror_method_ != NULL) {
+ if (mirror_method_.Get() != nullptr) {
mirror::Class* klass = mirror_method_->GetDeclaringClass();
declaring_class_ = &reg_types_.FromClass(descriptor, klass,
klass->CannotBeAssignedFromOtherTypes());
diff --git a/runtime/verifier/method_verifier.h b/runtime/verifier/method_verifier.h
index e63a90c2ba..78cbe0693d 100644
--- a/runtime/verifier/method_verifier.h
+++ b/runtime/verifier/method_verifier.h
@@ -27,6 +27,7 @@
#include "class_reference.h"
#include "dex_file.h"
#include "dex_instruction.h"
+#include "handle.h"
#include "instruction_flags.h"
#include "method_reference.h"
#include "reg_type.h"
@@ -152,7 +153,7 @@ class MethodVerifier {
Handle<mirror::ClassLoader> class_loader,
const DexFile::ClassDef* class_def,
const DexFile::CodeItem* code_item,
- mirror::ArtMethod* method, uint32_t method_access_flags)
+ Handle<mirror::ArtMethod> method, uint32_t method_access_flags)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
uint8_t EncodePcToReferenceMapData() const;
@@ -203,7 +204,7 @@ class MethodVerifier {
MethodVerifier(const DexFile* dex_file, Handle<mirror::DexCache>* dex_cache,
Handle<mirror::ClassLoader>* class_loader, const DexFile::ClassDef* class_def,
- const DexFile::CodeItem* code_item, uint32_t method_idx, mirror::ArtMethod* method,
+ const DexFile::CodeItem* code_item, uint32_t method_idx, Handle<mirror::ArtMethod> method,
uint32_t access_flags, bool can_load_classes, bool allow_soft_failures,
bool need_precise_constants)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -256,7 +257,7 @@ class MethodVerifier {
Handle<mirror::ClassLoader> class_loader,
const DexFile::ClassDef* class_def_idx,
const DexFile::CodeItem* code_item,
- mirror::ArtMethod* method, uint32_t method_access_flags,
+ Handle<mirror::ArtMethod> method, uint32_t method_access_flags,
bool allow_soft_failures, bool need_precise_constants)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -639,7 +640,7 @@ class MethodVerifier {
const uint32_t dex_method_idx_; // The method we're working on.
// Its object representation if known.
- mirror::ArtMethod* mirror_method_ GUARDED_BY(Locks::mutator_lock_);
+ Handle<mirror::ArtMethod> mirror_method_ GUARDED_BY(Locks::mutator_lock_);
const uint32_t method_access_flags_; // Method's access flags.
RegType* return_type_; // Lazily computed return type of the method.
const DexFile* const dex_file_; // The dex file containing the method.