Merge "Quick: Fix LVN/GVN handling of acquire operations."
diff --git a/build/Android.common_build.mk b/build/Android.common_build.mk
index 0dcefea..386128e 100644
--- a/build/Android.common_build.mk
+++ b/build/Android.common_build.mk
@@ -158,6 +158,7 @@
-Wno-unused-parameter \
-Wstrict-aliasing \
-fstrict-aliasing \
+ -Wunreachable-code \
-fvisibility=protected
ART_TARGET_CLANG_CFLAGS :=
diff --git a/compiler/dex/mir_dataflow.cc b/compiler/dex/mir_dataflow.cc
index e71c806..246ae44 100644
--- a/compiler/dex/mir_dataflow.cc
+++ b/compiler/dex/mir_dataflow.cc
@@ -1272,6 +1272,22 @@
return true;
}
+void MIRGraph::InitializeBasicBlockDataFlow() {
+ /*
+ * Allocate the BasicBlockDataFlow structure for the entry and code blocks.
+ */
+ for (BasicBlock* bb : block_list_) {
+ if (bb->hidden == true) continue;
+ if (bb->block_type == kDalvikByteCode ||
+ bb->block_type == kEntryBlock ||
+ bb->block_type == kExitBlock) {
+ bb->data_flow_info =
+ static_cast<BasicBlockDataFlow*>(arena_->Alloc(sizeof(BasicBlockDataFlow),
+ kArenaAllocDFInfo));
+ }
+ }
+}
+
/* Setup the basic data structures for SSA conversion */
void MIRGraph::CompilerInitializeSSAConversion() {
size_t num_reg = GetNumOfCodeAndTempVRs();
@@ -1319,19 +1335,7 @@
// The MIR graph keeps track of the sreg for method pointer specially, so record that now.
method_sreg_ = method_temp->s_reg_low;
- /*
- * Allocate the BasicBlockDataFlow structure for the entry and code blocks
- */
- for (BasicBlock* bb : block_list_) {
- if (bb->hidden == true) continue;
- if (bb->block_type == kDalvikByteCode ||
- bb->block_type == kEntryBlock ||
- bb->block_type == kExitBlock) {
- bb->data_flow_info =
- static_cast<BasicBlockDataFlow*>(arena_->Alloc(sizeof(BasicBlockDataFlow),
- kArenaAllocDFInfo));
- }
- }
+ InitializeBasicBlockDataFlow();
}
/*
diff --git a/compiler/dex/mir_graph.cc b/compiler/dex/mir_graph.cc
index bd7e4f7..dda9e77 100644
--- a/compiler/dex/mir_graph.cc
+++ b/compiler/dex/mir_graph.cc
@@ -1153,7 +1153,7 @@
}
// Remove the BB information and also find the after_list.
- for (MIR* mir = first_list_mir; mir != last_list_mir; mir = mir->next) {
+ for (MIR* mir = first_list_mir; mir != last_list_mir->next; mir = mir->next) {
mir->bb = NullBasicBlockId;
}
@@ -1684,9 +1684,6 @@
temp_bit_vector_size_ = GetNumOfCodeAndTempVRs();
temp_bit_vector_ = new (temp_scoped_alloc_.get()) ArenaBitVector(
temp_scoped_alloc_.get(), temp_bit_vector_size_, false, kBitMapRegisterV);
-
- // Update the maximum number of reachable blocks.
- max_num_reachable_blocks_ = num_reachable_blocks_;
}
void MIRGraph::SSATransformationEnd() {
@@ -1699,6 +1696,9 @@
temp_bit_vector_ = nullptr;
DCHECK(temp_scoped_alloc_.get() != nullptr);
temp_scoped_alloc_.reset();
+
+ // Update the maximum number of reachable blocks.
+ max_num_reachable_blocks_ = num_reachable_blocks_;
}
size_t MIRGraph::GetNumDalvikInsns() const {
diff --git a/compiler/dex/mir_graph.h b/compiler/dex/mir_graph.h
index f53ec89..f14b187 100644
--- a/compiler/dex/mir_graph.h
+++ b/compiler/dex/mir_graph.h
@@ -525,7 +525,7 @@
class MIRGraph {
public:
MIRGraph(CompilationUnit* cu, ArenaAllocator* arena);
- ~MIRGraph();
+ virtual ~MIRGraph();
/*
* Examine the graph to determine whether it's worthwile to spend the time compiling
@@ -1147,6 +1147,7 @@
void ComputeDefBlockMatrix();
void ComputeDominators();
void CompilerInitializeSSAConversion();
+ virtual void InitializeBasicBlockDataFlow();
void InsertPhiNodes();
void DoDFSPreOrderSSARename(BasicBlock* block);
diff --git a/compiler/dex/quick/x86/assemble_x86.cc b/compiler/dex/quick/x86/assemble_x86.cc
index ab1608b..dce2b73 100644
--- a/compiler/dex/quick/x86/assemble_x86.cc
+++ b/compiler/dex/quick/x86/assemble_x86.cc
@@ -580,7 +580,7 @@
case kX86CallA: return true;
default: return false;
}
- case kPcRel: return true;
+ case kPcRel:
switch (entry->opcode) {
case kX86PcRelLoadRA: return true;
default: return false;
diff --git a/compiler/dex/quick/x86/target_x86.cc b/compiler/dex/quick/x86/target_x86.cc
index 760358e..9aeaf60 100755
--- a/compiler/dex/quick/x86/target_x86.cc
+++ b/compiler/dex/quick/x86/target_x86.cc
@@ -2236,8 +2236,6 @@
OpSize opsize = static_cast<OpSize>(mir->dalvikInsn.vC >> 16);
RegLocation rl_dest = mir_graph_->GetDest(mir);
RegStorage vector_src = RegStorage::Solo128(mir->dalvikInsn.vB);
- int extract_index = mir->dalvikInsn.arg[0];
- int extr_opcode = 0;
RegLocation rl_result;
bool is_wide = false;
@@ -2273,12 +2271,7 @@
* 2-2) In 32-bit case, use movd twice to move to 32-bit GP pair.
* 3) Store the result to the final destination.
*/
- RegStorage rs_tmp_vector = Get128BitRegister(AllocTempDouble());
- NewLIR2(kX86MovdqaRR, rs_tmp_vector.GetReg(), vector_src.GetReg());
- NewLIR2(kX86PsrldqRI, rs_tmp_vector.GetReg(), 8);
- NewLIR2(kX86PaddqRR, vector_src.GetReg(), rs_tmp_vector.GetReg());
- FreeTemp(rs_tmp_vector);
-
+ NewLIR2(kX86PsrldqRI, vector_src.GetReg(), 8);
rl_result = EvalLocWide(rl_dest, kCoreReg, true);
if (cu_->target64) {
DCHECK(!rl_result.reg.IsPair());
@@ -2291,16 +2284,21 @@
StoreValueWide(rl_dest, rl_result);
} else {
+ int extract_index = mir->dalvikInsn.arg[0];
+ int extr_opcode = 0;
+ rl_result = UpdateLocTyped(rl_dest, kCoreReg);
+
// Handle the rest of integral types now.
switch (opsize) {
case k32:
- rl_result = UpdateLocTyped(rl_dest, kCoreReg);
- extr_opcode = (rl_result.location == kLocPhysReg) ? kX86PextrdMRI : kX86PextrdRRI;
+ extr_opcode = (rl_result.location == kLocPhysReg) ? kX86PextrdRRI : kX86PextrdMRI;
break;
case kSignedHalf:
case kUnsignedHalf:
- rl_result= UpdateLocTyped(rl_dest, kCoreReg);
- extr_opcode = (rl_result.location == kLocPhysReg) ? kX86PextrwMRI : kX86PextrwRRI;
+ extr_opcode = (rl_result.location == kLocPhysReg) ? kX86PextrwRRI : kX86PextrwMRI;
+ break;
+ case kSignedByte:
+ extr_opcode = (rl_result.location == kLocPhysReg) ? kX86PextrbRRI : kX86PextrbMRI;
break;
default:
LOG(FATAL) << "Unsupported vector reduce " << opsize;
@@ -2309,11 +2307,7 @@
if (rl_result.location == kLocPhysReg) {
NewLIR3(extr_opcode, rl_result.reg.GetReg(), vector_src.GetReg(), extract_index);
- if (is_wide == true) {
- StoreFinalValue(rl_dest, rl_result);
- } else {
- StoreFinalValueWide(rl_dest, rl_result);
- }
+ StoreFinalValue(rl_dest, rl_result);
} else {
int displacement = SRegOffset(rl_result.s_reg_low);
LIR *l = NewLIR3(extr_opcode, rs_rX86_SP.GetReg(), displacement, vector_src.GetReg());
@@ -2357,7 +2351,7 @@
break;
case k64:
op_shuffle = kX86PunpcklqdqRR;
- op_mov = kX86MovqrxRR;
+ op_mov = kX86MovqxrRR;
is_wide = true;
break;
case kSignedByte:
diff --git a/compiler/utils/arm64/assembler_arm64.cc b/compiler/utils/arm64/assembler_arm64.cc
index 3edf59b..c82b4f0 100644
--- a/compiler/utils/arm64/assembler_arm64.cc
+++ b/compiler/utils/arm64/assembler_arm64.cc
@@ -299,6 +299,10 @@
CHECK(dst.IsCoreRegister() && base.IsCoreRegister());
LoadWFromOffset(kLoadWord, dst.AsOverlappingCoreRegisterLow(), base.AsCoreRegister(),
offs.Int32Value());
+ if (kPoisonHeapReferences) {
+ WRegister ref_reg = dst.AsOverlappingCoreRegisterLow();
+ ___ Neg(reg_w(ref_reg), vixl::Operand(reg_w(ref_reg)));
+ }
}
void Arm64Assembler::LoadRawPtr(ManagedRegister m_dst, ManagedRegister m_base, Offset offs) {
diff --git a/compiler/utils/x86_64/assembler_x86_64.cc b/compiler/utils/x86_64/assembler_x86_64.cc
index a47e968..1dcd4b3 100644
--- a/compiler/utils/x86_64/assembler_x86_64.cc
+++ b/compiler/utils/x86_64/assembler_x86_64.cc
@@ -1992,6 +1992,9 @@
X86_64ManagedRegister dest = mdest.AsX86_64();
CHECK(dest.IsCpuRegister() && dest.IsCpuRegister());
movq(dest.AsCpuRegister(), Address(base.AsX86_64().AsCpuRegister(), offs));
+ if (kPoisonHeapReferences) {
+ negl(dest.AsCpuRegister());
+ }
}
void X86_64Assembler::LoadRawPtr(ManagedRegister mdest, ManagedRegister base,
@@ -2276,4 +2279,3 @@
} // namespace x86_64
} // namespace art
-
diff --git a/runtime/base/macros.h b/runtime/base/macros.h
index fae9271..b66d528 100644
--- a/runtime/base/macros.h
+++ b/runtime/base/macros.h
@@ -179,6 +179,7 @@
#define WARN_UNUSED __attribute__((warn_unused_result))
template<typename T> void UNUSED(const T&) {}
+#define UNREACHABLE __builtin_unreachable
// Annotalysis thread-safety analysis support.
#if defined(__SUPPORT_TS_ANNOTATION__) || defined(__clang__)
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index cc77c50..6ed27bb 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -1179,7 +1179,7 @@
uint32_t image_oat_checksum = 0;
uintptr_t image_oat_data_begin = 0;
int32_t image_patch_delta = 0;
- if (instruction_set == Runtime::Current()->GetInstructionSet()) {
+ if (instruction_set == runtime->GetInstructionSet()) {
const ImageHeader& image_header = image_space->GetImageHeader();
image_oat_checksum = image_header.GetOatChecksum();
image_oat_data_begin = reinterpret_cast<uintptr_t>(image_header.GetOatDataBegin());
@@ -2269,9 +2269,7 @@
return soa.Decode<mirror::Class*>(result.get());
}
}
-
- ThrowNoClassDefFoundError("Class %s not found", PrintableString(descriptor).c_str());
- return nullptr;
+ UNREACHABLE();
}
mirror::Class* ClassLinker::DefineClass(Thread* self, const char* descriptor,
@@ -4340,7 +4338,7 @@
LOG(FATAL) << "Unexpected class status. " << PrettyClass(klass.Get()) << " is "
<< klass->GetStatus();
}
- LOG(FATAL) << "Not Reached" << PrettyClass(klass.Get());
+ UNREACHABLE();
}
bool ClassLinker::ValidateSuperClassDescriptors(Handle<mirror::Class> klass) {
diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc
index 353d00c..59630fe 100644
--- a/runtime/gc/space/image_space.cc
+++ b/runtime/gc/space/image_space.cc
@@ -149,7 +149,8 @@
arg_vector.push_back(oat_file_option_string);
Runtime::Current()->AddCurrentRuntimeFeaturesAsDex2OatArguments(&arg_vector);
- CHECK_EQ(image_isa, kRuntimeISA) << "We should always be generating an image for the current isa.";
+ CHECK_EQ(image_isa, kRuntimeISA)
+ << "We should always be generating an image for the current isa.";
int32_t base_offset = ChooseRelocationOffsetDelta(ART_BASE_ADDRESS_MIN_DELTA,
ART_BASE_ADDRESS_MAX_DELTA);
@@ -270,10 +271,10 @@
return Exec(argv, error_msg);
}
-static ImageHeader* ReadSpecificImageHeaderOrDie(const char* filename) {
+static ImageHeader* ReadSpecificImageHeader(const char* filename, std::string* error_msg) {
std::unique_ptr<ImageHeader> hdr(new ImageHeader);
if (!ReadSpecificImageHeader(filename, hdr.get())) {
- LOG(FATAL) << "Unable to read image header for " << filename;
+ *error_msg = StringPrintf("Unable to read image header for %s", filename);
return nullptr;
}
return hdr.release();
@@ -281,6 +282,17 @@
ImageHeader* ImageSpace::ReadImageHeaderOrDie(const char* image_location,
const InstructionSet image_isa) {
+ std::string error_msg;
+ ImageHeader* image_header = ReadImageHeader(image_location, image_isa, &error_msg);
+ if (image_header == nullptr) {
+ LOG(FATAL) << error_msg;
+ }
+ return image_header;
+}
+
+ImageHeader* ImageSpace::ReadImageHeader(const char* image_location,
+ const InstructionSet image_isa,
+ std::string* error_msg) {
std::string system_filename;
bool has_system = false;
std::string cache_filename;
@@ -294,33 +306,37 @@
std::unique_ptr<ImageHeader> sys_hdr(new ImageHeader);
std::unique_ptr<ImageHeader> cache_hdr(new ImageHeader);
if (!ReadSpecificImageHeader(system_filename.c_str(), sys_hdr.get())) {
- LOG(FATAL) << "Unable to read image header for " << image_location << " at "
- << system_filename;
+ *error_msg = StringPrintf("Unable to read image header for %s at %s",
+ image_location, system_filename.c_str());
return nullptr;
}
if (!ReadSpecificImageHeader(cache_filename.c_str(), cache_hdr.get())) {
- LOG(FATAL) << "Unable to read image header for " << image_location << " at "
- << cache_filename;
+ *error_msg = StringPrintf("Unable to read image header for %s at %s",
+ image_location, cache_filename.c_str());
return nullptr;
}
if (sys_hdr->GetOatChecksum() != cache_hdr->GetOatChecksum()) {
- LOG(FATAL) << "Unable to find a relocated version of image file " << image_location;
+ *error_msg = StringPrintf("Unable to find a relocated version of image file %s",
+ image_location);
return nullptr;
}
return cache_hdr.release();
} else if (!has_cache) {
- LOG(FATAL) << "Unable to find a relocated version of image file " << image_location;
+ *error_msg = StringPrintf("Unable to find a relocated version of image file %s",
+ image_location);
return nullptr;
} else if (!has_system && has_cache) {
// This can probably just use the cache one.
- return ReadSpecificImageHeaderOrDie(cache_filename.c_str());
+ return ReadSpecificImageHeader(cache_filename.c_str(), error_msg);
}
} else {
// We don't want to relocate, Just pick the appropriate one if we have it and return.
if (has_system && has_cache) {
// We want the cache if the checksum matches, otherwise the system.
- std::unique_ptr<ImageHeader> system(ReadSpecificImageHeaderOrDie(system_filename.c_str()));
- std::unique_ptr<ImageHeader> cache(ReadSpecificImageHeaderOrDie(cache_filename.c_str()));
+ std::unique_ptr<ImageHeader> system(ReadSpecificImageHeader(system_filename.c_str(),
+ error_msg));
+ std::unique_ptr<ImageHeader> cache(ReadSpecificImageHeader(cache_filename.c_str(),
+ error_msg));
if (system.get() == nullptr ||
(cache.get() != nullptr && cache->GetOatChecksum() == system->GetOatChecksum())) {
return cache.release();
@@ -328,14 +344,14 @@
return system.release();
}
} else if (has_system) {
- return ReadSpecificImageHeaderOrDie(system_filename.c_str());
+ return ReadSpecificImageHeader(system_filename.c_str(), error_msg);
} else if (has_cache) {
- return ReadSpecificImageHeaderOrDie(cache_filename.c_str());
+ return ReadSpecificImageHeader(cache_filename.c_str(), error_msg);
}
}
}
- LOG(FATAL) << "Unable to find image file for: " << image_location;
+ *error_msg = StringPrintf("Unable to find image file for %s", image_location);
return nullptr;
}
@@ -563,12 +579,13 @@
CHECK_EQ(image_header.GetImageBegin(), map->Begin());
DCHECK_EQ(0, memcmp(&image_header, map->Begin(), sizeof(ImageHeader)));
- std::unique_ptr<MemMap> image_map(MemMap::MapFileAtAddress(nullptr, image_header.GetImageBitmapSize(),
- PROT_READ, MAP_PRIVATE,
- file->Fd(), image_header.GetBitmapOffset(),
- false,
- image_filename,
- error_msg));
+ std::unique_ptr<MemMap> image_map(
+ MemMap::MapFileAtAddress(nullptr, image_header.GetImageBitmapSize(),
+ PROT_READ, MAP_PRIVATE,
+ file->Fd(), image_header.GetBitmapOffset(),
+ false,
+ image_filename,
+ error_msg));
if (image_map.get() == nullptr) {
*error_msg = StringPrintf("Failed to map image bitmap: %s", error_msg->c_str());
return nullptr;
@@ -616,11 +633,14 @@
runtime->SetDefaultImt(down_cast<mirror::ObjectArray<mirror::ArtMethod>*>(default_imt));
mirror::Object* callee_save_method = image_header.GetImageRoot(ImageHeader::kCalleeSaveMethod);
- runtime->SetCalleeSaveMethod(down_cast<mirror::ArtMethod*>(callee_save_method), Runtime::kSaveAll);
+ runtime->SetCalleeSaveMethod(down_cast<mirror::ArtMethod*>(callee_save_method),
+ Runtime::kSaveAll);
callee_save_method = image_header.GetImageRoot(ImageHeader::kRefsOnlySaveMethod);
- runtime->SetCalleeSaveMethod(down_cast<mirror::ArtMethod*>(callee_save_method), Runtime::kRefsOnly);
+ runtime->SetCalleeSaveMethod(down_cast<mirror::ArtMethod*>(callee_save_method),
+ Runtime::kRefsOnly);
callee_save_method = image_header.GetImageRoot(ImageHeader::kRefsAndArgsSaveMethod);
- runtime->SetCalleeSaveMethod(down_cast<mirror::ArtMethod*>(callee_save_method), Runtime::kRefsAndArgs);
+ runtime->SetCalleeSaveMethod(down_cast<mirror::ArtMethod*>(callee_save_method),
+ Runtime::kRefsAndArgs);
if (VLOG_IS_ON(heap) || VLOG_IS_ON(startup)) {
LOG(INFO) << "ImageSpace::Init exiting (" << PrettyDuration(NanoTime() - start_time)
diff --git a/runtime/gc/space/image_space.h b/runtime/gc/space/image_space.h
index 2586ece..d7f8057 100644
--- a/runtime/gc/space/image_space.h
+++ b/runtime/gc/space/image_space.h
@@ -47,10 +47,17 @@
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Reads the image header from the specified image location for the
- // instruction set image_isa.
+ // instruction set image_isa or dies trying.
static ImageHeader* ReadImageHeaderOrDie(const char* image_location,
InstructionSet image_isa);
+ // Reads the image header from the specified image location for the
+ // instruction set image_isa. Returns nullptr on failure, with
+ // reason in error_msg.
+ static ImageHeader* ReadImageHeader(const char* image_location,
+ InstructionSet image_isa,
+ std::string* error_msg);
+
// Give access to the OatFile.
const OatFile* GetOatFile() const;
diff --git a/runtime/mirror/object.cc b/runtime/mirror/object.cc
index a1177d6..57069ab 100644
--- a/runtime/mirror/object.cc
+++ b/runtime/mirror/object.cc
@@ -187,8 +187,7 @@
}
}
}
- LOG(FATAL) << "Unreachable";
- return 0;
+ UNREACHABLE();
}
void Object::CheckFieldAssignmentImpl(MemberOffset field_offset, Object* new_value) {
diff --git a/runtime/native/dalvik_system_VMRuntime.cc b/runtime/native/dalvik_system_VMRuntime.cc
index 64d4fe2..23f46f4 100644
--- a/runtime/native/dalvik_system_VMRuntime.cc
+++ b/runtime/native/dalvik_system_VMRuntime.cc
@@ -16,6 +16,7 @@
#include <limits.h>
+#include "ScopedUtfChars.h"
#include "class_linker-inl.h"
#include "common_throws.h"
#include "debugger.h"
@@ -24,6 +25,8 @@
#include "gc/allocator/dlmalloc.h"
#include "gc/heap.h"
#include "gc/space/dlmalloc_space.h"
+#include "gc/space/image_space.h"
+#include "instruction_set.h"
#include "intern_table.h"
#include "jni_internal.h"
#include "mirror/art_method-inl.h"
@@ -91,7 +94,8 @@
return nullptr;
}
Runtime* runtime = Runtime::Current();
- mirror::Class* array_class = runtime->GetClassLinker()->FindArrayClass(soa.Self(), &element_class);
+ mirror::Class* array_class = runtime->GetClassLinker()->FindArrayClass(soa.Self(),
+ &element_class);
if (UNLIKELY(array_class == nullptr)) {
return nullptr;
}
@@ -518,6 +522,28 @@
env->ReleaseStringUTFChars(pkgName, pkgNameChars);
}
+static jboolean VMRuntime_isBootClassPathOnDisk(JNIEnv* env, jclass, jstring java_instruction_set) {
+ ScopedUtfChars instruction_set(env, java_instruction_set);
+ if (instruction_set.c_str() == nullptr) {
+ return JNI_FALSE;
+ }
+ InstructionSet isa = GetInstructionSetFromString(instruction_set.c_str());
+ if (isa == kNone) {
+ ScopedLocalRef<jclass> iae(env, env->FindClass("java/lang/IllegalArgumentException"));
+ std::string message(StringPrintf("Instruction set %s is invalid.", instruction_set.c_str()));
+ env->ThrowNew(iae.get(), message.c_str());
+ return JNI_FALSE;
+ }
+ std::string error_msg;
+ std::unique_ptr<ImageHeader> image_header(gc::space::ImageSpace::ReadImageHeader(
+ Runtime::Current()->GetImageLocation().c_str(), isa, &error_msg));
+ return image_header.get() != nullptr;
+}
+
+static jstring VMRuntime_getCurrentInstructionSet(JNIEnv* env, jclass) {
+ return env->NewStringUTF(GetInstructionSetString(kRuntimeISA));
+}
+
static JNINativeMethod gMethods[] = {
NATIVE_METHOD(VMRuntime, addressOf, "!(Ljava/lang/Object;)J"),
NATIVE_METHOD(VMRuntime, bootClassPath, "()Ljava/lang/String;"),
@@ -543,7 +569,10 @@
NATIVE_METHOD(VMRuntime, is64Bit, "!()Z"),
NATIVE_METHOD(VMRuntime, isCheckJniEnabled, "!()Z"),
NATIVE_METHOD(VMRuntime, preloadDexCaches, "()V"),
- NATIVE_METHOD(VMRuntime, registerAppInfo, "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V"),
+ NATIVE_METHOD(VMRuntime, registerAppInfo,
+ "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V"),
+ NATIVE_METHOD(VMRuntime, isBootClassPathOnDisk, "(Ljava/lang/String;)Z"),
+ NATIVE_METHOD(VMRuntime, getCurrentInstructionSet, "()Ljava/lang/String;"),
};
void register_dalvik_system_VMRuntime(JNIEnv* env) {
diff --git a/runtime/parsed_options.cc b/runtime/parsed_options.cc
index 2bd994d..d820026 100644
--- a/runtime/parsed_options.cc
+++ b/runtime/parsed_options.cc
@@ -932,7 +932,7 @@
}
bool sane_val = true;
double value;
- if (false) {
+ if ((false)) {
// TODO: this doesn't seem to work on the emulator. b/15114595
std::stringstream iss(substring);
iss >> value;
diff --git a/runtime/quick_exception_handler.cc b/runtime/quick_exception_handler.cc
index 43d21de..2c158ba 100644
--- a/runtime/quick_exception_handler.cc
+++ b/runtime/quick_exception_handler.cc
@@ -230,7 +230,7 @@
reinterpret_cast<mirror::Object*>(GetVReg(m, reg, kind)));
break;
case kLongLoVReg:
- if (GetVRegKind(reg + 1, kinds), kLongHiVReg) {
+ if (GetVRegKind(reg + 1, kinds) == kLongHiVReg) {
// Treat it as a "long" register pair.
new_frame->SetVRegLong(reg, GetVRegPair(m, reg, kLongLoVReg, kLongHiVReg));
} else {
@@ -238,14 +238,14 @@
}
break;
case kLongHiVReg:
- if (GetVRegKind(reg - 1, kinds), kLongLoVReg) {
+ if (GetVRegKind(reg - 1, kinds) == kLongLoVReg) {
// Nothing to do: we treated it as a "long" register pair.
} else {
new_frame->SetVReg(reg, GetVReg(m, reg, kind));
}
break;
case kDoubleLoVReg:
- if (GetVRegKind(reg + 1, kinds), kDoubleHiVReg) {
+ if (GetVRegKind(reg + 1, kinds) == kDoubleHiVReg) {
// Treat it as a "double" register pair.
new_frame->SetVRegLong(reg, GetVRegPair(m, reg, kDoubleLoVReg, kDoubleHiVReg));
} else {
@@ -253,7 +253,7 @@
}
break;
case kDoubleHiVReg:
- if (GetVRegKind(reg - 1, kinds), kDoubleLoVReg) {
+ if (GetVRegKind(reg - 1, kinds) == kDoubleLoVReg) {
// Nothing to do: we treated it as a "double" register pair.
} else {
new_frame->SetVReg(reg, GetVReg(m, reg, kind));
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 49f8c63..48439b6 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -678,6 +678,7 @@
compiler_executable_ = options->compiler_executable_;
compiler_options_ = options->compiler_options_;
image_compiler_options_ = options->image_compiler_options_;
+ image_location_ = options->image_;
max_spins_before_thin_lock_inflation_ = options->max_spins_before_thin_lock_inflation_;
diff --git a/runtime/runtime.h b/runtime/runtime.h
index 35e3a88..1a6c6e0 100644
--- a/runtime/runtime.h
+++ b/runtime/runtime.h
@@ -137,6 +137,10 @@
return image_compiler_options_;
}
+ const std::string& GetImageLocation() const {
+ return image_location_;
+ }
+
const ProfilerOptions& GetProfilerOptions() const {
return profiler_options_;
}
@@ -537,6 +541,7 @@
std::string patchoat_executable_;
std::vector<std::string> compiler_options_;
std::vector<std::string> image_compiler_options_;
+ std::string image_location_;
std::string boot_class_path_string_;
std::string class_path_string_;
diff --git a/test/118-noimage-dex2oat/expected.txt b/test/118-noimage-dex2oat/expected.txt
index 472a5f2..6825fae 100644
--- a/test/118-noimage-dex2oat/expected.txt
+++ b/test/118-noimage-dex2oat/expected.txt
@@ -1,6 +1,6 @@
Run -Xnoimage-dex2oat
-Has image is false, is image dex2oat enabled is false.
+Has image is false, is image dex2oat enabled is false, is BOOTCLASSPATH on disk is false.
Run -Ximage-dex2oat
-Has image is true, is image dex2oat enabled is true.
+Has image is true, is image dex2oat enabled is true, is BOOTCLASSPATH on disk is true.
Run default
-Has image is true, is image dex2oat enabled is true.
+Has image is true, is image dex2oat enabled is true, is BOOTCLASSPATH on disk is true.
diff --git a/test/118-noimage-dex2oat/src/Main.java b/test/118-noimage-dex2oat/src/Main.java
index 11c736a..c83b84d 100644
--- a/test/118-noimage-dex2oat/src/Main.java
+++ b/test/118-noimage-dex2oat/src/Main.java
@@ -14,18 +14,28 @@
* limitations under the License.
*/
+import java.lang.reflect.Method;
+
public class Main {
- public static void main(String[] args) {
+ public static void main(String[] args) throws Exception {
boolean hasImage = hasImage();
+ String instructionSet = VMRuntime.getCurrentInstructionSet();
+ boolean isBootClassPathOnDisk = VMRuntime.isBootClassPathOnDisk(instructionSet);
System.out.println(
"Has image is " + hasImage + ", is image dex2oat enabled is "
- + isImageDex2OatEnabled() + ".");
+ + isImageDex2OatEnabled() + ", is BOOTCLASSPATH on disk is "
+ + isBootClassPathOnDisk + ".");
if (hasImage && !isImageDex2OatEnabled()) {
throw new Error("Image with dex2oat disabled runs with an oat file");
} else if (!hasImage && isImageDex2OatEnabled()) {
throw new Error("Image with dex2oat enabled runs without an oat file");
}
+ if (hasImage && !isBootClassPathOnDisk) {
+ throw new Error("Image with dex2oat disabled runs with an image file");
+ } else if (!hasImage && isBootClassPathOnDisk) {
+ throw new Error("Image with dex2oat enabled runs without an image file");
+ }
}
static {
@@ -35,4 +45,26 @@
private native static boolean hasImage();
private native static boolean isImageDex2OatEnabled();
+
+ private static class VMRuntime {
+ private static final Method getCurrentInstructionSetMethod;
+ private static final Method isBootClassPathOnDiskMethod;
+ static {
+ try {
+ Class c = Class.forName("dalvik.system.VMRuntime");
+ getCurrentInstructionSetMethod = c.getDeclaredMethod("getCurrentInstructionSet");
+ isBootClassPathOnDiskMethod = c.getDeclaredMethod("isBootClassPathOnDisk",
+ String.class);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static String getCurrentInstructionSet() throws Exception {
+ return (String) getCurrentInstructionSetMethod.invoke(null);
+ }
+ public static boolean isBootClassPathOnDisk(String instructionSet) throws Exception {
+ return (boolean) isBootClassPathOnDiskMethod.invoke(null, instructionSet);
+ }
+ }
}