summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDragos Sbirlea <dragoss@google.com>2013-06-21 09:20:34 -0700
committerDragos Sbirlea <dragoss@google.com>2013-06-25 13:12:53 -0700
commit7467ee05012e1fd9834df74663c1ebda46f5636b (patch)
treed93d7b7f13440eff50c552ccdab8ce8e4e5a9547
parentb126134010ebeee771da0eec7fa76ad13fe9a9c9 (diff)
downloadart-7467ee05012e1fd9834df74663c1ebda46f5636b.zip
art-7467ee05012e1fd9834df74663c1ebda46f5636b.tar.gz
art-7467ee05012e1fd9834df74663c1ebda46f5636b.tar.bz2
Added support for SEA IR.
- Modified makefile to take the existance of SEA_IR_ART file to mean "switch to sea ir mode". - Switching SEA IR mode on leads to the new compiler being fed the fibonacci methods only, if they are used as input. - Added partial support for the control flow subgraph of the SEA IR (instruction nodes and region nodes for conditional and unconditional branches). Change-Id: I29020b8e2df5a00fde75715c3683cc25038589f4 Conflicts: src/compiler/driver/compiler_driver.cc
-rw-r--r--.gitignore3
-rw-r--r--build/Android.common.mk18
-rw-r--r--build/Android.libart-compiler.mk5
-rw-r--r--src/compiler/dex/frontend.cc5
-rw-r--r--src/compiler/dex/frontend.h7
-rw-r--r--src/compiler/driver/compiler_driver.cc21
-rw-r--r--src/compiler/driver/compiler_driver.h1
-rw-r--r--src/compiler/sea_ir/frontend.cc81
-rw-r--r--src/compiler/sea_ir/sea.cc172
-rw-r--r--src/compiler/sea_ir/sea.h102
-rw-r--r--src/dex2oat.cc6
-rw-r--r--src/runtime.cc4
-rw-r--r--src/runtime.h13
13 files changed, 436 insertions, 2 deletions
diff --git a/.gitignore b/.gitignore
index 5973a95..1cdfed9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,4 @@
USE_LLVM_COMPILER
+USE_PORTABLE_COMPILER
+SMALL_ART
+SEA_IR_ART
diff --git a/build/Android.common.mk b/build/Android.common.mk
index a7bf944..33c5ac6 100644
--- a/build/Android.common.mk
+++ b/build/Android.common.mk
@@ -23,6 +23,15 @@ ifeq ($(WITH_ART_SMALL_MODE), true)
ART_SMALL_MODE := true
endif
+ART_SEA_IR_MODE := false
+ifneq ($(wildcard art/SEA_IR_ART),)
+$(info Enabling ART_SEA_IR_MODE because of existence of art/SEA_IR_ART)
+ART_SEA_IR_MODE := true
+endif
+ifeq ($(WITH_ART_SEA_IR_MODE), true)
+ART_SEA_IR_MODE := true
+endif
+
ART_USE_PORTABLE_COMPILER := false
ifneq ($(wildcard art/USE_PORTABLE_COMPILER),)
$(info Enabling ART_USE_PORTABLE_COMPILER because of existence of art/USE_PORTABLE_COMPILER)
@@ -71,6 +80,10 @@ ifeq ($(ART_SMALL_MODE),true)
art_cflags += -DART_SMALL_MODE=1
endif
+ifeq ($(ART_SEA_IR_MODE),true)
+ art_cflags += -DART_SEA_IR_MODE=1
+endif
+
# TODO: enable -std=gnu++0x for auto support when on Ubuntu 12.04 LTS (Precise Pangolin)
# On 10.04 LTS (Lucid Lynx), it can cause dependencies on GLIBCXX_3.4.14 version symbols.
@@ -302,6 +315,11 @@ LIBART_COMMON_SRC_FILES += \
src/oat/runtime/support_throw.cc \
src/oat/runtime/support_interpreter.cc
+ifeq ($(ART_SEA_IR_MODE),true)
+LIBART_COMMON_SRC_FILES += \
+ src/compiler/sea_ir/sea.cc
+endif
+
LIBART_TARGET_SRC_FILES := \
$(LIBART_COMMON_SRC_FILES) \
src/base/logging_android.cc \
diff --git a/build/Android.libart-compiler.mk b/build/Android.libart-compiler.mk
index 708a488..25e6997 100644
--- a/build/Android.libart-compiler.mk
+++ b/build/Android.libart-compiler.mk
@@ -76,6 +76,11 @@ LIBART_COMPILER_SRC_FILES := \
src/elf_writer.cc \
src/elf_writer_quick.cc
+ifeq ($(ART_SEA_IR_MODE),true)
+LIBART_COMPILER_SRC_FILES += \
+ src/compiler/sea_ir/frontend.cc
+endif
+
LIBART_COMPILER_CFLAGS :=
ifeq ($(ART_USE_PORTABLE_COMPILER),true)
LIBART_COMPILER_SRC_FILES += src/elf_writer_mclinker.cc
diff --git a/src/compiler/dex/frontend.cc b/src/compiler/dex/frontend.cc
index e015645..c528d86 100644
--- a/src/compiler/dex/frontend.cc
+++ b/src/compiler/dex/frontend.cc
@@ -29,6 +29,8 @@
#include "backend.h"
#include "base/logging.h"
+
+
namespace {
#if !defined(ART_USE_PORTABLE_COMPILER)
pthread_once_t llvm_multi_init = PTHREAD_ONCE_INIT;
@@ -104,6 +106,7 @@ static uint32_t kCompilerDebugFlags = 0 | // Enable debug/testing modes
//(1 << kDebugShowSummaryMemoryUsage) |
0;
+
static CompiledMethod* CompileMethod(CompilerDriver& compiler,
const CompilerBackend compiler_backend,
const DexFile::CodeItem* code_item,
@@ -277,6 +280,8 @@ CompiledMethod* CompileOneMethod(CompilerDriver& compiler,
);
}
+
+
} // namespace art
extern "C" art::CompiledMethod*
diff --git a/src/compiler/dex/frontend.h b/src/compiler/dex/frontend.h
index dc57a23..69d7f77 100644
--- a/src/compiler/dex/frontend.h
+++ b/src/compiler/dex/frontend.h
@@ -20,6 +20,11 @@
#include "dex_file.h"
#include "dex_instruction.h"
+
+
+
+
+
namespace llvm {
class Module;
class LLVMContext;
@@ -116,4 +121,6 @@ extern "C" art::CompiledMethod* ArtCompileMethod(art::CompilerDriver& driver,
jobject class_loader,
const art::DexFile& dex_file);
+
+
#endif // ART_SRC_COMPILER_DEX_COMPILER_H_
diff --git a/src/compiler/driver/compiler_driver.cc b/src/compiler/driver/compiler_driver.cc
index 4a6eb96..122988a 100644
--- a/src/compiler/driver/compiler_driver.cc
+++ b/src/compiler/driver/compiler_driver.cc
@@ -374,6 +374,11 @@ CompilerDriver::CompilerDriver(CompilerBackend compiler_backend, InstructionSet
dex_to_dex_compiler_ = FindFunction<CompilerFn>(compiler_so_name, compiler_library_, "ArtCompileDEX");
+ sea_ir_compiler_ = NULL;
+ if (Runtime::Current()->IsSeaIRMode()) {
+ sea_ir_compiler_ = FindFunction<CompilerFn>(compiler_so_name, compiler_library_, "SeaIrCompileMethod");
+ }
+
init_compiler_context(*this);
if (compiler_backend_ == kPortable) {
@@ -2149,10 +2154,22 @@ void CompilerDriver::CompileMethod(const DexFile::CodeItem* code_item, uint32_t
// Do compile small methods.
dont_compile = false;
}
-
if (!dont_compile) {
- compiled_method = (*compiler_)(*this, code_item, access_flags, invoke_type, class_def_idx,
+ bool use_sea = false;
+
+ if (Runtime::Current()->IsSeaIRMode()) {
+ use_sea = true;
+ }
+ if (use_sea) {
+ use_sea = (std::string::npos != PrettyMethod(method_idx, dex_file).find("fibonacci"));
+ }
+ if (!use_sea) {
+ compiled_method = (*compiler_)(*this, code_item, access_flags, invoke_type, class_def_idx,
method_idx, class_loader, dex_file);
+ } else {
+ compiled_method = (*sea_ir_compiler_)(*this, code_item, access_flags, invoke_type, class_def_idx,
+ method_idx, class_loader, dex_file);
+ }
CHECK(compiled_method != NULL) << PrettyMethod(method_idx, dex_file);
} else if (allow_dex_to_dex_compilation) {
// TODO: add a mode to disable DEX-to-DEX compilation ?
diff --git a/src/compiler/driver/compiler_driver.h b/src/compiler/driver/compiler_driver.h
index fdd2149..b37b74b 100644
--- a/src/compiler/driver/compiler_driver.h
+++ b/src/compiler/driver/compiler_driver.h
@@ -404,6 +404,7 @@ class CompilerDriver {
uint32_t class_dex_idx, uint32_t method_idx,
jobject class_loader, const DexFile& dex_file);
CompilerFn compiler_;
+ CompilerFn sea_ir_compiler_;
CompilerFn dex_to_dex_compiler_;
diff --git a/src/compiler/sea_ir/frontend.cc b/src/compiler/sea_ir/frontend.cc
new file mode 100644
index 0000000..d4e1c7e
--- /dev/null
+++ b/src/compiler/sea_ir/frontend.cc
@@ -0,0 +1,81 @@
+
+#include <llvm/Support/Threading.h>
+
+#include "compiler/driver/compiler_driver.h"
+
+
+#include "compiler/llvm/llvm_compilation_unit.h"
+#include "compiler/dex/portable/mir_to_gbc.h"
+
+#include "leb128.h"
+#include "mirror/object.h"
+#include "runtime.h"
+#include "base/logging.h"
+
+#ifdef ART_SEA_IR_MODE
+#include "compiler/sea_ir/sea.h"
+#endif
+
+
+
+
+#ifdef ART_SEA_IR_MODE
+#include "compiler/sea_ir/sea.h"
+namespace art {
+
+static CompiledMethod* CompileMethodWithSeaIr(CompilerDriver& compiler,
+ const CompilerBackend compiler_backend,
+ const DexFile::CodeItem* code_item,
+ uint32_t access_flags, InvokeType invoke_type,
+ uint32_t class_def_idx, uint32_t method_idx,
+ jobject class_loader, const DexFile& dex_file
+#if defined(ART_USE_PORTABLE_COMPILER)
+ , llvm::LlvmCompilationUnit* llvm_compilation_unit
+#endif
+)
+{
+ VLOG(compiler) << "Compiling " << PrettyMethod(method_idx, dex_file) << "...";
+ sea_ir::SeaGraph* sg = sea_ir::SeaGraph::GetCurrentGraph();
+ sg->CompileMethod(code_item, class_def_idx, method_idx, dex_file);
+ sg->DumpSea("/tmp/temp.dot");
+ CHECK(0 && "No SEA compiled function exists yet.");
+ return NULL;
+}
+
+
+CompiledMethod* SeaIrCompileOneMethod(CompilerDriver& compiler,
+ const CompilerBackend backend,
+ const DexFile::CodeItem* code_item,
+ uint32_t access_flags,
+ InvokeType invoke_type,
+ uint32_t class_def_idx,
+ uint32_t method_idx,
+ jobject class_loader,
+ const DexFile& dex_file,
+ llvm::LlvmCompilationUnit* llvm_compilation_unit)
+{
+ return CompileMethodWithSeaIr(compiler, backend, code_item, access_flags, invoke_type, class_def_idx,
+ method_idx, class_loader, dex_file
+#if defined(ART_USE_PORTABLE_COMPILER)
+ , llvm_compilation_unit
+#endif
+
+ );
+}
+
+extern "C" art::CompiledMethod*
+ SeaIrCompileMethod(art::CompilerDriver& compiler,
+ const art::DexFile::CodeItem* code_item,
+ uint32_t access_flags, art::InvokeType invoke_type,
+ uint32_t class_def_idx, uint32_t method_idx, jobject class_loader,
+ const art::DexFile& dex_file)
+{
+ // TODO: check method fingerprint here to determine appropriate backend type. Until then, use build default
+ art::CompilerBackend backend = compiler.GetCompilerBackend();
+ return art::SeaIrCompileOneMethod(compiler, backend, code_item, access_flags, invoke_type,
+ class_def_idx, method_idx, class_loader, dex_file,
+ NULL /* use thread llvm_info */);
+}
+#endif
+
+} // end namespace art
diff --git a/src/compiler/sea_ir/sea.cc b/src/compiler/sea_ir/sea.cc
new file mode 100644
index 0000000..e08558f
--- /dev/null
+++ b/src/compiler/sea_ir/sea.cc
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "compiler/sea_ir/sea.h"
+#include "file_output_stream.h"
+
+
+
+namespace sea_ir {
+
+
+SeaGraph SeaGraph::graph_;
+int SeaNode::current_max_node_id_ = 0;
+
+SeaGraph* SeaGraph::GetCurrentGraph() {
+ return &sea_ir::SeaGraph::graph_;
+}
+
+void SeaGraph::DumpSea(std::string filename) const {
+ std::string result;
+ result += "digraph seaOfNodes {\n";
+ for(std::vector<Region*>::const_iterator cit = regions_.begin(); cit != regions_.end(); cit++) {
+ result += (*cit)->ToDot();
+ }
+ result += "}\n";
+ art::File* file = art::OS::OpenFile(filename.c_str(), true, true);
+ art::FileOutputStream fos(file);
+ fos.WriteFully(result.c_str(), result.size());
+ LOG(INFO) << "Written SEA string to file...";
+}
+
+void SeaGraph::CompileMethod(const art::DexFile::CodeItem* code_item,
+ uint32_t class_def_idx, uint32_t method_idx, const art::DexFile& dex_file) {
+ const uint16_t* code = code_item->insns_;
+ const size_t size_in_code_units = code_item->insns_size_in_code_units_;
+
+ Region* r = NULL;
+ // This maps target instruction pointers to their corresponding region objects.
+ std::map<const uint16_t*, Region*> target_regions;
+ size_t i = 0;
+
+ // Pass 1: Find the start instruction of basic blocks, as targets and flow-though of branches.
+ while (i < size_in_code_units) {
+ const art::Instruction* inst = art::Instruction::At(&code[i]);
+ if (inst->IsBranch()||inst->IsUnconditional()) {
+ int32_t offset = inst->GetTargetOffset();
+ if (target_regions.end() == target_regions.find(&code[i+offset])) {
+ Region* region = GetNewRegion();
+ target_regions.insert(std::pair<const uint16_t*, Region*>(&code[i+offset], region));
+ }
+ if (inst->IsFlowthrough() &&
+ (target_regions.end() == target_regions.find(&code[i+inst->SizeInCodeUnits()]))) {
+ Region* region = GetNewRegion();
+ target_regions.insert(std::pair<const uint16_t*, Region*>(&code[i+inst->SizeInCodeUnits()], region));
+ }
+ }
+ i += inst->SizeInCodeUnits();
+ }
+
+
+ // Pass 2: Assign instructions to region nodes and
+ // assign branches their control flow successors.
+ i = 0;
+ r = GetNewRegion();
+ sea_ir::SeaNode* last_node = NULL;
+ sea_ir::SeaNode* node = NULL;
+ while (i < size_in_code_units) {
+ const art::Instruction* inst = art::Instruction::At(&code[i]); //TODO: find workaround for this
+ last_node = node;
+ node = new sea_ir::SeaNode(inst);
+
+ if (inst->IsBranch() || inst->IsUnconditional()) {
+ int32_t offset = inst->GetTargetOffset();
+ std::map<const uint16_t*, Region*>::iterator it = target_regions.find(&code[i+offset]);
+ DCHECK(it != target_regions.end());
+ node->AddSuccessor(it->second);
+ }
+
+ std::map<const uint16_t*, Region*>::iterator it = target_regions.find(&code[i]);
+ if (target_regions.end() != it) {
+ // Get the already created region because this is a branch target.
+ Region* nextRegion = it->second;
+ if (last_node->GetInstruction()->IsBranch() && last_node->GetInstruction()->IsFlowthrough()) {
+ last_node->AddSuccessor(nextRegion);
+
+ }
+ r = nextRegion;
+ }
+
+ LOG(INFO) << inst->GetDexPc(code) << "*** " << inst->DumpString(&dex_file)
+ << " region:" <<r->StringId() << std::endl;
+ r->AddChild(node);
+ i += inst->SizeInCodeUnits();
+ }
+
+}
+
+
+Region* SeaGraph::GetNewRegion() {
+ Region* new_region = new Region();
+ AddRegion(new_region);
+ return new_region;
+}
+
+void SeaGraph::AddRegion(Region* r) {
+ DCHECK(r) << "Tried to add NULL region to SEA graph.";
+ regions_.push_back(r);
+}
+void Region::AddChild(sea_ir::SeaNode* instruction) {
+ DCHECK(inst) << "Tried to add NULL instruction to region node.";
+ instructions_.push_back(instruction);
+}
+
+SeaNode* Region::GetLastChild() const {
+ if (instructions_.size()>0) {
+ return instructions_.back();
+ }
+ return NULL;
+}
+
+std::string SeaNode::ToDot() const {
+ std::string node = "// Instruction: \n" + StringId() +
+ " [label=\"" + instruction_->DumpString(NULL) + "\"];\n";
+
+ for(std::vector<SeaNode*>::const_iterator cit = successors_.begin();
+ cit != successors_.end(); cit++) {
+ DCHECK(NULL != *cit) << "Null successor found for SeaNode" << StringId() << ".";
+ node += StringId() + " -> " + (*cit)->StringId() + ";\n\n";
+ }
+ return node;
+}
+
+std::string SeaNode::StringId() const {
+ std::stringstream ss;
+ ss << id_;
+ return ss.str();
+}
+
+std::string Region::ToDot() const {
+ std::string result = "// Region: \n" +
+ StringId() + " [label=\"region " + StringId() + "\"];";
+
+ for(std::vector<SeaNode*>::const_iterator cit = instructions_.begin();
+ cit != instructions_.end(); cit++) {
+ result += (*cit)->ToDot();
+ result += StringId() + " -> " + (*cit)->StringId() + ";\n";
+ }
+
+ result += "// End Region.\n";
+ return result;
+}
+
+void SeaNode::AddSuccessor(SeaNode* successor) {
+ DCHECK(successor) << "Tried to add NULL successor to SEA node.";
+ successors_.push_back(successor);
+ return;
+}
+
+} // end namespace
diff --git a/src/compiler/sea_ir/sea.h b/src/compiler/sea_ir/sea.h
new file mode 100644
index 0000000..0ebd4d0
--- /dev/null
+++ b/src/compiler/sea_ir/sea.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "dex_file.h"
+#include "dex_instruction.h"
+
+#ifndef SEA_IR_H_
+#define SEA_IR_H_
+
+#include <set>
+#include <map>
+
+namespace sea_ir {
+
+
+class SeaNode {
+ public:
+ explicit SeaNode(const art::Instruction* in):id_(GetNewId()), instruction_(in), successors_() {};
+ explicit SeaNode():id_(GetNewId()), instruction_(NULL) {};
+ void AddSuccessor(SeaNode* successor);
+ const art::Instruction* GetInstruction() {
+ DCHECK(NULL != instruction_);
+ return instruction_;
+ }
+ std::string StringId() const;
+ // Returns a dot language formatted string representing the node and
+ // (by convention) outgoing edges, so that the composition of theToDot() of all nodes
+ // builds a complete dot graph (without prolog and epilog though).
+ virtual std::string ToDot() const;
+ virtual ~SeaNode(){};
+
+ protected:
+ // Returns the id of the current block as string
+
+ static int GetNewId() {
+ return current_max_node_id_++;
+ }
+
+
+ private:
+ const int id_;
+ const art::Instruction* const instruction_;
+ std::vector<sea_ir::SeaNode*> successors_;
+ static int current_max_node_id_;
+};
+
+
+
+class Region : public SeaNode {
+ public:
+ explicit Region():SeaNode() {}
+ void AddChild(sea_ir::SeaNode* instruction);
+ SeaNode* GetLastChild() const;
+
+ // Returns a dot language formatted string representing the node and
+ // (by convention) outgoing edges, so that the composition of theToDot() of all nodes
+ // builds a complete dot graph (without prolog and epilog though).
+ virtual std::string ToDot() const;
+
+ private:
+ std::vector<sea_ir::SeaNode*> instructions_;
+};
+
+
+
+class SeaGraph {
+ public:
+ static SeaGraph* GetCurrentGraph();
+ void CompileMethod(const art::DexFile::CodeItem* code_item,
+ uint32_t class_def_idx, uint32_t method_idx, const art::DexFile& dex_file);
+ // Returns a string representation of the region and its Instruction children
+ void DumpSea(std::string filename) const;
+ /*** Static helper functions follow: ***/
+ static int ParseInstruction(const uint16_t* code_ptr,
+ art::DecodedInstruction* decoded_instruction);
+ static bool IsInstruction(const uint16_t* code_ptr);
+
+ private:
+ // Registers the parameter as a child region of the SeaGraph instance
+ void AddRegion(Region* r);
+ // Returns new region and registers it with the SeaGraph instance
+ Region* GetNewRegion();
+ static SeaGraph graph_;
+ std::vector<Region*> regions_;
+};
+
+
+} // end namespace sea_ir
+#endif
diff --git a/src/dex2oat.cc b/src/dex2oat.cc
index b5dc319..7cf54b4 100644
--- a/src/dex2oat.cc
+++ b/src/dex2oat.cc
@@ -823,6 +823,12 @@ static int dex2oat(int argc, char** argv) {
options.push_back(std::make_pair("-small", reinterpret_cast<void*>(NULL)));
#endif // ART_SMALL_MODE
+
+#ifdef ART_SEA_IR_MODE
+ options.push_back(std::make_pair("-sea_ir", reinterpret_cast<void*>(NULL)));
+#endif
+
+
Dex2Oat* p_dex2oat;
if (!Dex2Oat::Create(&p_dex2oat, options, compiler_backend, instruction_set, thread_count,
support_debugging)) {
diff --git a/src/runtime.cc b/src/runtime.cc
index 1889d88..0a38eb9 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -357,6 +357,7 @@ Runtime::ParsedOptions* Runtime::ParsedOptions::Create(const Options& options, b
parsed->small_mode_method_threshold_ = Runtime::kDefaultSmallModeMethodThreshold;
parsed->small_mode_method_dex_size_limit_ = Runtime::kDefaultSmallModeMethodDexSizeLimit;
+ parsed->sea_ir_mode_ = false;
// gLogVerbosity.class_linker = true; // TODO: don't check this in!
// gLogVerbosity.compiler = true; // TODO: don't check this in!
// gLogVerbosity.heap = true; // TODO: don't check this in!
@@ -566,6 +567,8 @@ Runtime::ParsedOptions* Runtime::ParsedOptions::Create(const Options& options, b
Trace::SetDefaultClockSource(kProfilerClockSourceDual);
} else if (option == "-small") {
parsed->small_mode_ = true;
+ }else if (option == "-sea_ir") {
+ parsed->sea_ir_mode_ = true;
} else if (StartsWith(option, "-small-mode-methods-max:")) {
parsed->small_mode_method_threshold_ = ParseIntegerOrDie(option);
} else if (StartsWith(option, "-small-mode-methods-size-max:")) {
@@ -794,6 +797,7 @@ bool Runtime::Init(const Options& raw_options, bool ignore_unrecognized) {
small_mode_method_threshold_ = options->small_mode_method_threshold_;
small_mode_method_dex_size_limit_ = options->small_mode_method_dex_size_limit_;
+ sea_ir_mode_ = options->sea_ir_mode_;
vfprintf_ = options->hook_vfprintf_;
exit_ = options->hook_exit_;
abort_ = options->hook_abort_;
diff --git a/src/runtime.h b/src/runtime.h
index dfcd647..0b893a3 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -108,9 +108,12 @@ class Runtime {
void (*hook_abort_)();
std::vector<std::string> properties_;
bool small_mode_;
+
size_t small_mode_method_threshold_;
size_t small_mode_method_dex_size_limit_;
+ bool sea_ir_mode_;
+
private:
ParsedOptions() {}
};
@@ -131,6 +134,14 @@ class Runtime {
return is_concurrent_gc_enabled_;
}
+ bool IsSeaIRMode() const {
+ return sea_ir_mode_;
+ }
+
+ void SetSeaIRMode(bool sea_ir_mode) {
+ sea_ir_mode_ = sea_ir_mode;
+ }
+
bool IsSmallMode() const {
return small_mode_;
}
@@ -374,6 +385,8 @@ class Runtime {
size_t small_mode_method_threshold_;
size_t small_mode_method_dex_size_limit_;
+ bool sea_ir_mode_;
+
// The host prefix is used during cross compilation. It is removed
// from the start of host paths such as:
// $ANDROID_PRODUCT_OUT/system/framework/boot.oat