diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index 131be37..a3e7efa 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -47,7 +47,6 @@
 #include "driver/compiler_options.h"
 #include "jni_internal.h"
 #include "object_lock.h"
-#include "profiler.h"
 #include "runtime.h"
 #include "gc/accounting/card_table-inl.h"
 #include "gc/accounting/heap_bitmap.h"
diff --git a/runtime/Android.mk b/runtime/Android.mk
index aa12c83..bf4e8f1 100644
--- a/runtime/Android.mk
+++ b/runtime/Android.mk
@@ -169,7 +169,6 @@
   os_linux.cc \
   parsed_options.cc \
   primitive.cc \
-  profiler.cc \
   quick_exception_handler.cc \
   quick/inline_method_analyser.cc \
   reference_table.cc \
diff --git a/runtime/native/dalvik_system_DexFile.cc b/runtime/native/dalvik_system_DexFile.cc
index 8c7c966..46be5e6 100644
--- a/runtime/native/dalvik_system_DexFile.cc
+++ b/runtime/native/dalvik_system_DexFile.cc
@@ -33,7 +33,6 @@
 #include "oat_file_assistant.h"
 #include "oat_file_manager.h"
 #include "os.h"
-#include "profiler.h"
 #include "runtime.h"
 #include "scoped_thread_state_change.h"
 #include "ScopedLocalRef.h"
diff --git a/runtime/oat_file_assistant.h b/runtime/oat_file_assistant.h
index bb7b408..d55e373 100644
--- a/runtime/oat_file_assistant.h
+++ b/runtime/oat_file_assistant.h
@@ -28,7 +28,6 @@
 #include "compiler_filter.h"
 #include "oat_file.h"
 #include "os.h"
-#include "profiler.h"
 
 namespace art {
 
diff --git a/runtime/profiler.cc b/runtime/profiler.cc
deleted file mode 100644
index 6a77a9e..0000000
--- a/runtime/profiler.cc
+++ /dev/null
@@ -1,920 +0,0 @@
-/*
- * Copyright (C) 2011 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 "profiler.h"
-
-#include <sys/file.h>
-#include <sys/stat.h>
-#include <sys/uio.h>
-
-#include <fstream>
-
-#include "art_method-inl.h"
-#include "base/stl_util.h"
-#include "base/time_utils.h"
-#include "base/unix_file/fd_file.h"
-#include "class_linker.h"
-#include "common_throws.h"
-#include "dex_file-inl.h"
-#include "instrumentation.h"
-#include "mirror/class-inl.h"
-#include "mirror/dex_cache.h"
-#include "mirror/object_array-inl.h"
-#include "mirror/object-inl.h"
-#include "os.h"
-#include "scoped_thread_state_change.h"
-#include "ScopedLocalRef.h"
-#include "thread.h"
-#include "thread_list.h"
-#include "utils.h"
-
-#include "entrypoints/quick/quick_entrypoints.h"
-
-namespace art {
-
-BackgroundMethodSamplingProfiler* BackgroundMethodSamplingProfiler::profiler_ = nullptr;
-pthread_t BackgroundMethodSamplingProfiler::profiler_pthread_ = 0U;
-volatile bool BackgroundMethodSamplingProfiler::shutting_down_ = false;
-
-// TODO: this profiler runs regardless of the state of the machine.  Maybe we should use the
-// wakelock or something to modify the run characteristics.  This can be done when we
-// have some performance data after it's been used for a while.
-
-// Walk through the method within depth of max_depth_ on the Java stack
-class BoundedStackVisitor : public StackVisitor {
- public:
-  BoundedStackVisitor(std::vector<std::pair<ArtMethod*, uint32_t>>* stack,
-                      Thread* thread,
-                      uint32_t max_depth)
-      SHARED_REQUIRES(Locks::mutator_lock_)
-      : StackVisitor(thread, nullptr, StackVisitor::StackWalkKind::kIncludeInlinedFrames),
-        stack_(stack),
-        max_depth_(max_depth),
-        depth_(0) {}
-
-  bool VisitFrame() SHARED_REQUIRES(Locks::mutator_lock_) {
-    ArtMethod* m = GetMethod();
-    if (m->IsRuntimeMethod()) {
-      return true;
-    }
-    uint32_t dex_pc_ = GetDexPc();
-    stack_->push_back(std::make_pair(m, dex_pc_));
-    ++depth_;
-    if (depth_ < max_depth_) {
-      return true;
-    } else {
-      return false;
-    }
-  }
-
- private:
-  std::vector<std::pair<ArtMethod*, uint32_t>>* const stack_;
-  const uint32_t max_depth_;
-  uint32_t depth_;
-
-  DISALLOW_COPY_AND_ASSIGN(BoundedStackVisitor);
-};
-
-// This is called from either a thread list traversal or from a checkpoint.  Regardless
-// of which caller, the mutator lock must be held.
-static void GetSample(Thread* thread, void* arg) SHARED_REQUIRES(Locks::mutator_lock_) {
-  BackgroundMethodSamplingProfiler* profiler =
-      reinterpret_cast<BackgroundMethodSamplingProfiler*>(arg);
-  const ProfilerOptions profile_options = profiler->GetProfilerOptions();
-  switch (profile_options.GetProfileType()) {
-    case kProfilerMethod: {
-      ArtMethod* method = thread->GetCurrentMethod(nullptr);
-      if ((false) && method == nullptr) {
-        LOG(INFO) << "No current method available";
-        std::ostringstream os;
-        thread->Dump(os);
-        std::string data(os.str());
-        LOG(INFO) << data;
-      }
-      profiler->RecordMethod(method);
-      break;
-    }
-    case kProfilerBoundedStack: {
-      std::vector<InstructionLocation> stack;
-      uint32_t max_depth = profile_options.GetMaxStackDepth();
-      BoundedStackVisitor bounded_stack_visitor(&stack, thread, max_depth);
-      bounded_stack_visitor.WalkStack();
-      profiler->RecordStack(stack);
-      break;
-    }
-    default:
-      LOG(INFO) << "This profile type is not implemented.";
-  }
-}
-
-// A closure that is called by the thread checkpoint code.
-class SampleCheckpoint FINAL : public Closure {
- public:
-  explicit SampleCheckpoint(BackgroundMethodSamplingProfiler* const profiler) :
-    profiler_(profiler) {}
-
-  void Run(Thread* thread) OVERRIDE {
-    Thread* self = Thread::Current();
-    if (thread == nullptr) {
-      LOG(ERROR) << "Checkpoint with nullptr thread";
-      return;
-    }
-
-    // Grab the mutator lock (shared access).
-    ScopedObjectAccess soa(self);
-
-    // Grab a sample.
-    GetSample(thread, this->profiler_);
-
-    // And finally tell the barrier that we're done.
-    this->profiler_->GetBarrier().Pass(self);
-  }
-
- private:
-  BackgroundMethodSamplingProfiler* const profiler_;
-};
-
-bool BackgroundMethodSamplingProfiler::ShuttingDown(Thread* self) {
-  MutexLock mu(self, *Locks::profiler_lock_);
-  return shutting_down_;
-}
-
-void* BackgroundMethodSamplingProfiler::RunProfilerThread(void* arg) {
-  Runtime* runtime = Runtime::Current();
-  BackgroundMethodSamplingProfiler* profiler =
-      reinterpret_cast<BackgroundMethodSamplingProfiler*>(arg);
-
-  // Add a random delay for the first time run so that we don't hammer the CPU
-  // with all profiles running at the same time.
-  const int kRandomDelayMaxSecs = 30;
-  const double kMaxBackoffSecs = 24*60*60;   // Max backoff time.
-
-  srand(MicroTime() * getpid());
-  int startup_delay = rand() % kRandomDelayMaxSecs;   // random delay for startup.
-
-
-  CHECK(runtime->AttachCurrentThread("Profiler", true, runtime->GetSystemThreadGroup(),
-                                      !runtime->IsAotCompiler()));
-
-  Thread* self = Thread::Current();
-
-  double backoff = 1.0;
-  while (true) {
-    if (ShuttingDown(self)) {
-      break;
-    }
-
-    {
-      // wait until we need to run another profile
-      uint64_t delay_secs = profiler->options_.GetPeriodS() * backoff;
-
-      // Add a startup delay to prevent all the profiles running at once.
-      delay_secs += startup_delay;
-
-      // Immediate startup for benchmarking?
-      if (profiler->options_.GetStartImmediately() && startup_delay > 0) {
-        delay_secs = 0;
-      }
-
-      startup_delay = 0;
-
-      VLOG(profiler) << "Delaying profile start for " << delay_secs << " secs";
-      MutexLock mu(self, profiler->wait_lock_);
-      profiler->period_condition_.TimedWait(self, delay_secs * 1000, 0);
-      // We were either signaled by Stop or timedout, in either case ignore the timed out result.
-
-      // Expand the backoff by its coefficient, but don't go beyond the max.
-      backoff = std::min(backoff * profiler->options_.GetBackoffCoefficient(), kMaxBackoffSecs);
-    }
-
-    if (ShuttingDown(self)) {
-      break;
-    }
-
-
-    uint64_t start_us = MicroTime();
-    uint64_t end_us = start_us + profiler->options_.GetDurationS() * UINT64_C(1000000);
-    uint64_t now_us = start_us;
-
-    VLOG(profiler) << "Starting profiling run now for "
-                   << PrettyDuration((end_us - start_us) * 1000);
-
-    SampleCheckpoint check_point(profiler);
-
-    size_t valid_samples = 0;
-    while (now_us < end_us) {
-      if (ShuttingDown(self)) {
-        break;
-      }
-
-      usleep(profiler->options_.GetIntervalUs());    // Non-interruptible sleep.
-
-      ThreadList* thread_list = runtime->GetThreadList();
-
-      profiler->profiler_barrier_->Init(self, 0);
-      size_t barrier_count = thread_list->RunCheckpointOnRunnableThreads(&check_point);
-
-      // All threads are suspended, nothing to do.
-      if (barrier_count == 0) {
-        now_us = MicroTime();
-        continue;
-      }
-
-      valid_samples += barrier_count;
-
-      ScopedThreadStateChange tsc(self, kWaitingForCheckPointsToRun);
-
-      // Wait for the barrier to be crossed by all runnable threads.  This wait
-      // is done with a timeout so that we can detect problems with the checkpoint
-      // running code.  We should never see this.
-      const uint32_t kWaitTimeoutMs = 10000;
-
-      // Wait for all threads to pass the barrier.
-      bool timed_out =  profiler->profiler_barrier_->Increment(self, barrier_count, kWaitTimeoutMs);
-
-      // We should never get a timeout.  If we do, it suggests a problem with the checkpoint
-      // code.  Crash the process in this case.
-      CHECK(!timed_out);
-
-      // Update the current time.
-      now_us = MicroTime();
-    }
-
-    if (valid_samples > 0) {
-      // After the profile has been taken, write it out.
-      ScopedObjectAccess soa(self);   // Acquire the mutator lock.
-      uint32_t size = profiler->WriteProfile();
-      VLOG(profiler) << "Profile size: " << size;
-    }
-  }
-
-  LOG(INFO) << "Profiler shutdown";
-  runtime->DetachCurrentThread();
-  return nullptr;
-}
-
-// Write out the profile file if we are generating a profile.
-uint32_t BackgroundMethodSamplingProfiler::WriteProfile() {
-  std::string full_name = output_filename_;
-  VLOG(profiler) << "Saving profile to " << full_name;
-
-  int fd = open(full_name.c_str(), O_RDWR);
-  if (fd < 0) {
-    // Open failed.
-    LOG(ERROR) << "Failed to open profile file " << full_name;
-    return 0;
-  }
-
-  // Lock the file for exclusive access.  This will block if another process is using
-  // the file.
-  int err = flock(fd, LOCK_EX);
-  if (err < 0) {
-    LOG(ERROR) << "Failed to lock profile file " << full_name;
-    return 0;
-  }
-
-  // Read the previous profile.
-  profile_table_.ReadPrevious(fd, options_.GetProfileType());
-
-  // Move back to the start of the file.
-  lseek(fd, 0, SEEK_SET);
-
-  // Format the profile output and write to the file.
-  std::ostringstream os;
-  uint32_t num_methods = DumpProfile(os);
-  std::string data(os.str());
-  const char *p = data.c_str();
-  size_t length = data.length();
-  size_t full_length = length;
-  do {
-    int n = ::write(fd, p, length);
-    p += n;
-    length -= n;
-  } while (length > 0);
-
-  // Truncate the file to the new length.
-  if (ftruncate(fd, full_length) == -1) {
-    LOG(ERROR) << "Failed to truncate profile file " << full_name;
-  }
-
-  // Now unlock the file, allowing another process in.
-  err = flock(fd, LOCK_UN);
-  if (err < 0) {
-    LOG(ERROR) << "Failed to unlock profile file " << full_name;
-  }
-
-  // Done, close the file.
-  ::close(fd);
-
-  // Clean the profile for the next time.
-  CleanProfile();
-
-  return num_methods;
-}
-
-bool BackgroundMethodSamplingProfiler::Start(
-    const std::string& output_filename, const ProfilerOptions& options) {
-  if (!options.IsEnabled()) {
-    return false;
-  }
-
-  CHECK(!output_filename.empty());
-
-  Thread* self = Thread::Current();
-  {
-    MutexLock mu(self, *Locks::profiler_lock_);
-    // Don't start two profiler threads.
-    if (profiler_ != nullptr) {
-      return true;
-    }
-  }
-
-  LOG(INFO) << "Starting profiler using output file: " << output_filename
-            << " and options: " << options;
-  {
-    MutexLock mu(self, *Locks::profiler_lock_);
-    profiler_ = new BackgroundMethodSamplingProfiler(output_filename, options);
-
-    CHECK_PTHREAD_CALL(pthread_create, (&profiler_pthread_, nullptr, &RunProfilerThread,
-        reinterpret_cast<void*>(profiler_)),
-                       "Profiler thread");
-  }
-  return true;
-}
-
-
-
-void BackgroundMethodSamplingProfiler::Stop() {
-  BackgroundMethodSamplingProfiler* profiler = nullptr;
-  pthread_t profiler_pthread = 0U;
-  {
-    MutexLock trace_mu(Thread::Current(), *Locks::profiler_lock_);
-    CHECK(!shutting_down_);
-    profiler = profiler_;
-    shutting_down_ = true;
-    profiler_pthread = profiler_pthread_;
-  }
-
-  // Now wake up the sampler thread if it sleeping.
-  {
-    MutexLock profile_mu(Thread::Current(), profiler->wait_lock_);
-    profiler->period_condition_.Signal(Thread::Current());
-  }
-  // Wait for the sample thread to stop.
-  CHECK_PTHREAD_CALL(pthread_join, (profiler_pthread, nullptr), "profiler thread shutdown");
-
-  {
-    MutexLock mu(Thread::Current(), *Locks::profiler_lock_);
-    profiler_ = nullptr;
-  }
-  delete profiler;
-}
-
-
-void BackgroundMethodSamplingProfiler::Shutdown() {
-  Stop();
-}
-
-BackgroundMethodSamplingProfiler::BackgroundMethodSamplingProfiler(
-  const std::string& output_filename, const ProfilerOptions& options)
-    : output_filename_(output_filename),
-      options_(options),
-      wait_lock_("Profile wait lock"),
-      period_condition_("Profile condition", wait_lock_),
-      profile_table_(wait_lock_),
-      profiler_barrier_(new Barrier(0)) {
-  // Populate the filtered_methods set.
-  // This is empty right now, but to add a method, do this:
-  //
-  // filtered_methods_.insert("void java.lang.Object.wait(long, int)");
-}
-
-// Filter out methods the profiler doesn't want to record.
-// We require mutator lock since some statistics will be updated here.
-bool BackgroundMethodSamplingProfiler::ProcessMethod(ArtMethod* method) {
-  if (method == nullptr) {
-    profile_table_.NullMethod();
-    // Don't record a null method.
-    return false;
-  }
-
-  mirror::Class* cls = method->GetDeclaringClass();
-  if (cls != nullptr) {
-    if (cls->GetClassLoader() == nullptr) {
-      // Don't include things in the boot
-      profile_table_.BootMethod();
-      return false;
-    }
-  }
-
-  bool is_filtered = false;
-
-  if (strcmp(method->GetName(), "<clinit>") == 0) {
-    // always filter out class init
-    is_filtered = true;
-  }
-
-  // Filter out methods by name if there are any.
-  if (!is_filtered && filtered_methods_.size() > 0) {
-    std::string method_full_name = PrettyMethod(method);
-
-    // Don't include specific filtered methods.
-    is_filtered = filtered_methods_.count(method_full_name) != 0;
-  }
-  return !is_filtered;
-}
-
-// A method has been hit, record its invocation in the method map.
-// The mutator_lock must be held (shared) when this is called.
-void BackgroundMethodSamplingProfiler::RecordMethod(ArtMethod* method) {
-  // Add to the profile table unless it is filtered out.
-  if (ProcessMethod(method)) {
-    profile_table_.Put(method);
-  }
-}
-
-// Record the current bounded stack into sampling results.
-void BackgroundMethodSamplingProfiler::RecordStack(const std::vector<InstructionLocation>& stack) {
-  if (stack.size() == 0) {
-    return;
-  }
-  // Get the method on top of the stack. We use this method to perform filtering.
-  ArtMethod* method = stack.front().first;
-  if (ProcessMethod(method)) {
-      profile_table_.PutStack(stack);
-  }
-}
-
-// Clean out any recordings for the method traces.
-void BackgroundMethodSamplingProfiler::CleanProfile() {
-  profile_table_.Clear();
-}
-
-uint32_t BackgroundMethodSamplingProfiler::DumpProfile(std::ostream& os) {
-  return profile_table_.Write(os, options_.GetProfileType());
-}
-
-// Profile Table.
-// This holds a mapping of ArtMethod* to a count of how many times a sample
-// hit it at the top of the stack.
-ProfileSampleResults::ProfileSampleResults(Mutex& lock)
-    : lock_(lock),
-      num_samples_(0U),
-      num_null_methods_(0U),
-      num_boot_methods_(0U),
-      previous_num_samples_(0U),
-      previous_num_null_methods_(0U),
-      previous_num_boot_methods_(0U) {
-  for (int i = 0; i < kHashSize; i++) {
-    table[i] = nullptr;
-  }
-  method_context_table = nullptr;
-  stack_trie_root_ = nullptr;
-}
-
-ProfileSampleResults::~ProfileSampleResults() {
-  Clear();
-}
-
-// Add a method to the profile table.  If it's the first time the method
-// has been seen, add it with count=1, otherwise increment the count.
-void ProfileSampleResults::Put(ArtMethod* method) {
-  MutexLock mu(Thread::Current(), lock_);
-  uint32_t index = Hash(method);
-  if (table[index] == nullptr) {
-    table[index] = new Map();
-  }
-  Map::iterator i = table[index]->find(method);
-  if (i == table[index]->end()) {
-    (*table[index])[method] = 1;
-  } else {
-    i->second++;
-  }
-  num_samples_++;
-}
-
-// Add a bounded stack to the profile table. Only the count of the method on
-// top of the frame will be increased.
-void ProfileSampleResults::PutStack(const std::vector<InstructionLocation>& stack) {
-  MutexLock mu(Thread::Current(), lock_);
-  ScopedObjectAccess soa(Thread::Current());
-  if (stack_trie_root_ == nullptr) {
-    // The root of the stack trie is a dummy node so that we don't have to maintain
-    // a collection of tries.
-    stack_trie_root_ = new StackTrieNode();
-  }
-
-  StackTrieNode* current = stack_trie_root_;
-  if (stack.size() == 0) {
-    current->IncreaseCount();
-    return;
-  }
-
-  for (std::vector<InstructionLocation>::const_reverse_iterator iter = stack.rbegin();
-       iter != stack.rend(); ++iter) {
-    InstructionLocation inst_loc = *iter;
-    ArtMethod* method = inst_loc.first;
-    if (method == nullptr) {
-      // skip null method
-      continue;
-    }
-    uint32_t dex_pc = inst_loc.second;
-    uint32_t method_idx = method->GetDexMethodIndex();
-    const DexFile* dex_file = method->GetDeclaringClass()->GetDexCache()->GetDexFile();
-    MethodReference method_ref(dex_file, method_idx);
-    StackTrieNode* child = current->FindChild(method_ref, dex_pc);
-    if (child != nullptr) {
-      current = child;
-    } else {
-      uint32_t method_size = 0;
-      const DexFile::CodeItem* codeitem = method->GetCodeItem();
-      if (codeitem != nullptr) {
-        method_size = codeitem->insns_size_in_code_units_;
-      }
-      StackTrieNode* new_node = new StackTrieNode(method_ref, dex_pc, method_size, current);
-      current->AppendChild(new_node);
-      current = new_node;
-    }
-  }
-
-  if (current != stack_trie_root_ && current->GetCount() == 0) {
-    // Insert into method_context table;
-    if (method_context_table == nullptr) {
-      method_context_table = new MethodContextMap();
-    }
-    MethodReference method = current->GetMethod();
-    MethodContextMap::iterator i = method_context_table->find(method);
-    if (i == method_context_table->end()) {
-      TrieNodeSet* node_set = new TrieNodeSet();
-      node_set->insert(current);
-      (*method_context_table)[method] = node_set;
-    } else {
-      TrieNodeSet* node_set = i->second;
-      node_set->insert(current);
-    }
-  }
-  current->IncreaseCount();
-  num_samples_++;
-}
-
-// Write the profile table to the output stream.  Also merge with the previous profile.
-uint32_t ProfileSampleResults::Write(std::ostream& os, ProfileDataType type) {
-  ScopedObjectAccess soa(Thread::Current());
-  num_samples_ += previous_num_samples_;
-  num_null_methods_ += previous_num_null_methods_;
-  num_boot_methods_ += previous_num_boot_methods_;
-
-  VLOG(profiler) << "Profile: "
-                 << num_samples_ << "/" << num_null_methods_ << "/" << num_boot_methods_;
-  os << num_samples_ << "/" << num_null_methods_ << "/" << num_boot_methods_ << "\n";
-  uint32_t num_methods = 0;
-  if (type == kProfilerMethod) {
-    for (int i = 0 ; i < kHashSize; i++) {
-      Map *map = table[i];
-      if (map != nullptr) {
-        for (const auto &meth_iter : *map) {
-          ArtMethod *method = meth_iter.first;
-          std::string method_name = PrettyMethod(method);
-
-          const DexFile::CodeItem* codeitem = method->GetCodeItem();
-          uint32_t method_size = 0;
-          if (codeitem != nullptr) {
-            method_size = codeitem->insns_size_in_code_units_;
-          }
-          uint32_t count = meth_iter.second;
-
-          // Merge this profile entry with one from a previous run (if present).  Also
-          // remove the previous entry.
-          PreviousProfile::iterator pi = previous_.find(method_name);
-          if (pi != previous_.end()) {
-            count += pi->second.count_;
-            previous_.erase(pi);
-          }
-          os << StringPrintf("%s/%u/%u\n",  method_name.c_str(), count, method_size);
-          ++num_methods;
-        }
-      }
-    }
-  } else if (type == kProfilerBoundedStack) {
-    if (method_context_table != nullptr) {
-      for (const auto &method_iter : *method_context_table) {
-        MethodReference method = method_iter.first;
-        TrieNodeSet* node_set = method_iter.second;
-        std::string method_name = PrettyMethod(method.dex_method_index, *(method.dex_file));
-        uint32_t method_size = 0;
-        uint32_t total_count = 0;
-        PreviousContextMap new_context_map;
-        for (const auto &trie_node_i : *node_set) {
-          StackTrieNode* node = trie_node_i;
-          method_size = node->GetMethodSize();
-          uint32_t count = node->GetCount();
-          uint32_t dexpc = node->GetDexPC();
-          total_count += count;
-
-          StackTrieNode* current = node->GetParent();
-          // We go backward on the trie to retrieve context and dex_pc until the dummy root.
-          // The format of the context is "method_1@pc_1@method_2@pc_2@..."
-          std::vector<std::string> context_vector;
-          while (current != nullptr && current->GetParent() != nullptr) {
-            context_vector.push_back(StringPrintf("%s@%u",
-                PrettyMethod(current->GetMethod().dex_method_index, *(current->GetMethod().dex_file)).c_str(),
-                current->GetDexPC()));
-            current = current->GetParent();
-          }
-          std::string context_sig = Join(context_vector, '@');
-          new_context_map[std::make_pair(dexpc, context_sig)] = count;
-        }
-
-        PreviousProfile::iterator pi = previous_.find(method_name);
-        if (pi != previous_.end()) {
-          total_count += pi->second.count_;
-          PreviousContextMap* previous_context_map = pi->second.context_map_;
-          if (previous_context_map != nullptr) {
-            for (const auto &context_i : *previous_context_map) {
-              uint32_t count = context_i.second;
-              PreviousContextMap::iterator ci = new_context_map.find(context_i.first);
-              if (ci == new_context_map.end()) {
-                new_context_map[context_i.first] = count;
-              } else {
-                ci->second += count;
-              }
-            }
-          }
-          delete previous_context_map;
-          previous_.erase(pi);
-        }
-        // We write out profile data with dex pc and context information in the following format:
-        // "method/total_count/size/[pc_1:count_1:context_1#pc_2:count_2:context_2#...]".
-        std::vector<std::string> context_count_vector;
-        for (const auto &context_i : new_context_map) {
-          context_count_vector.push_back(StringPrintf("%u:%u:%s", context_i.first.first,
-              context_i.second, context_i.first.second.c_str()));
-        }
-        os << StringPrintf("%s/%u/%u/[%s]\n", method_name.c_str(), total_count,
-            method_size, Join(context_count_vector, '#').c_str());
-        ++num_methods;
-      }
-    }
-  }
-
-  // Now we write out the remaining previous methods.
-  for (const auto &pi : previous_) {
-    if (type == kProfilerMethod) {
-      os << StringPrintf("%s/%u/%u\n",  pi.first.c_str(), pi.second.count_, pi.second.method_size_);
-    } else if (type == kProfilerBoundedStack) {
-      os << StringPrintf("%s/%u/%u/[",  pi.first.c_str(), pi.second.count_, pi.second.method_size_);
-      PreviousContextMap* previous_context_map = pi.second.context_map_;
-      if (previous_context_map != nullptr) {
-        std::vector<std::string> context_count_vector;
-        for (const auto &context_i : *previous_context_map) {
-          context_count_vector.push_back(StringPrintf("%u:%u:%s", context_i.first.first,
-              context_i.second, context_i.first.second.c_str()));
-        }
-        os << Join(context_count_vector, '#');
-      }
-      os << "]\n";
-    }
-    ++num_methods;
-  }
-  return num_methods;
-}
-
-void ProfileSampleResults::Clear() {
-  num_samples_ = 0;
-  num_null_methods_ = 0;
-  num_boot_methods_ = 0;
-  for (int i = 0; i < kHashSize; i++) {
-    delete table[i];
-    table[i] = nullptr;
-  }
-  if (stack_trie_root_ != nullptr) {
-    stack_trie_root_->DeleteChildren();
-    delete stack_trie_root_;
-    stack_trie_root_ = nullptr;
-    if (method_context_table != nullptr) {
-      delete method_context_table;
-      method_context_table = nullptr;
-    }
-  }
-  for (auto &pi : previous_) {
-    if (pi.second.context_map_ != nullptr) {
-      delete pi.second.context_map_;
-      pi.second.context_map_ = nullptr;
-    }
-  }
-  previous_.clear();
-}
-
-uint32_t ProfileSampleResults::Hash(ArtMethod* method) {
-  return (PointerToLowMemUInt32(method) >> 3) % kHashSize;
-}
-
-// Read a single line into the given string.  Returns true if everything OK, false
-// on EOF or error.
-static bool ReadProfileLine(int fd, std::string& line) {
-  char buf[4];
-  line.clear();
-  while (true) {
-    int n = read(fd, buf, 1);     // TODO: could speed this up but is it worth it?
-    if (n != 1) {
-      return false;
-    }
-    if (buf[0] == '\n') {
-      break;
-    }
-    line += buf[0];
-  }
-  return true;
-}
-
-void ProfileSampleResults::ReadPrevious(int fd, ProfileDataType type) {
-  // Reset counters.
-  previous_num_samples_ = previous_num_null_methods_ = previous_num_boot_methods_ = 0;
-
-  std::string line;
-
-  // The first line contains summary information.
-  if (!ReadProfileLine(fd, line)) {
-    return;
-  }
-  std::vector<std::string> summary_info;
-  Split(line, '/', &summary_info);
-  if (summary_info.size() != 3) {
-    // Bad summary info.  It should be count/nullcount/bootcount
-    return;
-  }
-  previous_num_samples_ = strtoul(summary_info[0].c_str(), nullptr, 10);
-  previous_num_null_methods_ = strtoul(summary_info[1].c_str(), nullptr, 10);
-  previous_num_boot_methods_ = strtoul(summary_info[2].c_str(), nullptr, 10);
-
-  // Now read each line until the end of file.  Each line consists of 3 or 4 fields separated by /
-  while (true) {
-    if (!ReadProfileLine(fd, line)) {
-      break;
-    }
-    std::vector<std::string> info;
-    Split(line, '/', &info);
-    if (info.size() != 3 && info.size() != 4) {
-      // Malformed.
-      break;
-    }
-    std::string methodname = info[0];
-    uint32_t total_count = strtoul(info[1].c_str(), nullptr, 10);
-    uint32_t size = strtoul(info[2].c_str(), nullptr, 10);
-    PreviousContextMap* context_map = nullptr;
-    if (type == kProfilerBoundedStack && info.size() == 4) {
-      context_map = new PreviousContextMap();
-      std::string context_counts_str = info[3].substr(1, info[3].size() - 2);
-      std::vector<std::string> context_count_pairs;
-      Split(context_counts_str, '#', &context_count_pairs);
-      for (uint32_t i = 0; i < context_count_pairs.size(); ++i) {
-        std::vector<std::string> context_count;
-        Split(context_count_pairs[i], ':', &context_count);
-        if (context_count.size() == 2) {
-          // Handles the situtation when the profile file doesn't contain context information.
-          uint32_t dexpc = strtoul(context_count[0].c_str(), nullptr, 10);
-          uint32_t count = strtoul(context_count[1].c_str(), nullptr, 10);
-          (*context_map)[std::make_pair(dexpc, "")] = count;
-        } else {
-          // Handles the situtation when the profile file contains context information.
-          uint32_t dexpc = strtoul(context_count[0].c_str(), nullptr, 10);
-          uint32_t count = strtoul(context_count[1].c_str(), nullptr, 10);
-          std::string context = context_count[2];
-          (*context_map)[std::make_pair(dexpc, context)] = count;
-        }
-      }
-    }
-    previous_[methodname] = PreviousValue(total_count, size, context_map);
-  }
-}
-
-bool ProfileFile::LoadFile(const std::string& fileName) {
-  LOG(VERBOSE) << "reading profile file " << fileName;
-  struct stat st;
-  int err = stat(fileName.c_str(), &st);
-  if (err == -1) {
-    LOG(VERBOSE) << "not found";
-    return false;
-  }
-  if (st.st_size == 0) {
-    return false;  // Empty profiles are invalid.
-  }
-  std::ifstream in(fileName.c_str());
-  if (!in) {
-    LOG(VERBOSE) << "profile file " << fileName << " exists but can't be opened";
-    LOG(VERBOSE) << "file owner: " << st.st_uid << ":" << st.st_gid;
-    LOG(VERBOSE) << "me: " << getuid() << ":" << getgid();
-    LOG(VERBOSE) << "file permissions: " << std::oct << st.st_mode;
-    LOG(VERBOSE) << "errno: " << errno;
-    return false;
-  }
-  // The first line contains summary information.
-  std::string line;
-  std::getline(in, line);
-  if (in.eof()) {
-    return false;
-  }
-  std::vector<std::string> summary_info;
-  Split(line, '/', &summary_info);
-  if (summary_info.size() != 3) {
-    // Bad summary info.  It should be total/null/boot.
-    return false;
-  }
-  // This is the number of hits in all profiled methods (without null or boot methods)
-  uint32_t total_count = strtoul(summary_info[0].c_str(), nullptr, 10);
-
-  // Now read each line until the end of file.  Each line consists of 3 fields separated by '/'.
-  // Store the info in descending order given by the most used methods.
-  typedef std::set<std::pair<int, std::vector<std::string>>> ProfileSet;
-  ProfileSet countSet;
-  while (!in.eof()) {
-    std::getline(in, line);
-    if (in.eof()) {
-      break;
-    }
-    std::vector<std::string> info;
-    Split(line, '/', &info);
-    if (info.size() != 3 && info.size() != 4) {
-      // Malformed.
-      return false;
-    }
-    int count = atoi(info[1].c_str());
-    countSet.insert(std::make_pair(-count, info));
-  }
-
-  uint32_t curTotalCount = 0;
-  ProfileSet::iterator end = countSet.end();
-  const ProfileData* prevData = nullptr;
-  for (ProfileSet::iterator it = countSet.begin(); it != end ; it++) {
-    const std::string& methodname = it->second[0];
-    uint32_t count = -it->first;
-    uint32_t size = strtoul(it->second[2].c_str(), nullptr, 10);
-    double usedPercent = (count * 100.0) / total_count;
-
-    curTotalCount += count;
-    // Methods with the same count should be part of the same top K percentage bucket.
-    double topKPercentage = (prevData != nullptr) && (prevData->GetCount() == count)
-      ? prevData->GetTopKUsedPercentage()
-      : 100 * static_cast<double>(curTotalCount) / static_cast<double>(total_count);
-
-    // Add it to the profile map.
-    ProfileData curData = ProfileData(methodname, count, size, usedPercent, topKPercentage);
-    profile_map_[methodname] = curData;
-    prevData = &curData;
-  }
-  return true;
-}
-
-bool ProfileFile::GetProfileData(ProfileFile::ProfileData* data, const std::string& method_name) {
-  ProfileMap::iterator i = profile_map_.find(method_name);
-  if (i == profile_map_.end()) {
-    return false;
-  }
-  *data = i->second;
-  return true;
-}
-
-bool ProfileFile::GetTopKSamples(std::set<std::string>& topKSamples, double topKPercentage) {
-  ProfileMap::iterator end = profile_map_.end();
-  for (ProfileMap::iterator it = profile_map_.begin(); it != end; it++) {
-    if (it->second.GetTopKUsedPercentage() < topKPercentage) {
-      topKSamples.insert(it->first);
-    }
-  }
-  return true;
-}
-
-StackTrieNode* StackTrieNode::FindChild(MethodReference method, uint32_t dex_pc) {
-  if (children_.size() == 0) {
-    return nullptr;
-  }
-  // Create a dummy node for searching.
-  StackTrieNode* node = new StackTrieNode(method, dex_pc, 0, nullptr);
-  std::set<StackTrieNode*, StackTrieNodeComparator>::iterator i = children_.find(node);
-  delete node;
-  return (i == children_.end()) ? nullptr : *i;
-}
-
-void StackTrieNode::DeleteChildren() {
-  for (auto &child : children_) {
-    if (child != nullptr) {
-      child->DeleteChildren();
-      delete child;
-    }
-  }
-}
-
-}  // namespace art
diff --git a/runtime/profiler.h b/runtime/profiler.h
deleted file mode 100644
index bd29f71..0000000
--- a/runtime/profiler.h
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * Copyright (C) 2011 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.
- */
-
-#ifndef ART_RUNTIME_PROFILER_H_
-#define ART_RUNTIME_PROFILER_H_
-
-#include <memory>
-#include <ostream>
-#include <set>
-#include <string>
-#include <vector>
-
-#include "barrier.h"
-#include "base/macros.h"
-#include "base/mutex.h"
-#include "globals.h"
-#include "instrumentation.h"
-#include "profiler_options.h"
-#include "os.h"
-#include "safe_map.h"
-#include "method_reference.h"
-
-namespace art {
-
-namespace mirror {
-  class Class;
-}  // namespace mirror
-class ArtMethod;
-class Thread;
-
-typedef std::pair<ArtMethod*, uint32_t> InstructionLocation;
-
-// This class stores the sampled bounded stacks in a trie structure. A path of the trie represents
-// a particular context with the method on top of the stack being a leaf or an internal node of the
-// trie rather than the root.
-class StackTrieNode {
- public:
-  StackTrieNode(MethodReference method, uint32_t dex_pc, uint32_t method_size,
-      StackTrieNode* parent) :
-      parent_(parent), method_(method), dex_pc_(dex_pc),
-      count_(0), method_size_(method_size) {
-  }
-  StackTrieNode() : parent_(nullptr), method_(nullptr, 0),
-      dex_pc_(0), count_(0), method_size_(0) {
-  }
-  StackTrieNode* GetParent() { return parent_; }
-  MethodReference GetMethod() { return method_; }
-  uint32_t GetCount() { return count_; }
-  uint32_t GetDexPC() { return dex_pc_; }
-  uint32_t GetMethodSize() { return method_size_; }
-  void AppendChild(StackTrieNode* child) { children_.insert(child); }
-  StackTrieNode* FindChild(MethodReference method, uint32_t dex_pc);
-  void DeleteChildren();
-  void IncreaseCount() { ++count_; }
-
- private:
-  // Comparator for stack trie node.
-  struct StackTrieNodeComparator {
-    bool operator()(StackTrieNode* node1, StackTrieNode* node2) const {
-      MethodReference mr1 = node1->GetMethod();
-      MethodReference mr2 = node2->GetMethod();
-      if (mr1.dex_file == mr2.dex_file) {
-        if (mr1.dex_method_index == mr2.dex_method_index) {
-          return node1->GetDexPC() < node2->GetDexPC();
-        } else {
-          return mr1.dex_method_index < mr2.dex_method_index;
-        }
-      } else {
-        return mr1.dex_file < mr2.dex_file;
-      }
-    }
-  };
-
-  std::set<StackTrieNode*, StackTrieNodeComparator> children_;
-  StackTrieNode* parent_;
-  MethodReference method_;
-  uint32_t dex_pc_;
-  uint32_t count_;
-  uint32_t method_size_;
-};
-
-//
-// This class holds all the results for all runs of the profiler.  It also
-// counts the number of null methods (where we can't determine the method) and
-// the number of methods in the boot path (where we have already compiled the method).
-//
-// This object is an internal profiler object and uses the same locking as the profiler
-// itself.
-class ProfileSampleResults {
- public:
-  explicit ProfileSampleResults(Mutex& lock);
-  ~ProfileSampleResults();
-
-  void Put(ArtMethod* method) REQUIRES(!lock_);
-  void PutStack(const std::vector<InstructionLocation>& stack_dump) REQUIRES(!lock_);
-  uint32_t Write(std::ostream &os, ProfileDataType type);
-  void ReadPrevious(int fd, ProfileDataType type);
-  void Clear();
-  uint32_t GetNumSamples() { return num_samples_; }
-  void NullMethod() { ++num_null_methods_; }
-  void BootMethod() { ++num_boot_methods_; }
-
- private:
-  uint32_t Hash(ArtMethod* method);
-  static constexpr int kHashSize = 17;
-  Mutex& lock_;                  // Reference to the main profiler lock - we don't need two of them.
-  uint32_t num_samples_;         // Total number of samples taken.
-  uint32_t num_null_methods_;    // Number of samples where can don't know the method.
-  uint32_t num_boot_methods_;    // Number of samples in the boot path.
-
-  typedef std::map<ArtMethod*, uint32_t> Map;  // Map of method vs its count.
-  Map *table[kHashSize];
-
-  typedef std::set<StackTrieNode*> TrieNodeSet;
-  // Map of method hit by profiler vs the set of stack trie nodes for this method.
-  typedef std::map<MethodReference, TrieNodeSet*, MethodReferenceComparator> MethodContextMap;
-  MethodContextMap *method_context_table;
-  StackTrieNode* stack_trie_root_;  // Root of the trie that stores sampled stack information.
-
-  // Map from <pc, context> to counts.
-  typedef std::map<std::pair<uint32_t, std::string>, uint32_t> PreviousContextMap;
-  struct PreviousValue {
-    PreviousValue() : count_(0), method_size_(0), context_map_(nullptr) {}
-    PreviousValue(uint32_t count, uint32_t method_size, PreviousContextMap* context_map)
-      : count_(count), method_size_(method_size), context_map_(context_map) {}
-    uint32_t count_;
-    uint32_t method_size_;
-    PreviousContextMap* context_map_;
-  };
-
-  typedef std::map<std::string, PreviousValue> PreviousProfile;
-  PreviousProfile previous_;
-  uint32_t previous_num_samples_;
-  uint32_t previous_num_null_methods_;     // Number of samples where can don't know the method.
-  uint32_t previous_num_boot_methods_;     // Number of samples in the boot path.
-};
-
-//
-// The BackgroundMethodSamplingProfiler runs in a thread.  Most of the time it is sleeping but
-// occasionally wakes up and counts the number of times a method is called.  Each time
-// it ticks, it looks at the current method and records it in the ProfileSampleResults
-// table.
-//
-// The timing is controlled by a number of variables:
-// 1.  Period: the time between sampling runs.
-// 2.  Interval: the time between each sample in a run.
-// 3.  Duration: the duration of a run.
-//
-// So the profiler thread is sleeping for the 'period' time.  It wakes up and runs for the
-// 'duration'.  The run consists of a series of samples, each of which is 'interval' microseconds
-// apart.  At the end of a run, it writes the results table to a file and goes back to sleep.
-
-class BackgroundMethodSamplingProfiler {
- public:
-  // Start a profile thread with the user-supplied arguments.
-  // Returns true if the profile was started or if it was already running. Returns false otherwise.
-  static bool Start(const std::string& output_filename, const ProfilerOptions& options)
-      REQUIRES(!Locks::mutator_lock_, !Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_,
-               !Locks::profiler_lock_);
-
-  // NO_THREAD_SAFETY_ANALYSIS for static function calling into member function with excludes lock.
-  static void Stop() REQUIRES(!Locks::profiler_lock_, !wait_lock_, !Locks::profiler_lock_)
-      NO_THREAD_SAFETY_ANALYSIS;
-  // NO_THREAD_SAFETY_ANALYSIS for static function calling into member function with excludes lock.
-  static void Shutdown() REQUIRES(!Locks::profiler_lock_) NO_THREAD_SAFETY_ANALYSIS;
-
-  void RecordMethod(ArtMethod *method) SHARED_REQUIRES(Locks::mutator_lock_);
-  void RecordStack(const std::vector<InstructionLocation>& stack)
-      SHARED_REQUIRES(Locks::mutator_lock_);
-  bool ProcessMethod(ArtMethod* method) SHARED_REQUIRES(Locks::mutator_lock_);
-  const ProfilerOptions& GetProfilerOptions() const { return options_; }
-
-  Barrier& GetBarrier() {
-    return *profiler_barrier_;
-  }
-
- private:
-  explicit BackgroundMethodSamplingProfiler(
-    const std::string& output_filename, const ProfilerOptions& options);
-
-  // The sampling interval in microseconds is passed as an argument.
-  // NO_THREAD_SAFETY_ANALYSIS for static function calling into member function with excludes lock.
-  static void* RunProfilerThread(void* arg) REQUIRES(!Locks::profiler_lock_)
-      NO_THREAD_SAFETY_ANALYSIS;
-
-  uint32_t WriteProfile() SHARED_REQUIRES(Locks::mutator_lock_);
-
-  void CleanProfile();
-  uint32_t DumpProfile(std::ostream& os) SHARED_REQUIRES(Locks::mutator_lock_);
-  static bool ShuttingDown(Thread* self) REQUIRES(!Locks::profiler_lock_);
-
-  static BackgroundMethodSamplingProfiler* profiler_ GUARDED_BY(Locks::profiler_lock_);
-
-  // We need to shut the sample thread down at exit.  Setting this to true will do that.
-  static volatile bool shutting_down_ GUARDED_BY(Locks::profiler_lock_);
-
-  // Sampling thread, non-zero when sampling.
-  static pthread_t profiler_pthread_;
-
-  // Some measure of the number of samples that are significant.
-  static constexpr uint32_t kSignificantSamples = 10;
-
-  // The name of the file where profile data will be written.
-  std::string output_filename_;
-  // The options used to start the profiler.
-  const ProfilerOptions& options_;
-
-
-  // Profile condition support.
-  Mutex wait_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
-  ConditionVariable period_condition_ GUARDED_BY(wait_lock_);
-
-  ProfileSampleResults profile_table_;
-
-  std::unique_ptr<Barrier> profiler_barrier_;
-
-  // Set of methods to be filtered out.  This will probably be rare because
-  // most of the methods we want to be filtered reside in the boot path and
-  // are automatically filtered.
-  typedef std::set<std::string> FilteredMethods;
-  FilteredMethods filtered_methods_;
-
-  DISALLOW_COPY_AND_ASSIGN(BackgroundMethodSamplingProfiler);
-};
-
-//
-// Contains profile data generated from previous runs of the program and stored
-// in a file.  It is used to determine whether to compile a particular method or not.
-class ProfileFile {
- public:
-  class ProfileData {
-   public:
-    ProfileData() : count_(0), method_size_(0), used_percent_(0), top_k_used_percentage_(0) {}
-    ProfileData(const std::string& method_name, uint32_t count, uint32_t method_size,
-      double used_percent, double top_k_used_percentage) :
-      method_name_(method_name), count_(count), method_size_(method_size),
-      used_percent_(used_percent), top_k_used_percentage_(top_k_used_percentage) {
-      // TODO: currently method_size_ is unused
-      UNUSED(method_size_);
-    }
-
-    double GetUsedPercent() const { return used_percent_; }
-    uint32_t GetCount() const { return count_; }
-    double GetTopKUsedPercentage() const { return top_k_used_percentage_; }
-
-   private:
-    std::string method_name_;       // Method name.
-    uint32_t count_;                // Number of times it has been called.
-    uint32_t method_size_;          // Size of the method on dex instructions.
-    double used_percent_;           // Percentage of how many times this method was called.
-    double top_k_used_percentage_;  // The percentage of the group that comprise K% of the total
-                                    // used methods this methods belongs to.
-  };
-
- public:
-  // Loads profile data from the given file. The new data are merged with any existing data.
-  // Returns true if the file was loaded successfully and false otherwise.
-  bool LoadFile(const std::string& filename);
-
-  // Computes the group that comprise top_k_percentage of the total used methods.
-  bool GetTopKSamples(std::set<std::string>& top_k_methods, double top_k_percentage);
-
-  // If the given method has an entry in the profile table it updates the data
-  // and returns true. Otherwise returns false and leaves the data unchanged.
-  bool GetProfileData(ProfileData* data, const std::string& method_name);
-
- private:
-  // Profile data is stored in a map, indexed by the full method name.
-  typedef std::map<std::string, ProfileData> ProfileMap;
-  ProfileMap profile_map_;
-};
-
-}  // namespace art
-
-#endif  // ART_RUNTIME_PROFILER_H_
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 40e1b13..af70270 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -118,7 +118,6 @@
 #include "oat_file_manager.h"
 #include "os.h"
 #include "parsed_options.h"
-#include "profiler.h"
 #include "jit/profile_saver.h"
 #include "quick/quick_method_frame_info.h"
 #include "reflection.h"
