Adding oat_process
- Added oat_process, a version of app_process use to launch frameworks apps
- Added liboat_runtime, a version of libandroid_runtime that uses art instead of dvm
This is just a special makefile, frameworks/base/core/jni code is used for source
- Added support for build a boot.oat with the full BOOTCLASSPATH
The older smaller boat.oat is now core.oat
- Added mem_map code for making sure a requested memory region is available
Moved mem_map code to cc file to make easier to debug with smaller rebuild
- Moved oat base address to 0x6000000 as a work around to host addres conflict
- Added -Xms and -Xmx options to dex2oat to allow build specific memory options
- Fixed miranda method initialization problem found compiling full bootclasspath
- Made compiler.cc tolerant of verification errors found compiling full bootclasspath
- Bumped arena block alloc warning to avoid noise when compiling full bootclasspath
- Marked implicit GC unimplemented to fail fast
- Added --output argument to oatdump
- Made many object asserts tolerate access in IsErroneous state
now that verifier is failing validation of some classes during compilation
- Made runtime tolerate unknown access as short term solution for oat_process
- Workaround SSA issue to restore full bootclasspath compilation
- Added test-art-target-processs to excercise oat_process with "am"
"am" found bug where class_linker was using Method::GetClass and not ::GetDeclaringClass
Change-Id: I1a645a142b163e06bab9e72eb094ae1f1dbfbd97
diff --git a/src/mem_map.cc b/src/mem_map.cc
new file mode 100644
index 0000000..e44a894
--- /dev/null
+++ b/src/mem_map.cc
@@ -0,0 +1,163 @@
+#include "mem_map.h"
+
+#include <sys/mman.h>
+
+#include "utils.h"
+
+/*
+ * Copyright (C) 2008 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 "mem_map.h"
+
+#include <sys/mman.h>
+
+namespace art {
+
+size_t ParseHex(const std::string& string) {
+ CHECK_EQ(8U, string.size());
+ const char* str = string.c_str();
+ char* end;
+ size_t value = strtoul(str, &end, 16);
+ CHECK(end != str) << "Failed to parse hexadecimal value from " << string;
+ CHECK(*end == '\0') << "Failed to parse hexadecimal value from " << string;
+ return value;
+}
+
+void CheckMapRequest(byte* addr, size_t length) {
+#ifndef NDEBUG
+ if (addr == NULL) {
+ return;
+ }
+ size_t base = reinterpret_cast<size_t>(addr);
+ size_t limit = base + length;
+
+ std::string maps;
+ bool read = ReadFileToString("/proc/self/maps", &maps);
+ if (!read) {
+ PLOG(FATAL) << "Failed to read /proc/self/maps";
+ }
+ // Quick and dirty parse of output like shown below. We only focus
+ // on grabbing the two 32-bit hex values at the start of each line
+ // and will fail on wider addresses found on 64-bit systems.
+
+ // 00008000-0001f000 r-xp 00000000 b3:01 273 /system/bin/toolbox
+ // 0001f000-00021000 rw-p 00017000 b3:01 273 /system/bin/toolbox
+ // 00021000-00029000 rw-p 00000000 00:00 0 [heap]
+ // 40011000-40053000 r-xp 00000000 b3:01 1050 /system/lib/libc.so
+ // 40053000-40056000 rw-p 00042000 b3:01 1050 /system/lib/libc.so
+ // 40056000-40061000 rw-p 00000000 00:00 0
+ // 40061000-40063000 r-xp 00000000 b3:01 1107 /system/lib/libusbhost.so
+ // 40063000-40064000 rw-p 00002000 b3:01 1107 /system/lib/libusbhost.so
+ // 4009d000-400a0000 r-xp 00000000 b3:01 1022 /system/lib/liblog.so
+ // 400a0000-400a1000 rw-p 00003000 b3:01 1022 /system/lib/liblog.so
+ // 400b7000-400cc000 r-xp 00000000 b3:01 932 /system/lib/libm.so
+ // 400cc000-400cd000 rw-p 00015000 b3:01 932 /system/lib/libm.so
+ // 400cf000-400d0000 r--p 00000000 00:00 0
+ // 400e4000-400ec000 r--s 00000000 00:0b 388 /dev/__properties__ (deleted)
+ // 400ec000-400fa000 r-xp 00000000 b3:01 1101 /system/lib/libcutils.so
+ // 400fa000-400fb000 rw-p 0000e000 b3:01 1101 /system/lib/libcutils.so
+ // 400fb000-4010a000 rw-p 00000000 00:00 0
+ // 4010d000-4010e000 r-xp 00000000 b3:01 929 /system/lib/libstdc++.so
+ // 4010e000-4010f000 rw-p 00001000 b3:01 929 /system/lib/libstdc++.so
+ // b0001000-b0009000 r-xp 00001000 b3:01 1098 /system/bin/linker
+ // b0009000-b000a000 rw-p 00009000 b3:01 1098 /system/bin/linker
+ // b000a000-b0015000 rw-p 00000000 00:00 0
+ // bee35000-bee56000 rw-p 00000000 00:00 0 [stack]
+ // ffff0000-ffff1000 r-xp 00000000 00:00 0 [vectors]
+
+ for (size_t i = 0; i < maps.size(); i++) {
+ size_t remaining = maps.size() - i;
+ if (remaining < 8+1+8) { // 00008000-0001f000
+ LOG(FATAL) << "Failed to parse at pos " << i << "\n" << maps;
+ }
+ std::string start_str = maps.substr(i, 8);
+ std::string end_str = maps.substr(i+1+8, 8);
+ uint32_t start = ParseHex(start_str);
+ uint32_t end = ParseHex(end_str);
+ CHECK(!(base >= start && base < end)
+ && !(limit >= start && limit < end)
+ && !(base <= start && limit > end))
+ << StringPrintf("Requested region %08x-%08x overlaps with existing map %08x-%08x\n",
+ base, limit, start, end)
+ << maps;
+ i += 8+1+8;
+ i = maps.find('\n', i);
+ CHECK(i != std::string::npos) << "Failed to find newline from pos " << i << "\n" << maps;
+ }
+#endif
+}
+
+MemMap* MemMap::Map(byte* addr, size_t length, int prot) {
+ CHECK_NE(0U, length);
+ CHECK_NE(0, prot);
+ size_t page_aligned_size = RoundUp(length, kPageSize);
+ CheckMapRequest(addr, page_aligned_size);
+ byte* actual = reinterpret_cast<byte*>(mmap(addr,
+ page_aligned_size,
+ prot,
+ MAP_PRIVATE | MAP_ANONYMOUS,
+ -1,
+ 0));
+ if (actual == MAP_FAILED) {
+ PLOG(ERROR) << "mmap failed";
+ return NULL;
+ }
+ return new MemMap(actual, length, actual, page_aligned_size);
+}
+
+MemMap* MemMap::Map(byte* addr, size_t length, int prot, int flags, int fd, off_t start) {
+ CHECK_NE(0U, length);
+ CHECK_NE(0, prot);
+ CHECK_NE(0, flags & (MAP_SHARED | MAP_PRIVATE));
+ // adjust to be page-aligned
+ int page_offset = start % kPageSize;
+ off_t page_aligned_offset = start - page_offset;
+ size_t page_aligned_size = RoundUp(length + page_offset, kPageSize);
+ CheckMapRequest(addr, page_aligned_size);
+ byte* actual = reinterpret_cast<byte*>(mmap(addr,
+ page_aligned_size,
+ prot,
+ flags,
+ fd,
+ page_aligned_offset));
+ if (actual == MAP_FAILED) {
+ PLOG(ERROR) << "mmap failed";
+ return NULL;
+ }
+ return new MemMap(actual + page_offset, length, actual, page_aligned_size);
+}
+
+MemMap::~MemMap() {
+ if (base_addr_ == NULL && base_length_ == 0) {
+ return;
+ }
+ int result = munmap(base_addr_, base_length_);
+ base_addr_ = NULL;
+ base_length_ = 0;
+ if (result == -1) {
+ PLOG(FATAL) << "munmap failed";
+ }
+}
+
+MemMap::MemMap(byte* addr, size_t length, void* base_addr, size_t base_length)
+ : addr_(addr), length_(length), base_addr_(base_addr), base_length_(base_length) {
+ CHECK(addr_ != NULL);
+ CHECK(length_ != 0);
+ CHECK(base_addr_ != NULL);
+ CHECK(base_length_ != 0);
+};
+
+} // namespace art