Initialize the bootstrap class path from standard sources.
Change-Id: Ib49d21f98fd76504e5d3675fc731261426ca84ed
diff --git a/build/Android.common.mk b/build/Android.common.mk
index 56b5db2..f92bc09 100644
--- a/build/Android.common.mk
+++ b/build/Android.common.mk
@@ -82,6 +82,7 @@
src/dex_instruction_visitor_test.cc \
src/jni_compiler_test.cc.arm \
src/object_test.cc \
+ src/runtime_test.cc \
src/space_test.cc
TEST_TARGET_SRC_FILES := \
diff --git a/src/heap.cc b/src/heap.cc
index 6ec6aac..bc54a82 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -8,6 +8,7 @@
#include "mark_sweep.h"
#include "object.h"
#include "space.h"
+#include "scoped_ptr.h"
#include "stl_util.h"
namespace art {
diff --git a/src/jni_internal.cc b/src/jni_internal.cc
index 6c6f493..6aa5c77 100644
--- a/src/jni_internal.cc
+++ b/src/jni_internal.cc
@@ -7,6 +7,8 @@
#include "logging.h"
#include "runtime.h"
+#include "scoped_ptr.h"
+#include "stringpiece.h"
#include "thread.h"
namespace art {
@@ -32,7 +34,8 @@
Runtime::Options options;
for (int i = 0; i < args->nOptions; ++i) {
JavaVMOption* option = &args->options[i];
- options.push_back(std::make_pair(option->optionString, option->extraInfo));
+ options.push_back(std::make_pair(StringPiece(option->optionString),
+ option->extraInfo));
}
bool ignore_unrecognized = args->ignoreUnrecognized;
scoped_ptr<Runtime> runtime(Runtime::Create(options, ignore_unrecognized));
diff --git a/src/runtime.cc b/src/runtime.cc
index f03157f..18b001e 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -8,6 +8,7 @@
#include "class_linker.h"
#include "heap.h"
+#include "scoped_ptr.h"
#include "thread.h"
namespace art {
@@ -50,9 +51,61 @@
// notreached
}
+void ParseClassPath(const char* class_path, std::vector<std::string>* vec) {
+ CHECK(vec != NULL);
+ scoped_ptr_malloc<char> tmp(strdup(class_path));
+ char* full = tmp.get();
+ char* p = full;
+ while (p) {
+ p = strpbrk(full, ":");
+ if (p != NULL) {
+ p[0] = '\0';
+ }
+ if (full[0] != '\0') {
+ vec->push_back(std::string(full));
+ }
+ if (p) {
+ full = p + 1;
+ }
+ }
+}
+
+// TODO: move option processing elsewhere.
+const char* FindBootClassPath(const Runtime::Options& options) {
+ const char* boot_class_path = getenv("BOOTCLASSPATH");
+ const char* flag = "-Xbootclasspath:";
+ for (size_t i = 0; i < options.size(); ++i) {
+ const StringPiece& option = options[i].first;
+ if (option.starts_with(flag)) {
+ boot_class_path = option.substr(strlen(flag)).data();
+ }
+ }
+ if (boot_class_path == NULL) {
+ return "";
+ } else {
+ return boot_class_path;
+ }
+}
+
+void CreateBootClassPath(const Runtime::Options& options,
+ std::vector<DexFile*>* boot_class_path) {
+ CHECK(boot_class_path != NULL);
+ const char* str = FindBootClassPath(options);
+ std::vector<std::string> parsed;
+ ParseClassPath(str, &parsed);
+ for (size_t i = 0; i < parsed.size(); ++i) {
+ DexFile* dex_file = DexFile::OpenFile(parsed[i].c_str());
+ if (dex_file != NULL) {
+ boot_class_path->push_back(dex_file);
+ }
+ }
+}
+
+// TODO: do something with ignore_unrecognized when we parse the option
+// strings for real.
Runtime* Runtime::Create(const Options& options, bool ignore_unrecognized) {
- // TODO: parse arguments
- std::vector<DexFile*> boot_class_path; // empty
+ std::vector<DexFile*> boot_class_path;
+ CreateBootClassPath(options, &boot_class_path);
return Runtime::Create(boot_class_path);
}
diff --git a/src/runtime.h b/src/runtime.h
index 9ff532c..7a1a504 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -4,22 +4,23 @@
#define ART_SRC_RUNTIME_H_
#include <vector>
+#include <utility>
#include "globals.h"
#include "macros.h"
-#include "dex_file.h"
#include "stringpiece.h"
namespace art {
class ClassLinker;
+class DexFile;
class Heap;
class JniEnvironment;
class ThreadList;
class Runtime {
public:
- typedef std::vector<std::pair<const char*, void*> > Options;
+ typedef std::vector<std::pair<StringPiece, void*> > Options;
// Creates and initializes a new runtime.
static Runtime* Create(const Options& options, bool ignore_unrecognized);
diff --git a/src/runtime_test.cc b/src/runtime_test.cc
new file mode 100644
index 0000000..4b59cb3
--- /dev/null
+++ b/src/runtime_test.cc
@@ -0,0 +1,69 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+
+#include "src/runtime.h"
+
+#include "gtest/gtest.h"
+
+namespace art {
+void ParseClassPath(const char* class_path, std::vector<std::string>* vec);
+}
+
+namespace {
+
+TEST(RuntimeTest, ParseClassPath) {
+ std::vector<std::string> vec;
+
+ art::ParseClassPath("", &vec);
+ EXPECT_EQ(0U, vec.size());
+ vec.clear();
+
+ art::ParseClassPath(":", &vec);
+ EXPECT_EQ(0U, vec.size());
+ vec.clear();
+
+ art::ParseClassPath(":foo", &vec);
+ EXPECT_EQ(1U, vec.size());
+ vec.clear();
+
+ art::ParseClassPath("foo:", &vec);
+ EXPECT_EQ(1U, vec.size());
+ vec.clear();
+
+ art::ParseClassPath(":foo:", &vec);
+ EXPECT_EQ(1U, vec.size());
+ vec.clear();
+
+ art::ParseClassPath("foo:bar", &vec);
+ EXPECT_EQ(2U, vec.size());
+ vec.clear();
+
+ art::ParseClassPath(":foo:bar", &vec);
+ EXPECT_EQ(2U, vec.size());
+ vec.clear();
+
+ art::ParseClassPath("foo:bar:", &vec);
+ EXPECT_EQ(2U, vec.size());
+ vec.clear();
+
+ art::ParseClassPath(":foo:bar:", &vec);
+ EXPECT_EQ(2U, vec.size());
+ vec.clear();
+
+ art::ParseClassPath("foo:bar:baz", &vec);
+ EXPECT_EQ(3U, vec.size());
+ vec.clear();
+
+ art::ParseClassPath(":foo:bar:baz", &vec);
+ EXPECT_EQ(3U, vec.size());
+ vec.clear();
+
+ art::ParseClassPath("foo:bar:baz:", &vec);
+ EXPECT_EQ(3U, vec.size());
+ vec.clear();
+
+ art::ParseClassPath(":foo:bar:baz:", &vec);
+ EXPECT_EQ(3U, vec.size());
+ vec.clear();
+}
+
+} // namespace