Add class loading infrastructure.

Change-Id: I94bdabcefdf1030ee1827d9219eaf60e4dc818ca
diff --git a/src/art.cc b/src/art.cc
deleted file mode 100644
index 08ae34d..0000000
--- a/src/art.cc
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-
-#include "art.h"
-
-namespace art {
-
-bool Art::Startup() {
-  return true;
-}
-
-void Art::Shutdown() {
-}
-
-}  // namespace art
diff --git a/src/art.h b/src/art.h
deleted file mode 100644
index b02c1a5..0000000
--- a/src/art.h
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-
-#ifndef ART_SRC_ART_H_
-#define ART_SRC_ART_H_
-
-namespace art {
-
-class Art {
- public:
-  static bool Startup();
-  static void Shutdown();
-};
-
-}  // namespace art
-
-namespace r = art;
-
-#endif  // ART_SRC_ART_H_
diff --git a/src/dex_file.cc b/src/dex_file.cc
new file mode 100644
index 0000000..a89baaf
--- /dev/null
+++ b/src/dex_file.cc
@@ -0,0 +1,128 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+
+#include "src/dex_file.h"
+#include "src/heap.h"
+#include "src/globals.h"
+#include "src/logging.h"
+#include "src/object.h"
+#include "src/raw_dex_file.h"
+
+namespace art {
+
+DexFile* DexFile::Open(const char* filename) {
+  RawDexFile* raw = RawDexFile::Open(filename);
+  if (raw == NULL) {
+    return NULL;
+  }
+  DexFile* dex_file = new DexFile(raw);
+  dex_file->Init();
+  return dex_file;
+}
+
+DexFile::~DexFile() {
+  delete raw_;
+  delete[] strings_;
+  delete[] classes_;
+  delete[] methods_;
+  delete[] fields_;
+}
+
+void DexFile::Init() {
+  num_strings_ = raw_->NumStringIds();
+  strings_ = new String*[num_strings_];
+
+  num_classes_ = raw_->NumTypeIds();
+  classes_ = new Class*[num_classes_];
+
+  num_methods_ = raw_->NumMethodIds();
+  methods_ = new Method*[num_methods_];
+
+  num_fields_ = raw_->NumFieldIds();
+  fields_ = new Field*[num_fields_];
+}
+
+Class* DexFile::LoadClass(const char* descriptor) {
+  const RawDexFile::ClassDef* class_def = raw_->FindClassDef(descriptor);
+  if (class_def == NULL) {
+    return NULL;
+  } else {
+    return LoadClass(*class_def);
+  }
+}
+
+Class* DexFile::LoadClass(const RawDexFile::ClassDef& class_def) {
+  const byte* class_data = raw_->GetClassData(class_def);
+  RawDexFile::ClassDataHeader header;
+  raw_->DecodeClassDataHeader(&header, class_data);
+
+  const char* descriptor = raw_->GetClassDescriptor(class_def);
+  CHECK(descriptor != NULL);
+
+  // Allocate storage for the new class object.
+  size_t size = Class::Size(header.static_fields_size_);
+  Class* klass = Heap::AllocClass(size);
+  CHECK(klass != NULL);
+
+  //klass->klass_ = NULL;  // TODO
+  klass->descriptor_ = descriptor;
+  klass->access_flags_ = class_def.access_flags_;
+  klass->class_loader_ = NULL;  // TODO
+  klass->dex_file_ = this;
+  klass->primitive_type_ = Class::kPrimNot;
+  klass->status_ = Class::kClassIdx;
+
+  klass->super_ = reinterpret_cast<Class*>(class_def.superclass_idx_);
+
+  // Load class interfaces.
+  LoadClassInterfaces(class_def, klass);
+
+  // Load static fields.
+  if (header.static_fields_size_ != 0) {
+    for (size_t i = 0; i < header.static_fields_size_; ++i) {
+      // TODO
+    }
+  }
+
+  // Load instance fields.
+  if (header.instance_fields_size_ != 0) {
+    for (size_t i = 0; i < header.instance_fields_size_; ++i) {
+      // TODO
+    }
+  }
+
+  // Load direct methods.
+
+  // Load virtual methods.
+
+  return klass;
+}
+
+void DexFile::LoadClassInterfaces(const RawDexFile::ClassDef& class_def,
+                                  Class* klass) {
+  const RawDexFile::TypeList* list = raw_->GetInterfacesList(class_def);
+  if (list != NULL) {
+    klass->interface_count_ = list->Size();
+    klass->interfaces_ = new Class*[list->Size()];
+    for (size_t i = 0; i < list->Size(); ++i) {
+      const RawDexFile::TypeItem& type_item = list->GetTypeItem(i);
+      klass->interfaces_[i] = reinterpret_cast<Class*>(type_item.type_idx_);
+    }
+  }
+}
+
+void DexFile::LoadSFields(Class* klass, const RawDexFile::Field* src,
+                            Field* dst) {
+
+}
+
+void DexFile::LoadIFields(Class* klass, const RawDexFile::Field* src,
+                          Field* dst) {
+}
+
+void DexFile::LoadMethod(Class* klass, const RawDexFile::Method* src,
+                         Method* dst) {
+}
+
+
+
+}  // namespace art
diff --git a/src/dex_file.h b/src/dex_file.h
new file mode 100644
index 0000000..3cd1a57
--- /dev/null
+++ b/src/dex_file.h
@@ -0,0 +1,77 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+
+#ifndef ART_SRC_DEX_FILE_H_
+#define ART_SRC_DEX_FILE_H_
+
+#include "src/globals.h"
+#include "src/macros.h"
+#include "src/object.h"
+#include "src/raw_dex_file.h"
+
+namespace art {
+
+class DexFile {
+ public:
+  // Opens a dex file.  Returns NULL on failure.
+  static DexFile* Open(const char* filename);
+
+  // Close and deallocate.
+  ~DexFile();
+
+  size_t NumTypes() {
+    return num_classes_;
+  }
+
+  size_t NumMethods() {
+    return num_methods_;
+  }
+
+  Class* LoadClass(const char* descriptor);
+
+  Class* LoadClass(const RawDexFile::ClassDef& class_def);
+
+ private:
+  DexFile(RawDexFile* raw) : raw_(raw) {};
+
+  void Init();
+
+  void LoadClassInterfaces(const RawDexFile::ClassDef& class_def,
+                             Class *klass);
+
+  void LoadSFields(Class* klass, const RawDexFile::Field* src,
+                   Field* dst);
+
+  void LoadIFields(Class* klass, const RawDexFile::Field* src,
+                   Field* dst);
+
+  void LoadMethod(Class* klass, const RawDexFile::Method* src,
+                  Method* dst);
+
+  // Table of contents for interned String objects.
+  String** strings_;
+  size_t num_strings_;
+
+  // Table of contents for Class objects.
+  Class** classes_;
+  size_t num_classes_;
+
+  // Table of contents for methods.
+  Method** methods_;
+  size_t num_methods_;
+
+  // Table of contents for fields.
+  Field** fields_;
+  size_t num_fields_;
+
+  // The size of the DEX file, in bytes.
+  size_t length_;
+
+  // The underlying dex file.
+  RawDexFile* raw_;
+
+  DISALLOW_COPY_AND_ASSIGN(DexFile);
+};
+
+}  // namespace art
+
+#endif  // ART_SRC_DEX_FILE_H_
diff --git a/src/dex_file_test.cc b/src/dex_file_test.cc
new file mode 100644
index 0000000..ff80e46
--- /dev/null
+++ b/src/dex_file_test.cc
@@ -0,0 +1,35 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+
+#include "src/dex_file.h"
+#include "src/scoped_ptr.h"
+
+#include <stdio.h>
+#include "gtest/gtest.h"
+
+namespace art {
+
+static const char* filename =
+    "/usr/local/google/work/dalvik-dev-git/Nested.dex";
+
+TEST(DexFile, Open) {
+  scoped_ptr<DexFile> dex(DexFile::Open(filename));
+  ASSERT_TRUE(dex != NULL);
+}
+
+TEST(DexFile, LoadNonexistent) {
+  scoped_ptr<DexFile> dex(DexFile::Open(filename));
+  ASSERT_TRUE(dex != NULL);
+
+  Class* klass = dex->LoadClass("NoSuchClass");
+  ASSERT_TRUE(klass == NULL);
+}
+
+TEST(DexFile, Load) {
+  scoped_ptr<DexFile> dex(DexFile::Open(filename));
+  ASSERT_TRUE(dex != NULL);
+
+  Class* klass = dex->LoadClass("LNested;");
+  ASSERT_TRUE(klass != NULL);
+}
+
+}  // namespace art
diff --git a/src/dex_instruction_visitor_test.cc b/src/dex_instruction_visitor_test.cc
index 239e1eb..768fc50 100644
--- a/src/dex_instruction_visitor_test.cc
+++ b/src/dex_instruction_visitor_test.cc
@@ -1,6 +1,7 @@
 // Copyright 2011 Google Inc. All Rights Reserved.
 
 #include "src/dex_instruction_visitor.h"
+#include "src/scoped_ptr.h"
 
 #include <iostream>
 #include "gtest/gtest.h"
@@ -10,7 +11,7 @@
 class TestVisitor : public DexInstructionVisitor<TestVisitor> {};
 
 TEST(Instruction, Init) {
-  TestVisitor visitor;
+  scoped_ptr<TestVisitor> visitor(new TestVisitor);
 }
 
 class CountVisitor : public DexInstructionVisitor<CountVisitor> {
diff --git a/src/globals.h b/src/globals.h
index 92d0cf7..1904203 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -3,6 +3,7 @@
 #ifndef ART_SRC_GLOBALS_H_
 #define ART_SRC_GLOBALS_H_
 
+#include <stddef.h>
 #include <stdint.h>
 
 namespace art {
diff --git a/src/heap.h b/src/heap.h
new file mode 100644
index 0000000..2673932
--- /dev/null
+++ b/src/heap.h
@@ -0,0 +1,22 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+// Author: cshapiro@google.com (Carl Shapiro)
+
+#ifndef ART_SRC_HEAP_H_
+#define ART_SRC_HEAP_H_
+
+#include "src/globals.h"
+#include "src/object.h"
+
+namespace art {
+
+class Heap {
+ public:
+  static Class* AllocClass(size_t size) {
+    byte* raw = new byte[size];
+    return reinterpret_cast<Class*>(raw);
+  }
+};
+
+}  // namespace art
+
+#endif  // ART_SRC_HEAP_H_
diff --git a/src/leb128.h b/src/leb128.h
new file mode 100644
index 0000000..aa8b895
--- /dev/null
+++ b/src/leb128.h
@@ -0,0 +1,76 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+
+#ifndef ART_SRC_LEB128_H_
+#define ART_SRC_LEB128_H_
+
+#include "src/globals.h"
+
+namespace art {
+
+// Reads an unsigned LEB128 value, updating the given pointer to point
+// just past the end of the read value. This function tolerates
+// non-zero high-order bits in the fifth encoded byte.
+static inline uint32_t DecodeUnsignedLeb128(const byte** data) {
+  const byte* ptr = *data;
+  int result = *(ptr++);
+  if (result > 0x7f) {
+    int cur = *(ptr++);
+    result = (result & 0x7f) | ((cur & 0x7f) << 7);
+    if (cur > 0x7f) {
+      cur = *(ptr++);
+      result |= (cur & 0x7f) << 14;
+      if (cur > 0x7f) {
+        cur = *(ptr++);
+        result |= (cur & 0x7f) << 21;
+        if (cur > 0x7f) {
+          // Note: We don't check to see if cur is out of range here,
+          // meaning we tolerate garbage in the four high-order bits.
+          cur = *(ptr++);
+          result |= cur << 28;
+        }
+      }
+    }
+  }
+  *data = ptr;
+  return (uint32_t)result;
+}
+
+// Reads a signed LEB128 value, updating the given pointer to point
+// just past the end of the read value. This function tolerates
+// non-zero high-order bits in the fifth encoded byte.
+static inline int32_t DecodeSignedLeb128(const byte** data) {
+  const byte* ptr = *data;
+  int32_t result = *(ptr++);
+  if (result <= 0x7f) {
+    result = (result << 25) >> 25;
+  } else {
+    int cur = *(ptr++);
+    result = (result & 0x7f) | ((cur & 0x7f) << 7);
+    if (cur <= 0x7f) {
+      result = (result << 18) >> 18;
+    } else {
+      cur = *(ptr++);
+      result |= (cur & 0x7f) << 14;
+      if (cur <= 0x7f) {
+        result = (result << 11) >> 11;
+      } else {
+        cur = *(ptr++);
+        result |= (cur & 0x7f) << 21;
+        if (cur <= 0x7f) {
+          result = (result << 4) >> 4;
+        } else {
+          // Note: We don't check to see if cur is out of range here,
+          // meaning we tolerate garbage in the four high-order bits.
+          cur = *(ptr++);
+          result |= cur << 28;
+        }
+      }
+    }
+  }
+  *data = ptr;
+  return result;
+}
+
+}  // namespace art
+
+#endif  // ART_SRC_LEB128_H_
diff --git a/src/logging.h b/src/logging.h
index ccab249..e1b99d6 100644
--- a/src/logging.h
+++ b/src/logging.h
@@ -74,6 +74,7 @@
 #endif
 
 #define LOG_INFO LogMessage(__FILE__, __LINE__)
+#define LOG_WARN LOG_INFO  // TODO
 #define LOG_FATAL LogMessageFatal(__FILE__, __LINE__)
 #define LOG(severity) LOG_ ## severity.stream()
 #define LG LOG(INFO)
diff --git a/src/object.h b/src/object.h
new file mode 100644
index 0000000..b7d3a50
--- /dev/null
+++ b/src/object.h
@@ -0,0 +1,214 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+
+#ifndef ART_SRC_OBJECT_H_
+#define ART_SRC_OBJECT_H_
+
+#include "src/globals.h"
+
+namespace art {
+
+class Array;
+class Class;
+class DexFile;
+class IField;
+class InterfaceEntry;
+class Monitor;
+class Method;
+class SField;
+
+class Object {
+  Class* klass_;
+  Monitor* lock_;
+};
+
+class Field {
+  Class* klass_;
+};
+
+// Instance fields.
+class IField : Field {
+  // TODO
+};
+
+// Static fields.
+class SField : Field {
+  // TODO
+};
+
+// Class objects.
+class Class : Object {
+ public:
+  enum ClassStatus {
+    kClassError = -1,
+    kClassNotReady = 0,
+    kClassIdx = 1,  // loaded, DEX idx in super or ifaces
+    kClassLoaded = 2,  // DEX idx values resolved
+    kClassResolved = 3,  // part of linking
+    kClassVerifying = 4,  // in the process of being verified
+    kClassVerified = 5,  // logically part of linking; done pre-init
+    kClassInitializing = 6,  // class init in progress
+    kClassInitialized = 7,  // ready to go
+  };
+
+  enum PrimitiveType {
+    kPrimNot = -1
+  };
+
+  // Returns the size in bytes of a class object instance with the
+  // given number of static fields.
+  static size_t Size(size_t num_sfields) {
+    return OFFSETOF_MEMBER(Class, sfields_) + sizeof(SField) * num_sfields;
+  }
+
+ public: // TODO: private
+  // leave space for instance data; we could access fields directly if
+  // we freeze the definition of java/lang/Class
+#define CLASS_FIELD_SLOTS   4
+  uint32_t instance_data_[CLASS_FIELD_SLOTS];
+#undef CLASS_FIELD_SLOTS
+
+  // UTF-8 descriptor for the class from constant pool
+  // ("Ljava/lang/Class;"), or on heap if generated ("[C")
+  const char* descriptor_;
+
+  // Proxy classes have their descriptor allocated on the native heap.
+  // When this field is non-NULL it must be explicitly freed.
+  char* descriptor_alloc_;
+
+  // access flags; low 16 bits are defined by VM spec
+  uint32_t access_flags_;
+
+  // VM-unique class serial number, nonzero, set very early
+  //uint32_t serial_number_;
+
+  // DexFile from which we came; needed to resolve constant pool entries
+  // (will be NULL for VM-generated, e.g. arrays and primitive classes)
+  DexFile* dex_file_;
+
+  // state of class initialization
+  ClassStatus status_;
+
+  // if class verify fails, we must return same error on subsequent tries
+  Class* verify_error_class_;
+
+  // threadId, used to check for recursive <clinit> invocation
+  uint32_t clinit_thread_id_;
+
+  // Total object size; used when allocating storage on gc heap.  (For
+  // interfaces and abstract classes this will be zero.)
+  uint32_t object_size_;
+
+  // For array classes, the class object for base element, for
+  // instanceof/checkcast (for String[][][], this will be String).
+  // Otherwise, NULL.
+  Class* array_element_class_;
+
+  // For array classes, the number of array dimensions, e.g. int[][]
+  // is 2.  Otherwise 0.
+  int32_t array_rank_;
+
+  // primitive type index, or PRIM_NOT (-1); set for generated prim classes
+  PrimitiveType primitive_type_;
+
+  // The superclass, or NULL if this is java.lang.Object or a
+  // primitive type.
+  Class* super_;
+
+  // defining class loader, or NULL for the "bootstrap" system loader
+  Object* class_loader_;
+
+  // initiating class loader list
+  // NOTE: for classes with low serialNumber, these are unused, and the
+  // values are kept in a table in gDvm.
+  //InitiatingLoaderList initiating_loader_list_;
+
+  // array of interfaces this class implements directly
+  int interface_count_;
+  Class** interfaces_;
+
+  // static, private, and <init> methods
+  int direct_method_count_;
+  Method* direct_methods_;
+
+  // virtual methods defined in this class; invoked through vtable
+  int virtual_method_count_;
+  Method* virtual_methods_;
+
+  // Virtual method table (vtable), for use by "invoke-virtual".  The
+  // vtable from the superclass is copied in, and virtual methods from
+  // our class either replace those from the super or are appended.
+  int32_t vtable_count_;
+  Method** vtable_;
+
+  // Interface table (iftable), one entry per interface supported by
+  // this class.  That means one entry for each interface we support
+  // directly, indirectly via superclass, or indirectly via
+  // superinterface.  This will be null if neither we nor our
+  // superclass implement any interfaces.
+  //
+  // Why we need this: given "class Foo implements Face", declare
+  // "Face faceObj = new Foo()".  Invoke faceObj.blah(), where "blah"
+  // is part of the Face interface.  We can't easily use a single
+  // vtable.
+  //
+  // For every interface a concrete class implements, we create a list
+  // of virtualMethod indices for the methods in the interface.
+  int iftable_count_;
+  InterfaceEntry* iftable_;
+
+  // The interface vtable indices for iftable get stored here.  By
+  // placing them all in a single pool for each class that implements
+  // interfaces, we decrease the number of allocations.
+  int ifvipool_count;
+  int* ifvipool_;
+
+  // instance fields
+  //
+  // These describe the layout of the contents of a
+  // DataObject-compatible Object.  Note that only the fields directly
+  // declared by this class are listed in ifields; fields declared by
+  // a superclass are listed in the superclass's ClassObject.ifields.
+  //
+  // All instance fields that refer to objects are guaranteed to be at
+  // the beginning of the field list.  ifieldRefCount specifies the
+  // number of reference fields.
+  int ifield_count_;
+  int ifield_ref_count_; // number of fields that are object refs
+  IField* ifields_;
+
+  // bitmap of offsets of ifields
+  uint32_t ref_offsets_;
+
+  // source file name, if known.  Otherwise, NULL.
+  const char* source_file_;
+
+  // Static fields
+  uint16_t num_sfields_;
+  SField sfields_[];  // MUST be last item
+};
+
+class String : Object {
+ public:
+  Array* array_;
+
+  uint32_t hash_code_;
+
+  uint32_t offset_;
+
+  uint32_t count_;
+};
+
+class Array : Object {
+ public:
+  // The number of array elements.
+  uint32_t length_;
+};
+
+class Method {
+ public:
+  Class* klass;
+};
+
+}  // namespace art
+
+#endif  // ART_SRC_OBJECT_H_
diff --git a/src/raw_dex_file.cc b/src/raw_dex_file.cc
new file mode 100644
index 0000000..9f09177
--- /dev/null
+++ b/src/raw_dex_file.cc
@@ -0,0 +1,121 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+
+#include "src/raw_dex_file.h"
+#include "src/globals.h"
+#include "src/logging.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <map>
+
+namespace art {
+
+const byte RawDexFile::kDexMagic[] = { 'd', 'e', 'x', '\n' };
+const byte RawDexFile::kDexMagicVersion[] = { '0', '3', '5', '\0' };
+
+RawDexFile* RawDexFile::Open(const char* filename) {
+  CHECK(filename != NULL);
+  int fd = open(filename, O_RDONLY);
+  if (fd == -1) {
+    LG << "open: " << strerror(errno);  // TODO: PLOG
+    return NULL;
+  }
+  struct stat sbuf;
+  memset(&sbuf, 0, sizeof(sbuf));
+  if (fstat(fd, &sbuf) == -1) {
+    LG << "fstat: " << strerror(errno);  // TODO: PLOG
+    close(fd);
+    return NULL;
+  }
+  size_t length = sbuf.st_size;
+  void* addr = mmap(NULL, length, PROT_READ, MAP_SHARED, fd, 0);
+  if (addr == MAP_FAILED) {
+    LG << "mmap: " << strerror(errno);  // TODO: PLOG
+    close(fd);
+    return NULL;
+  }
+  close(fd);
+  RawDexFile* raw = new RawDexFile(reinterpret_cast<byte*>(addr), length);
+  raw->Init();
+  return raw;
+}
+
+RawDexFile::~RawDexFile() {
+  CHECK(base_ != NULL);
+  const void* addr = reinterpret_cast<const void*>(base_);
+  if (munmap(const_cast<void*>(addr), length_) == -1) {
+    LG << "munmap: " << strerror(errno);  // TODO: PLOG
+  }
+}
+
+bool RawDexFile::Init() {
+  InitMembers();
+  if (!IsMagicValid()) {
+    return false;
+  }
+  InitIndex();
+  return true;
+}
+
+void RawDexFile::InitMembers() {
+  const byte* b = base_;
+  header_ = reinterpret_cast<const Header*>(b);
+  const Header* h = header_;
+  string_ids_ = reinterpret_cast<const StringId*>(b + h->string_ids_off_);
+  type_ids_ = reinterpret_cast<const TypeId*>(b + h->type_ids_off_);
+  field_ids_ = reinterpret_cast<const FieldId*>(b + h->field_ids_off_);
+  method_ids_ = reinterpret_cast<const MethodId*>(b + h->method_ids_off_);
+  proto_ids_ = reinterpret_cast<const ProtoId*>(b + h->proto_ids_off_);
+  class_defs_ = reinterpret_cast<const ClassDef*>(b + h->class_defs_off_);
+}
+
+bool RawDexFile::IsMagicValid() {
+  return CheckMagic(header_->magic);
+}
+
+bool RawDexFile::CheckMagic(const byte* magic) {
+  CHECK(magic != NULL);
+  if (memcmp(magic, kDexMagic, sizeof(kDexMagic)) != 0) {
+    LOG(WARN) << "Unrecognized magic number:"
+              << " " << magic[0]
+              << " " << magic[1]
+              << " " << magic[2]
+              << " " << magic[3];
+    return false;
+  }
+  const byte* version = &magic[sizeof(kDexMagic)];
+  if (memcmp(version, kDexMagicVersion, sizeof(kDexMagicVersion)) != 0) {
+    LOG(WARN) << "Unrecognized version number:"
+              << " " << version[0]
+              << " " << version[1]
+              << " " << version[2]
+              << " " << version[3];
+    return false;
+  }
+  return true;
+}
+
+void RawDexFile::InitIndex() {
+  CHECK_EQ(index_.size(), 0);
+  for (size_t i = 0; i < NumClassDefs(); ++i) {
+    const ClassDef& class_def = GetClassDef(i);
+    const char* descriptor = GetClassDescriptor(class_def);
+    index_[descriptor] = &class_def;
+  }
+}
+
+const RawDexFile::ClassDef* RawDexFile::FindClassDef(const char* descriptor) {
+  CHECK(descriptor != NULL);
+  Index::iterator it = index_.find(descriptor);
+  if (it == index_.end()) {
+    return NULL;
+  } else {
+    return it->second;
+  }
+}
+
+}  // namespace art
diff --git a/src/raw_dex_file.h b/src/raw_dex_file.h
new file mode 100644
index 0000000..3cd7c88
--- /dev/null
+++ b/src/raw_dex_file.h
@@ -0,0 +1,345 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+
+#ifndef ART_SRC_RAW_DEX_FILE_H_
+#define ART_SRC_RAW_DEX_FILE_H_
+
+#include "src/globals.h"
+#include "src/leb128.h"
+#include "src/logging.h"
+#include "src/strutil.h"
+
+#include <map>
+
+namespace art {
+
+class RawDexFile {
+ public:
+  static const byte kDexMagic[];
+  static const byte kDexMagicVersion[];
+  static const size_t kSha1DigestSize = 20;
+
+  // Raw header_item.
+  struct Header {
+    uint8_t magic[8];
+    uint32_t checksum;
+    uint8_t signature[kSha1DigestSize];
+    uint32_t file_size_;  // length of entire file
+    uint32_t header_size_;  // offset to start of next section
+    uint32_t endian_tag_;
+    uint32_t link_size_;
+    uint32_t link_off_;
+    uint32_t map_off_;
+    uint32_t string_ids_size_;
+    uint32_t string_ids_off_;
+    uint32_t type_ids_size_;
+    uint32_t type_ids_off_;
+    uint32_t proto_ids_size_;
+    uint32_t proto_ids_off_;
+    uint32_t field_ids_size_;
+    uint32_t field_ids_off_;
+    uint32_t method_ids_size_;
+    uint32_t method_ids_off_;
+    uint32_t class_defs_size_;
+    uint32_t class_defs_off_;
+    uint32_t data_size_;
+    uint32_t data_off_;
+  };
+
+  // Raw string_id_item.
+  struct StringId {
+    uint32_t string_data_off_;  // offset in bytes from the base address
+  };
+
+  // Raw type_id_item.
+  struct TypeId {
+    uint32_t descriptor_idx_;  // index into string_ids
+  };
+
+  // Raw field_id_item.
+  struct FieldId {
+    uint32_t class_idx_;  // index into typeIds list for defining class
+    uint32_t type_idx_;  // index into typeIds for field type
+    uint32_t name_idx_;  // index into stringIds for field name
+  };
+
+  // Raw method_id_item.
+  struct MethodId {
+    uint32_t class_idx_;  // index into typeIds list for defining class
+    uint32_t proto_idx_;  // index into protoIds for method prototype
+    uint32_t name_idx_;  // index into stringIds for method name
+  };
+
+  // Raw proto_id_item.
+  struct ProtoId {
+    uint32_t shorty_idx_;  // index into string_ids for shorty descriptor
+    uint32_t return_type_idx_;  // index into type_ids list for return type
+    uint32_t parameters_off_;  // file offset to type_list for parameter types
+  };
+
+  // Raw class_def_item.
+  struct ClassDef {
+    uint32_t class_idx_;  // index into typeIds for this class
+    uint32_t access_flags_;
+    uint32_t superclass_idx_;  // index into typeIds for superclass
+    uint32_t interfaces_off_;  // file offset to TypeList
+    uint32_t source_file_idx_;  // index into stringIds for source file name
+    uint32_t annotations_off_;  // file offset to annotations_directory_item
+    uint32_t class_data_off_;  // file offset to class_data_item
+    uint32_t static_values_off_;  // file offset to EncodedArray
+  };
+
+  // Raw type_item.
+  struct TypeItem {
+    uint16_t type_idx_;  // index into type_ids section
+  };
+
+  // Raw type_list.
+  class TypeList {
+   public:
+    uint32_t Size() const {
+      return size_;
+    }
+
+    const TypeItem& GetTypeItem(uint32_t idx) const {
+      CHECK_LT(idx, this->size_);
+      return this->list_[idx];
+    }
+
+   private:
+    uint32_t size_;  // size of the list, in entries
+    TypeItem list_[1];  // elements of the list
+  };
+
+  // Raw code_item.
+  struct Code {
+    uint16_t registers_size_;
+    uint16_t ins_size_;
+    uint16_t outs_size_;
+    uint16_t tries_size_;
+    uint32_t debug_info_off_;  // file offset to debug info stream
+    uint32_t insns_size_;  // size of the insns array, in 2 byte code units
+    uint16_t insns_[1];
+  };
+
+  // Partially decoded form of class_data_item.
+  struct ClassDataHeader {
+    uint32_t static_fields_size_;  // the number of static fields
+    uint32_t instance_fields_size_;  // the number of instance fields
+    uint32_t direct_methods_size_;  // the number of direct methods
+    uint32_t virtual_methods_size_;  // the number of virtual methods
+  };
+
+  // Decoded form of encoded_field.
+  struct Field {
+    uint32_t field_idx_;  // index into the field_ids list for the identity of this field
+    uint32_t access_flags_;  // access flags for the field
+  };
+
+  // Decoded form of encoded_method.
+  struct Method {
+    uint32_t method_idx_;
+    uint32_t access_flags_;
+    uint32_t code_off_;
+  };
+
+  // Opens a .dex file.
+  static RawDexFile* Open(const char* filename);
+
+  // Closes a .dex file.
+  ~RawDexFile();
+
+  // Looks up a class definition by its class descriptor.
+  const ClassDef* FindClassDef(const char* descriptor);
+
+  // Returns the number of string identifiers in the .dex file.
+  size_t NumStringIds() const {
+    CHECK(header_ != NULL);
+    return header_->string_ids_size_;
+  }
+
+  // Returns the number of type identifiers in the .dex file.
+  size_t NumTypeIds() const {
+    CHECK(header_ != NULL);
+    return header_->type_ids_size_;
+  }
+
+  // Returns the number of prototype identifiers in the .dex file.
+  size_t NumProtoIds() const {
+    CHECK(header_ != NULL);
+    return header_->proto_ids_size_;
+  }
+
+  // Returns the number of field identifiers in the .dex file.
+  size_t NumFieldIds() const {
+    CHECK(header_ != NULL);
+    return header_->field_ids_size_;
+  }
+
+  // Returns the number of method identifiers in the .dex file.
+  size_t NumMethodIds() const {
+    CHECK(header_ != NULL);
+    return header_->method_ids_size_;
+  }
+
+  // Returns the number of class definitions in the .dex file.
+  size_t NumClassDefs() const {
+    CHECK(header_ != NULL);
+    return header_->class_defs_size_;
+  }
+
+  // Returns a pointer to the memory mapped class data.
+  const byte* GetClassData(const ClassDef& class_def) const {
+    if (class_def.class_data_off_ == 0) {
+      LG << "class_def.class_data_off_ == 0";
+      return NULL;
+    }
+    return base_ + class_def.class_data_off_;
+  }
+
+  // Decodes the header section from the raw class data bytes.
+  void DecodeClassDataHeader(ClassDataHeader* header, const byte* class_data) {
+    CHECK(header != NULL);
+    memset(header, 0, sizeof(ClassDataHeader));
+    if (header != NULL) {
+      header->static_fields_size_ = DecodeUnsignedLeb128(&class_data);
+      header->instance_fields_size_ = DecodeUnsignedLeb128(&class_data);
+      header->direct_methods_size_ = DecodeUnsignedLeb128(&class_data);
+      header->virtual_methods_size_ = DecodeUnsignedLeb128(&class_data);
+    }
+  }
+
+  // Returns the class descriptor string of a class definition.
+  const char* GetClassDescriptor(const ClassDef& class_def) const {
+    return dexStringByTypeIdx(class_def.class_idx_);
+  }
+
+  // Returns the StringId at the specified index.
+  const StringId& GetStringId(uint32_t idx) const {
+    CHECK_LT(idx, NumStringIds());
+    return string_ids_[idx];
+  }
+
+  // Returns the TypeId at the specified index.
+  const TypeId& GetTypeId(uint32_t idx) const {
+    CHECK_LT(idx, NumTypeIds());
+    return type_ids_[idx];
+  }
+
+  // Returns the FieldId at the specified index.
+  const FieldId& GetFieldId(uint32_t idx) const {
+    CHECK_LT(idx, NumFieldIds());
+    return field_ids_[idx];
+  }
+
+  // Returns the MethodId at the specified index.
+  const MethodId& GetMethodId(uint32_t idx) const {
+    CHECK_LT(idx, NumMethodIds());
+    return method_ids_[idx];
+  }
+
+  // Returns the ProtoId at the specified index.
+  const ProtoId& GetProtoId(uint32_t idx) const {
+    CHECK_LT(idx, NumProtoIds());
+    return proto_ids_[idx];
+  }
+
+  // Returns the ClassDef at the specified index.
+  const ClassDef& GetClassDef(uint32_t idx) const {
+    CHECK_LT(idx, NumClassDefs());
+    return class_defs_[idx];
+  }
+
+  const TypeList* GetInterfacesList(const ClassDef& class_def) {
+    if (class_def.interfaces_off_ == 0) {
+        return NULL;
+    } else {
+      const byte* addr = base_ + class_def.interfaces_off_;
+      return reinterpret_cast<const TypeList*>(addr);
+    }
+  }
+
+  // From libdex...
+
+  // Returns a pointer to the UTF-8 string data referred to by the
+  // given string_id.
+  const char* dexGetStringData(const StringId& string_id) const {
+    const byte* ptr = base_ + string_id.string_data_off_;
+    // Skip the uleb128 length.
+    while (*(ptr++) > 0x7f) /* empty */ ;
+    return (const char*) ptr;
+  }
+
+  // return the UTF-8 encoded string with the specified string_id index
+  const char* dexStringById(uint32_t idx) const {
+    const StringId& string_id = GetStringId(idx);
+    return dexGetStringData(string_id);
+  }
+
+  // Get the descriptor string associated with a given type index.
+  const char* dexStringByTypeIdx(uint32_t idx) const {
+    const TypeId& type_id = GetTypeId(idx);
+    return dexStringById(type_id.descriptor_idx_);
+  }
+
+ private:
+  RawDexFile(const byte* addr, size_t length)
+      : base_(addr),
+        length_(length),
+        header_(0),
+        string_ids_(0),
+        type_ids_(0),
+        field_ids_(0),
+        method_ids_(0),
+        proto_ids_(0),
+        class_defs_(0) {}
+
+  // Top-level initializer that calls other Init methods.
+  bool Init();
+
+  // Caches pointers into to the various file sections.
+  void InitMembers();
+
+  // Builds the index of descriptors to class definitions.
+  void InitIndex();
+
+  // Returns true if the byte string equals the magic value.
+  bool CheckMagic(const byte* magic);
+
+  // Returns true if the header magic is of the expected value.
+  bool IsMagicValid();
+
+  // The index of descriptors to class definitions.
+  typedef std::map<const char*, const RawDexFile::ClassDef*, CStringLt> Index;
+  Index index_;
+
+  // The base address of the memory mapping.
+  const byte* base_;
+
+  // The length of the memory mapping in bytes.
+  const size_t length_;
+
+  // Points to the header section.
+  const Header* header_;
+
+  // Points to the base of the string identifier list.
+  const StringId* string_ids_;
+
+  // Points to the base of the type identifier list.
+  const TypeId* type_ids_;
+
+  // Points to the base of the field identifier list.
+  const FieldId* field_ids_;
+
+  // Points to the base of the method identifier list.
+  const MethodId* method_ids_;
+
+  // Points to the base of the prototype identifier list.
+  const ProtoId* proto_ids_;
+
+  // Points to the base of the class definition list.
+  const ClassDef* class_defs_;
+};
+
+}  // namespace art
+
+#endif  // ART_SRC_RAW_DEX_FILE_H_
diff --git a/src/raw_dex_file_test.cc b/src/raw_dex_file_test.cc
new file mode 100644
index 0000000..6347c44
--- /dev/null
+++ b/src/raw_dex_file_test.cc
@@ -0,0 +1,33 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+
+#include "src/raw_dex_file.h"
+
+#include <stdio.h>
+#include "gtest/gtest.h"
+
+namespace art {
+
+static const char* filename =
+    "/usr/local/google/work/dalvik-dev-git/Nested.dex";
+
+TEST(RawDexFile, Open) {
+  RawDexFile* raw = RawDexFile::Open(filename);
+  ASSERT_TRUE(raw != NULL);
+  delete raw;
+}
+
+TEST(RawDexFile, ClassDefs) {
+  RawDexFile* raw = RawDexFile::Open(filename);
+  ASSERT_TRUE(raw != NULL);
+  EXPECT_EQ(2U, raw->NumClassDefs());
+
+  const RawDexFile::ClassDef& c0 = raw->GetClassDef(0);
+  EXPECT_STREQ("LNested$Inner;", raw->GetClassDescriptor(c0));
+
+  const RawDexFile::ClassDef& c1 = raw->GetClassDef(1);
+  EXPECT_STREQ("LNested;", raw->GetClassDescriptor(c1));
+
+  delete raw;
+}
+
+}  // namespace art
diff --git a/src/runtime.cc b/src/runtime.cc
new file mode 100644
index 0000000..f627a46
--- /dev/null
+++ b/src/runtime.cc
@@ -0,0 +1,14 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+
+#include "src/runtime.h"
+
+namespace art {
+
+bool Runtime::Startup() {
+  return true;
+}
+
+void Runtime::Shutdown() {
+}
+
+}  // namespace art
diff --git a/src/runtime.h b/src/runtime.h
new file mode 100644
index 0000000..2afd9f0
--- /dev/null
+++ b/src/runtime.h
@@ -0,0 +1,20 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+
+#ifndef ART_SRC_RUNTIME_H_
+#define ART_SRC_RUNTIME_H_
+
+namespace art {
+
+class Runtime {
+ public:
+  static bool Startup();
+  static void Shutdown();
+
+  static void Compile(const char* filename);
+};
+
+}  // namespace art
+
+namespace r = art;
+
+#endif  // ART_SRC_RUNTIME_H_
diff --git a/src/scoped_ptr.h b/src/scoped_ptr.h
new file mode 100644
index 0000000..19c8166
--- /dev/null
+++ b/src/scoped_ptr.h
@@ -0,0 +1,378 @@
+// Copyright 2010 Google
+// 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.
+
+#ifndef ART_SRC_SCOPED_PTR_H_
+#define ART_SRC_SCOPED_PTR_H_
+
+//  This is an implementation designed to match the anticipated future TR2
+//  implementation of the scoped_ptr class, and its closely-related brethren,
+//  scoped_array, scoped_ptr_malloc, and make_scoped_ptr.
+
+#include <assert.h>
+#include <stdlib.h>
+
+#include <algorithm>
+#include <cstddef>
+
+namespace art {
+
+template <class C> class scoped_ptr;
+template <class C, class Free> class scoped_ptr_malloc;
+template <class C> class scoped_array;
+
+template <class C>
+scoped_ptr<C> make_scoped_ptr(C * param);
+
+// A scoped_ptr<T> is like a T*, except that the destructor of scoped_ptr<T>
+// automatically deletes the pointer it holds (if any).
+// That is, scoped_ptr<T> owns the T object that it points to.
+// Like a T*, a scoped_ptr<T> may hold either NULL or a pointer to a T object.
+//
+// The size of a scoped_ptr is small:
+// sizeof(scoped_ptr<C>) == sizeof(C*)
+template <class C>
+class scoped_ptr {
+ public:
+
+  // The element type
+  typedef C element_type;
+
+  // Constructor.  Defaults to intializing with NULL.
+  // There is no way to create an uninitialized scoped_ptr.
+  // The input parameter must be allocated with new.
+  explicit scoped_ptr(C* p = NULL) : ptr_(p) { }
+
+  // Destructor.  If there is a C object, delete it.
+  // We don't need to test ptr_ == NULL because C++ does that for us.
+  ~scoped_ptr() {
+    enum { type_must_be_complete = sizeof(C) };
+    delete ptr_;
+  }
+
+  // Reset.  Deletes the current owned object, if any.
+  // Then takes ownership of a new object, if given.
+  // this->reset(this->get()) works.
+  void reset(C* p = NULL) {
+    if (p != ptr_) {
+      enum { type_must_be_complete = sizeof(C) };
+      delete ptr_;
+      ptr_ = p;
+    }
+  }
+
+  // Accessors to get the owned object.
+  // operator* and operator-> will assert() if there is no current object.
+  C& operator*() const {
+    assert(ptr_ != NULL);
+    return *ptr_;
+  }
+  C* operator->() const  {
+    assert(ptr_ != NULL);
+    return ptr_;
+  }
+  C* get() const { return ptr_; }
+
+  // Comparison operators.
+  // These return whether two scoped_ptr refer to the same object, not just to
+  // two different but equal objects.
+  bool operator==(C* p) const { return ptr_ == p; }
+  bool operator!=(C* p) const { return ptr_ != p; }
+
+  // Swap two scoped pointers.
+  void swap(scoped_ptr& p2) {
+    C* tmp = ptr_;
+    ptr_ = p2.ptr_;
+    p2.ptr_ = tmp;
+  }
+
+  // Release a pointer.
+  // The return value is the current pointer held by this object.
+  // If this object holds a NULL pointer, the return value is NULL.
+  // After this operation, this object will hold a NULL pointer,
+  // and will not own the object any more.
+  C* release() {
+    C* retVal = ptr_;
+    ptr_ = NULL;
+    return retVal;
+  }
+
+ private:
+  C* ptr_;
+
+  // friend class that can access copy ctor (although if it actually
+  // calls a copy ctor, there will be a problem) see below
+  friend scoped_ptr<C> make_scoped_ptr<C>(C *p);
+
+  // Forbid comparison of scoped_ptr types.  If C2 != C, it totally doesn't
+  // make sense, and if C2 == C, it still doesn't make sense because you should
+  // never have the same object owned by two different scoped_ptrs.
+  template <class C2> bool operator==(scoped_ptr<C2> const& p2) const;
+  template <class C2> bool operator!=(scoped_ptr<C2> const& p2) const;
+
+  DISALLOW_COPY_AND_ASSIGN(scoped_ptr);
+};
+
+// Free functions
+template <class C>
+void swap(scoped_ptr<C>& p1, scoped_ptr<C>& p2) {
+  p1.swap(p2);
+}
+
+template <class C>
+bool operator==(C* p1, const scoped_ptr<C>& p2) {
+  return p1 == p2.get();
+}
+
+template <class C>
+bool operator!=(C* p1, const scoped_ptr<C>& p2) {
+  return p1 != p2.get();
+}
+
+template <class C>
+scoped_ptr<C> make_scoped_ptr(C *p) {
+  // This does nothing but to return a scoped_ptr of the type that the passed
+  // pointer is of.  (This eliminates the need to specify the name of T when
+  // making a scoped_ptr that is used anonymously/temporarily.)  From an
+  // access control point of view, we construct an unnamed scoped_ptr here
+  // which we return and thus copy-construct.  Hence, we need to have access
+  // to scoped_ptr::scoped_ptr(scoped_ptr const &).  However, it is guaranteed
+  // that we never actually call the copy constructor, which is a good thing
+  // as we would call the temporary's object destructor (and thus delete p)
+  // if we actually did copy some object, here.
+  return scoped_ptr<C>(p);
+}
+
+// scoped_array<C> is like scoped_ptr<C>, except that the caller must allocate
+// with new [] and the destructor deletes objects with delete [].
+//
+// As with scoped_ptr<C>, a scoped_array<C> either points to an object
+// or is NULL.  A scoped_array<C> owns the object that it points to.
+//
+// Size: sizeof(scoped_array<C>) == sizeof(C*)
+template <class C>
+class scoped_array {
+ public:
+
+  // The element type
+  typedef C element_type;
+
+  // Constructor.  Defaults to intializing with NULL.
+  // There is no way to create an uninitialized scoped_array.
+  // The input parameter must be allocated with new [].
+  explicit scoped_array(C* p = NULL) : array_(p) { }
+
+  // Destructor.  If there is a C object, delete it.
+  // We don't need to test ptr_ == NULL because C++ does that for us.
+  ~scoped_array() {
+    enum { type_must_be_complete = sizeof(C) };
+    delete[] array_;
+  }
+
+  // Reset.  Deletes the current owned object, if any.
+  // Then takes ownership of a new object, if given.
+  // this->reset(this->get()) works.
+  void reset(C* p = NULL) {
+    if (p != array_) {
+      enum { type_must_be_complete = sizeof(C) };
+      delete[] array_;
+      array_ = p;
+    }
+  }
+
+  // Get one element of the current object.
+  // Will assert() if there is no current object, or index i is negative.
+  C& operator[](std::ptrdiff_t i) const {
+    assert(i >= 0);
+    assert(array_ != NULL);
+    return array_[i];
+  }
+
+  // Get a pointer to the zeroth element of the current object.
+  // If there is no current object, return NULL.
+  C* get() const {
+    return array_;
+  }
+
+  // Comparison operators.
+  // These return whether two scoped_array refer to the same object, not just to
+  // two different but equal objects.
+  bool operator==(C* p) const { return array_ == p; }
+  bool operator!=(C* p) const { return array_ != p; }
+
+  // Swap two scoped arrays.
+  void swap(scoped_array& p2) {
+    C* tmp = array_;
+    array_ = p2.array_;
+    p2.array_ = tmp;
+  }
+
+  // Release an array.
+  // The return value is the current pointer held by this object.
+  // If this object holds a NULL pointer, the return value is NULL.
+  // After this operation, this object will hold a NULL pointer,
+  // and will not own the object any more.
+  C* release() {
+    C* retVal = array_;
+    array_ = NULL;
+    return retVal;
+  }
+
+ private:
+  C* array_;
+
+  // Forbid comparison of different scoped_array types.
+  template <class C2> bool operator==(scoped_array<C2> const& p2) const;
+  template <class C2> bool operator!=(scoped_array<C2> const& p2) const;
+
+  DISALLOW_COPY_AND_ASSIGN(scoped_array);
+};
+
+// Free functions
+template <class C>
+void swap(scoped_array<C>& p1, scoped_array<C>& p2) {
+  p1.swap(p2);
+}
+
+template <class C>
+bool operator==(C* p1, const scoped_array<C>& p2) {
+  return p1 == p2.get();
+}
+
+template <class C>
+bool operator!=(C* p1, const scoped_array<C>& p2) {
+  return p1 != p2.get();
+}
+
+// This class wraps the c library function free() in a class that can be
+// passed as a template argument to scoped_ptr_malloc below.
+class ScopedPtrMallocFree {
+ public:
+  inline void operator()(void* x) const {
+    free(x);
+  }
+};
+
+// scoped_ptr_malloc<> is similar to scoped_ptr<>, but it accepts a
+// second template argument, the functor used to free the object.
+
+template<class C, class FreeProc = ScopedPtrMallocFree>
+class scoped_ptr_malloc {
+ public:
+
+  // The element type
+  typedef C element_type;
+
+  // Constructor.  Defaults to intializing with NULL.
+  // There is no way to create an uninitialized scoped_ptr.
+  // The input parameter must be allocated with an allocator that matches the
+  // Free functor.  For the default Free functor, this is malloc, calloc, or
+  // realloc.
+  explicit scoped_ptr_malloc(C* p = NULL): ptr_(p) {}
+
+  // Destructor.  If there is a C object, call the Free functor.
+  ~scoped_ptr_malloc() {
+    free_(ptr_);
+  }
+
+  // Reset.  Calls the Free functor on the current owned object, if any.
+  // Then takes ownership of a new object, if given.
+  // this->reset(this->get()) works.
+  void reset(C* p = NULL) {
+    if (ptr_ != p) {
+      free_(ptr_);
+      ptr_ = p;
+    }
+  }
+
+  // Get the current object.
+  // operator* and operator-> will cause an assert() failure if there is
+  // no current object.
+  C& operator*() const {
+    assert(ptr_ != NULL);
+    return *ptr_;
+  }
+
+  C* operator->() const {
+    assert(ptr_ != NULL);
+    return ptr_;
+  }
+
+  C* get() const {
+    return ptr_;
+  }
+
+  // Comparison operators.
+  // These return whether a scoped_ptr_malloc and a plain pointer refer
+  // to the same object, not just to two different but equal objects.
+  // For compatibility wwith the boost-derived implementation, these
+  // take non-const arguments.
+  bool operator==(C* p) const {
+    return ptr_ == p;
+  }
+
+  bool operator!=(C* p) const {
+    return ptr_ != p;
+  }
+
+  // Swap two scoped pointers.
+  void swap(scoped_ptr_malloc & b) {
+    C* tmp = b.ptr_;
+    b.ptr_ = ptr_;
+    ptr_ = tmp;
+  }
+
+  // Release a pointer.
+  // The return value is the current pointer held by this object.
+  // If this object holds a NULL pointer, the return value is NULL.
+  // After this operation, this object will hold a NULL pointer,
+  // and will not own the object any more.
+  C* release() {
+    C* tmp = ptr_;
+    ptr_ = NULL;
+    return tmp;
+  }
+
+ private:
+  C* ptr_;
+
+  // no reason to use these: each scoped_ptr_malloc should have its own object
+  template <class C2, class GP>
+  bool operator==(scoped_ptr_malloc<C2, GP> const& p) const;
+  template <class C2, class GP>
+  bool operator!=(scoped_ptr_malloc<C2, GP> const& p) const;
+
+  static FreeProc const free_;
+
+  DISALLOW_COPY_AND_ASSIGN(scoped_ptr_malloc);
+};
+
+template<class C, class FP>
+FP const scoped_ptr_malloc<C, FP>::free_ = FP();
+
+template<class C, class FP> inline
+void swap(scoped_ptr_malloc<C, FP>& a, scoped_ptr_malloc<C, FP>& b) {
+  a.swap(b);
+}
+
+template<class C, class FP> inline
+bool operator==(C* p, const scoped_ptr_malloc<C, FP>& b) {
+  return p == b.get();
+}
+
+template<class C, class FP> inline
+bool operator!=(C* p, const scoped_ptr_malloc<C, FP>& b) {
+  return p != b.get();
+}
+}  // namespace art
+
+#endif  // ART_SRC_SCOPED_PTR_H_
diff --git a/src/strutil.h b/src/strutil.h
new file mode 100644
index 0000000..c9c6caa
--- /dev/null
+++ b/src/strutil.h
@@ -0,0 +1,26 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+
+#ifndef ART_SRC_STRUTIL_H_
+#define ART_SRC_STRUTIL_H_
+
+#include <string.h>
+
+namespace art {
+
+// Key comparison function for C strings.
+struct CStringLt {
+  bool operator()(const char* s1, const char* s2) const {
+    return strcmp(s1, s2) < 0;
+  }
+};
+
+// Key equality function for C strings.
+struct CStringEq {
+  bool operator()(const char* s1, const char* s2) const {
+    return strcmp(s1, s2) == 0;
+  }
+};
+
+}  // namespace art
+
+#endif  // ART_SRC_STRUTIL_H_
diff --git a/src/utils.h b/src/utils.h
index a8bf3e7..bf8896d 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -60,6 +60,18 @@
 }
 
 // Implementation is from "Hacker's Delight" by Henry S. Warren, Jr.,
+// figure 3-3, page 48, where the function is called clp2.
+static inline uint32_t RoundUpToPowerOfTwo(uint32_t x) {
+  x = x - 1;
+  x = x | (x >> 1);
+  x = x | (x >> 2);
+  x = x | (x >> 4);
+  x = x | (x >> 8);
+  x = x | (x >> 16);
+  return x + 1;
+}
+
+// Implementation is from "Hacker's Delight" by Henry S. Warren, Jr.,
 // figure 5-2, page 66, where the function is called pop.
 static inline int CountOneBits(uint32_t x) {
   x = x - ((x >> 1) & 0x55555555);