Version 3.17.13

Turned Flags into a uint32_t typedef (Chromium issue 194749).

Performance and stability improvements on all platforms.

git-svn-id: http://v8.googlecode.com/svn/trunk@13993 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/api.cc b/src/api.cc
index 64c0022..dfa5765 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -6454,6 +6454,11 @@
 }
 
 
+unsigned CpuProfileNode::GetNodeId() const {
+  return reinterpret_cast<const i::ProfileNode*>(this)->id();
+}
+
+
 int CpuProfileNode::GetChildrenCount() const {
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::CpuProfileNode::GetChildrenCount");
@@ -6473,11 +6478,12 @@
 void CpuProfile::Delete() {
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::CpuProfile::Delete");
-  i::CpuProfiler::DeleteProfile(reinterpret_cast<i::CpuProfile*>(this));
-  if (i::CpuProfiler::GetProfilesCount() == 0 &&
-      !i::CpuProfiler::HasDetachedProfiles()) {
+  i::CpuProfiler* profiler = isolate->cpu_profiler();
+  ASSERT(profiler != NULL);
+  profiler->DeleteProfile(reinterpret_cast<i::CpuProfile*>(this));
+  if (profiler->GetProfilesCount() == 0 && !profiler->HasDetachedProfiles()) {
     // If this was the last profile, clean up all accessory data as well.
-    i::CpuProfiler::DeleteAllProfiles();
+    profiler->DeleteAllProfiles();
   }
 }
 
@@ -6506,10 +6512,23 @@
 }
 
 
+const CpuProfileNode* CpuProfile::GetSample(int index) const {
+  const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
+  return reinterpret_cast<const CpuProfileNode*>(profile->sample(index));
+}
+
+
+int CpuProfile::GetSamplesCount() const {
+  return reinterpret_cast<const i::CpuProfile*>(this)->samples_count();
+}
+
+
 int CpuProfiler::GetProfilesCount() {
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::CpuProfiler::GetProfilesCount");
-  return i::CpuProfiler::GetProfilesCount();
+  i::CpuProfiler* profiler = isolate->cpu_profiler();
+  ASSERT(profiler != NULL);
+  return profiler->GetProfilesCount();
 }
 
 
@@ -6517,8 +6536,10 @@
                                           Handle<Value> security_token) {
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::CpuProfiler::GetProfile");
+  i::CpuProfiler* profiler = isolate->cpu_profiler();
+  ASSERT(profiler != NULL);
   return reinterpret_cast<const CpuProfile*>(
-      i::CpuProfiler::GetProfile(
+      profiler->GetProfile(
           security_token.IsEmpty() ? NULL : *Utils::OpenHandle(*security_token),
           index));
 }
@@ -6528,17 +6549,21 @@
                                            Handle<Value> security_token) {
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::CpuProfiler::FindProfile");
+  i::CpuProfiler* profiler = isolate->cpu_profiler();
+  ASSERT(profiler != NULL);
   return reinterpret_cast<const CpuProfile*>(
-      i::CpuProfiler::FindProfile(
+      profiler->FindProfile(
           security_token.IsEmpty() ? NULL : *Utils::OpenHandle(*security_token),
           uid));
 }
 
 
-void CpuProfiler::StartProfiling(Handle<String> title) {
+void CpuProfiler::StartProfiling(Handle<String> title, bool record_samples) {
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::CpuProfiler::StartProfiling");
-  i::CpuProfiler::StartProfiling(*Utils::OpenHandle(*title));
+  i::CpuProfiler* profiler = isolate->cpu_profiler();
+  ASSERT(profiler != NULL);
+  profiler->StartProfiling(*Utils::OpenHandle(*title), record_samples);
 }
 
 
@@ -6546,8 +6571,10 @@
                                              Handle<Value> security_token) {
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::CpuProfiler::StopProfiling");
+  i::CpuProfiler* profiler = isolate->cpu_profiler();
+  ASSERT(profiler != NULL);
   return reinterpret_cast<const CpuProfile*>(
-      i::CpuProfiler::StopProfiling(
+      profiler->StopProfiling(
           security_token.IsEmpty() ? NULL : *Utils::OpenHandle(*security_token),
           *Utils::OpenHandle(*title)));
 }
@@ -6556,7 +6583,9 @@
 void CpuProfiler::DeleteAllProfiles() {
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::CpuProfiler::DeleteAllProfiles");
-  i::CpuProfiler::DeleteAllProfiles();
+  i::CpuProfiler* profiler = isolate->cpu_profiler();
+  ASSERT(profiler != NULL);
+  profiler->DeleteAllProfiles();
 }
 
 
diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc
index 3ef8d37..58b2ad0 100644
--- a/src/bootstrapper.cc
+++ b/src/bootstrapper.cc
@@ -147,23 +147,13 @@
           v8::ExtensionConfiguration* extensions);
   ~Genesis() { }
 
-  Handle<Context> result() { return result_; }
-
-  Genesis* previous() { return previous_; }
-
   Isolate* isolate() const { return isolate_; }
   Factory* factory() const { return isolate_->factory(); }
   Heap* heap() const { return isolate_->heap(); }
 
+  Handle<Context> result() { return result_; }
+
  private:
-  Handle<Context> native_context_;
-  Isolate* isolate_;
-
-  // There may be more than one active genesis object: When GC is
-  // triggered during environment creation there may be weak handle
-  // processing callbacks which may create new environments.
-  Genesis* previous_;
-
   Handle<Context> native_context() { return native_context_; }
 
   // Creates some basic objects. Used for creating a context from scratch.
@@ -284,7 +274,9 @@
                                   Handle<Context> top_context,
                                   bool use_runtime_context);
 
+  Isolate* isolate_;
   Handle<Context> result_;
+  Handle<Context> native_context_;
 
   // Function instance maps. Function literal maps are created initially with
   // a read only prototype for the processing of JS builtins. Later the function
@@ -310,9 +302,9 @@
     v8::Handle<v8::ObjectTemplate> global_template,
     v8::ExtensionConfiguration* extensions) {
   HandleScope scope(isolate_);
-  Handle<Context> env;
   Genesis genesis(isolate_, global_object, global_template, extensions);
-  env = genesis.result();
+  Handle<Object> context(isolate_->global_handles()->Create(*genesis.result()));
+  Handle<Context> env = Handle<Context>::cast(context);
   if (!env.is_null()) {
     if (InstallExtensions(env, extensions)) {
       return env;
@@ -699,9 +691,8 @@
   // closure and extension object later (we need the empty function
   // and the global object, but in order to create those, we need the
   // native context).
-  native_context_ = Handle<Context>::cast(isolate()->global_handles()->Create(
-              *factory()->NewNativeContext()));
-  AddToWeakNativeContextList(*native_context_);
+  native_context_ = factory()->NewNativeContext();
+  AddToWeakNativeContextList(*native_context());
   isolate()->set_context(*native_context());
 
   // Allocate the message listeners object.
@@ -830,11 +821,11 @@
 
 void Genesis::HookUpInnerGlobal(Handle<GlobalObject> inner_global) {
   Handle<GlobalObject> inner_global_from_snapshot(
-      GlobalObject::cast(native_context_->extension()));
-  Handle<JSBuiltinsObject> builtins_global(native_context_->builtins());
-  native_context_->set_extension(*inner_global);
-  native_context_->set_global_object(*inner_global);
-  native_context_->set_security_token(*inner_global);
+      GlobalObject::cast(native_context()->extension()));
+  Handle<JSBuiltinsObject> builtins_global(native_context()->builtins());
+  native_context()->set_extension(*inner_global);
+  native_context()->set_global_object(*inner_global);
+  native_context()->set_security_token(*inner_global);
   static const PropertyAttributes attributes =
       static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE);
   ForceSetProperty(builtins_global,
@@ -2424,7 +2415,6 @@
 
   // Before creating the roots we must save the context and restore it
   // on all function exits.
-  HandleScope scope(isolate);
   SaveContext saved_context(isolate);
 
   // During genesis, the boilerplate for stack overflow won't work until the
@@ -2433,12 +2423,10 @@
   StackLimitCheck check(isolate);
   if (check.HasOverflowed()) return;
 
-  Handle<Context> new_context = Snapshot::NewContextFromSnapshot();
-  if (!new_context.is_null()) {
-    native_context_ =
-        Handle<Context>::cast(isolate->global_handles()->Create(*new_context));
-    AddToWeakNativeContextList(*native_context_);
-    isolate->set_context(*native_context_);
+  native_context_ = Snapshot::NewContextFromSnapshot();
+  if (!native_context().is_null()) {
+    AddToWeakNativeContextList(*native_context());
+    isolate->set_context(*native_context());
     isolate->counters()->contexts_created_by_snapshot()->Increment();
     Handle<GlobalObject> inner_global;
     Handle<JSGlobalProxy> global_proxy =
@@ -2474,7 +2462,7 @@
   InitializeExperimentalGlobal();
   if (!InstallExperimentalNatives()) return;
 
-  result_ = native_context_;
+  result_ = native_context();
 }
 
 
diff --git a/src/codegen.cc b/src/codegen.cc
index 508e221..90ab2b5 100644
--- a/src/codegen.cc
+++ b/src/codegen.cc
@@ -171,7 +171,8 @@
 bool CodeGenerator::ShouldGenerateLog(Expression* type) {
   ASSERT(type != NULL);
   Isolate* isolate = Isolate::Current();
-  if (!isolate->logger()->is_logging() && !CpuProfiler::is_profiling(isolate)) {
+  if (!isolate->logger()->is_logging() &&
+      !isolate->cpu_profiler()->is_profiling()) {
     return false;
   }
   Handle<String> name = Handle<String>::cast(type->AsLiteral()->handle());
diff --git a/src/compiler.cc b/src/compiler.cc
index 21ea25f..2c4dae5 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -1134,7 +1134,7 @@
   // script name and line number. Check explicitly whether logging is
   // enabled as finding the line number is not free.
   if (info->isolate()->logger()->is_logging_code_events() ||
-      CpuProfiler::is_profiling(info->isolate())) {
+      info->isolate()->cpu_profiler()->is_profiling()) {
     Handle<Script> script = info->script();
     Handle<Code> code = info->code();
     if (*code == info->isolate()->builtins()->builtin(Builtins::kLazyCompile))
diff --git a/src/cpu-profiler.cc b/src/cpu-profiler.cc
index 15edc1e..7979eb4 100644
--- a/src/cpu-profiler.cc
+++ b/src/cpu-profiler.cc
@@ -258,109 +258,66 @@
 }
 
 
-void CpuProfiler::StartProfiling(const char* title) {
-  ASSERT(Isolate::Current()->cpu_profiler() != NULL);
-  Isolate::Current()->cpu_profiler()->StartCollectingProfile(title);
-}
-
-
-void CpuProfiler::StartProfiling(String* title) {
-  ASSERT(Isolate::Current()->cpu_profiler() != NULL);
-  Isolate::Current()->cpu_profiler()->StartCollectingProfile(title);
-}
-
-
-CpuProfile* CpuProfiler::StopProfiling(const char* title) {
-  Isolate* isolate = Isolate::Current();
-  return is_profiling(isolate) ?
-      isolate->cpu_profiler()->StopCollectingProfile(title) : NULL;
-}
-
-
-CpuProfile* CpuProfiler::StopProfiling(Object* security_token, String* title) {
-  Isolate* isolate = Isolate::Current();
-  return is_profiling(isolate) ?
-      isolate->cpu_profiler()->StopCollectingProfile(
-          security_token, title) : NULL;
-}
-
-
 int CpuProfiler::GetProfilesCount() {
-  ASSERT(Isolate::Current()->cpu_profiler() != NULL);
   // The count of profiles doesn't depend on a security token.
-  return Isolate::Current()->cpu_profiler()->profiles_->Profiles(
-      TokenEnumerator::kNoSecurityToken)->length();
+  return profiles_->Profiles(TokenEnumerator::kNoSecurityToken)->length();
 }
 
 
 CpuProfile* CpuProfiler::GetProfile(Object* security_token, int index) {
-  ASSERT(Isolate::Current()->cpu_profiler() != NULL);
-  CpuProfiler* profiler = Isolate::Current()->cpu_profiler();
-  const int token = profiler->token_enumerator_->GetTokenId(security_token);
-  return profiler->profiles_->Profiles(token)->at(index);
+  const int token = token_enumerator_->GetTokenId(security_token);
+  return profiles_->Profiles(token)->at(index);
 }
 
 
 CpuProfile* CpuProfiler::FindProfile(Object* security_token, unsigned uid) {
-  ASSERT(Isolate::Current()->cpu_profiler() != NULL);
-  CpuProfiler* profiler = Isolate::Current()->cpu_profiler();
-  const int token = profiler->token_enumerator_->GetTokenId(security_token);
-  return profiler->profiles_->GetProfile(token, uid);
+  const int token = token_enumerator_->GetTokenId(security_token);
+  return profiles_->GetProfile(token, uid);
 }
 
 
-TickSample* CpuProfiler::TickSampleEvent(Isolate* isolate) {
-  if (CpuProfiler::is_profiling(isolate)) {
-    return isolate->cpu_profiler()->processor_->TickSampleEvent();
-  } else {
-    return NULL;
-  }
+TickSample* CpuProfiler::TickSampleEvent() {
+  if (is_profiling_) return processor_->TickSampleEvent();
+  return NULL;
 }
 
 
 void CpuProfiler::DeleteAllProfiles() {
-  Isolate* isolate = Isolate::Current();
-  ASSERT(isolate->cpu_profiler() != NULL);
-  if (is_profiling(isolate)) {
-    isolate->cpu_profiler()->StopProcessor();
-  }
-  isolate->cpu_profiler()->ResetProfiles();
+  if (is_profiling_) StopProcessor();
+  ResetProfiles();
 }
 
 
 void CpuProfiler::DeleteProfile(CpuProfile* profile) {
-  ASSERT(Isolate::Current()->cpu_profiler() != NULL);
-  Isolate::Current()->cpu_profiler()->profiles_->RemoveProfile(profile);
+  profiles_->RemoveProfile(profile);
   delete profile;
 }
 
 
 bool CpuProfiler::HasDetachedProfiles() {
-  ASSERT(Isolate::Current()->cpu_profiler() != NULL);
-  return Isolate::Current()->cpu_profiler()->profiles_->HasDetachedProfiles();
+  return profiles_->HasDetachedProfiles();
 }
 
 
 void CpuProfiler::CallbackEvent(Name* name, Address entry_point) {
-  Isolate::Current()->cpu_profiler()->processor_->CallbackCreateEvent(
+  processor_->CallbackCreateEvent(
       Logger::CALLBACK_TAG, CodeEntry::kEmptyNamePrefix, name, entry_point);
 }
 
 
 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
                            Code* code, const char* comment) {
-  Isolate::Current()->cpu_profiler()->processor_->CodeCreateEvent(
+  processor_->CodeCreateEvent(
       tag, comment, code->address(), code->ExecutableSize());
 }
 
 
 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
                            Code* code, Name* name) {
-  Isolate* isolate = Isolate::Current();
-  isolate->cpu_profiler()->processor_->CodeCreateEvent(
+  processor_->CodeCreateEvent(
       tag,
       name,
-      isolate->heap()->empty_string(),
+      isolate_->heap()->empty_string(),
       v8::CpuProfileNode::kNoLineNumberInfo,
       code->address(),
       code->ExecutableSize(),
@@ -372,11 +329,10 @@
                                   Code* code,
                                   SharedFunctionInfo* shared,
                                   Name* name) {
-  Isolate* isolate = Isolate::Current();
-  isolate->cpu_profiler()->processor_->CodeCreateEvent(
+  processor_->CodeCreateEvent(
       tag,
       name,
-      isolate->heap()->empty_string(),
+      isolate_->heap()->empty_string(),
       v8::CpuProfileNode::kNoLineNumberInfo,
       code->address(),
       code->ExecutableSize(),
@@ -388,7 +344,7 @@
                                   Code* code,
                                   SharedFunctionInfo* shared,
                                   String* source, int line) {
-  Isolate::Current()->cpu_profiler()->processor_->CodeCreateEvent(
+  processor_->CodeCreateEvent(
       tag,
       shared->DebugName(),
       source,
@@ -401,7 +357,7 @@
 
 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
                            Code* code, int args_count) {
-  Isolate::Current()->cpu_profiler()->processor_->CodeCreateEvent(
+  processor_->CodeCreateEvent(
       tag,
       args_count,
       code->address(),
@@ -410,7 +366,7 @@
 
 
 void CpuProfiler::CodeMoveEvent(Address from, Address to) {
-  Isolate::Current()->cpu_profiler()->processor_->CodeMoveEvent(from, to);
+  processor_->CodeMoveEvent(from, to);
 }
 
 
@@ -419,19 +375,18 @@
 
 
 void CpuProfiler::SharedFunctionInfoMoveEvent(Address from, Address to) {
-  CpuProfiler* profiler = Isolate::Current()->cpu_profiler();
-  profiler->processor_->SharedFunctionInfoMoveEvent(from, to);
+  processor_->SharedFunctionInfoMoveEvent(from, to);
 }
 
 
 void CpuProfiler::GetterCallbackEvent(Name* name, Address entry_point) {
-  Isolate::Current()->cpu_profiler()->processor_->CallbackCreateEvent(
+  processor_->CallbackCreateEvent(
       Logger::CALLBACK_TAG, "get ", name, entry_point);
 }
 
 
 void CpuProfiler::RegExpCodeCreateEvent(Code* code, String* source) {
-  Isolate::Current()->cpu_profiler()->processor_->RegExpCodeCreateEvent(
+  processor_->RegExpCodeCreateEvent(
       Logger::REG_EXP_TAG,
       "RegExp: ",
       source,
@@ -441,13 +396,14 @@
 
 
 void CpuProfiler::SetterCallbackEvent(Name* name, Address entry_point) {
-  Isolate::Current()->cpu_profiler()->processor_->CallbackCreateEvent(
+  processor_->CallbackCreateEvent(
       Logger::CALLBACK_TAG, "set ", name, entry_point);
 }
 
 
-CpuProfiler::CpuProfiler()
-    : profiles_(new CpuProfilesCollection()),
+CpuProfiler::CpuProfiler(Isolate* isolate)
+    : isolate_(isolate),
+      profiles_(new CpuProfilesCollection()),
       next_profile_uid_(1),
       token_enumerator_(new TokenEnumerator()),
       generator_(NULL),
@@ -468,43 +424,41 @@
   profiles_ = new CpuProfilesCollection();
 }
 
-void CpuProfiler::StartCollectingProfile(const char* title) {
-  if (profiles_->StartProfiling(title, next_profile_uid_++)) {
+void CpuProfiler::StartProfiling(const char* title, bool record_samples) {
+  if (profiles_->StartProfiling(title, next_profile_uid_++, record_samples)) {
     StartProcessorIfNotStarted();
   }
   processor_->AddCurrentStack();
 }
 
 
-void CpuProfiler::StartCollectingProfile(String* title) {
-  StartCollectingProfile(profiles_->GetName(title));
+void CpuProfiler::StartProfiling(String* title, bool record_samples) {
+  StartProfiling(profiles_->GetName(title), record_samples);
 }
 
 
 void CpuProfiler::StartProcessorIfNotStarted() {
   if (processor_ == NULL) {
-    Isolate* isolate = Isolate::Current();
-
     // Disable logging when using the new implementation.
-    saved_logging_nesting_ = isolate->logger()->logging_nesting_;
-    isolate->logger()->logging_nesting_ = 0;
+    saved_logging_nesting_ = isolate_->logger()->logging_nesting_;
+    isolate_->logger()->logging_nesting_ = 0;
     generator_ = new ProfileGenerator(profiles_);
     processor_ = new ProfilerEventsProcessor(generator_);
     is_profiling_ = true;
     processor_->Start();
     // Enumerate stuff we already have in the heap.
-    if (isolate->heap()->HasBeenSetUp()) {
+    if (isolate_->heap()->HasBeenSetUp()) {
       if (!FLAG_prof_browser_mode) {
         bool saved_log_code_flag = FLAG_log_code;
         FLAG_log_code = true;
-        isolate->logger()->LogCodeObjects();
+        isolate_->logger()->LogCodeObjects();
         FLAG_log_code = saved_log_code_flag;
       }
-      isolate->logger()->LogCompiledFunctions();
-      isolate->logger()->LogAccessorCallbacks();
+      isolate_->logger()->LogCompiledFunctions();
+      isolate_->logger()->LogAccessorCallbacks();
     }
     // Enable stack sampling.
-    Sampler* sampler = reinterpret_cast<Sampler*>(isolate->logger()->ticker_);
+    Sampler* sampler = reinterpret_cast<Sampler*>(isolate_->logger()->ticker_);
     if (!sampler->IsActive()) {
       sampler->Start();
       need_to_stop_sampler_ = true;
@@ -514,7 +468,8 @@
 }
 
 
-CpuProfile* CpuProfiler::StopCollectingProfile(const char* title) {
+CpuProfile* CpuProfiler::StopProfiling(const char* title) {
+  if (!is_profiling_) return NULL;
   const double actual_sampling_rate = generator_->actual_sampling_rate();
   StopProcessorIfLastProfile(title);
   CpuProfile* result =
@@ -528,8 +483,8 @@
 }
 
 
-CpuProfile* CpuProfiler::StopCollectingProfile(Object* security_token,
-                                               String* title) {
+CpuProfile* CpuProfiler::StopProfiling(Object* security_token, String* title) {
+  if (!is_profiling_) return NULL;
   const double actual_sampling_rate = generator_->actual_sampling_rate();
   const char* profile_title = profiles_->GetName(title);
   StopProcessorIfLastProfile(profile_title);
@@ -544,7 +499,7 @@
 
 
 void CpuProfiler::StopProcessor() {
-  Logger* logger = Isolate::Current()->logger();
+  Logger* logger = isolate_->logger();
   Sampler* sampler = reinterpret_cast<Sampler*>(logger->ticker_);
   sampler->DecreaseProfilingDepth();
   if (need_to_stop_sampler_) {
@@ -562,20 +517,4 @@
 }
 
 
-void CpuProfiler::SetUp() {
-  Isolate* isolate = Isolate::Current();
-  if (isolate->cpu_profiler() == NULL) {
-    isolate->set_cpu_profiler(new CpuProfiler());
-  }
-}
-
-
-void CpuProfiler::TearDown() {
-  Isolate* isolate = Isolate::Current();
-  if (isolate->cpu_profiler() != NULL) {
-    delete isolate->cpu_profiler();
-  }
-  isolate->set_cpu_profiler(NULL);
-}
-
 } }  // namespace v8::internal
diff --git a/src/cpu-profiler.h b/src/cpu-profiler.h
index 3dc766b..89d9c81 100644
--- a/src/cpu-profiler.h
+++ b/src/cpu-profiler.h
@@ -184,84 +184,71 @@
   unsigned enqueue_order_;
 };
 
-} }  // namespace v8::internal
 
-
-#define PROFILE(isolate, Call)                                \
-  LOG_CODE_EVENT(isolate, Call);                              \
-  do {                                                        \
-    if (v8::internal::CpuProfiler::is_profiling(isolate)) {   \
-      v8::internal::CpuProfiler::Call;                        \
-    }                                                         \
+#define PROFILE(IsolateGetter, Call)                                   \
+  do {                                                                 \
+    Isolate* cpu_profiler_isolate = (IsolateGetter);                   \
+    LOG_CODE_EVENT(cpu_profiler_isolate, Call);                        \
+    CpuProfiler* cpu_profiler = cpu_profiler_isolate->cpu_profiler();  \
+    if (cpu_profiler->is_profiling()) {                                \
+      cpu_profiler->Call;                                              \
+    }                                                                  \
   } while (false)
 
 
-namespace v8 {
-namespace internal {
-
-
-// TODO(isolates): isolatify this class.
 class CpuProfiler {
  public:
-  static void SetUp();
-  static void TearDown();
+  explicit CpuProfiler(Isolate* isolate);
+  ~CpuProfiler();
 
-  static void StartProfiling(const char* title);
-  static void StartProfiling(String* title);
-  static CpuProfile* StopProfiling(const char* title);
-  static CpuProfile* StopProfiling(Object* security_token, String* title);
-  static int GetProfilesCount();
-  static CpuProfile* GetProfile(Object* security_token, int index);
-  static CpuProfile* FindProfile(Object* security_token, unsigned uid);
-  static void DeleteAllProfiles();
-  static void DeleteProfile(CpuProfile* profile);
-  static bool HasDetachedProfiles();
+  void StartProfiling(const char* title, bool record_samples = false);
+  void StartProfiling(String* title, bool record_samples);
+  CpuProfile* StopProfiling(const char* title);
+  CpuProfile* StopProfiling(Object* security_token, String* title);
+  int GetProfilesCount();
+  CpuProfile* GetProfile(Object* security_token, int index);
+  CpuProfile* FindProfile(Object* security_token, unsigned uid);
+  void DeleteAllProfiles();
+  void DeleteProfile(CpuProfile* profile);
+  bool HasDetachedProfiles();
 
   // Invoked from stack sampler (thread or signal handler.)
-  static TickSample* TickSampleEvent(Isolate* isolate);
+  TickSample* TickSampleEvent();
 
   // Must be called via PROFILE macro, otherwise will crash when
   // profiling is not enabled.
-  static void CallbackEvent(Name* name, Address entry_point);
-  static void CodeCreateEvent(Logger::LogEventsAndTags tag,
-                              Code* code, const char* comment);
-  static void CodeCreateEvent(Logger::LogEventsAndTags tag,
-                              Code* code, Name* name);
-  static void CodeCreateEvent(Logger::LogEventsAndTags tag,
-                              Code* code,
+  void CallbackEvent(Name* name, Address entry_point);
+  void CodeCreateEvent(Logger::LogEventsAndTags tag,
+                       Code* code, const char* comment);
+  void CodeCreateEvent(Logger::LogEventsAndTags tag,
+                       Code* code, Name* name);
+  void CodeCreateEvent(Logger::LogEventsAndTags tag,
+                       Code* code,
                               SharedFunctionInfo* shared,
                               Name* name);
-  static void CodeCreateEvent(Logger::LogEventsAndTags tag,
-                              Code* code,
-                              SharedFunctionInfo* shared,
-                              String* source, int line);
-  static void CodeCreateEvent(Logger::LogEventsAndTags tag,
-                              Code* code, int args_count);
-  static void CodeMovingGCEvent() {}
-  static void CodeMoveEvent(Address from, Address to);
-  static void CodeDeleteEvent(Address from);
-  static void GetterCallbackEvent(Name* name, Address entry_point);
-  static void RegExpCodeCreateEvent(Code* code, String* source);
-  static void SetterCallbackEvent(Name* name, Address entry_point);
-  static void SharedFunctionInfoMoveEvent(Address from, Address to);
+  void CodeCreateEvent(Logger::LogEventsAndTags tag,
+                       Code* code,
+                       SharedFunctionInfo* shared,
+                       String* source, int line);
+  void CodeCreateEvent(Logger::LogEventsAndTags tag,
+                       Code* code, int args_count);
+  void CodeMovingGCEvent() {}
+  void CodeMoveEvent(Address from, Address to);
+  void CodeDeleteEvent(Address from);
+  void GetterCallbackEvent(Name* name, Address entry_point);
+  void RegExpCodeCreateEvent(Code* code, String* source);
+  void SetterCallbackEvent(Name* name, Address entry_point);
+  void SharedFunctionInfoMoveEvent(Address from, Address to);
 
-  static INLINE(bool is_profiling(Isolate* isolate)) {
-    CpuProfiler* profiler = isolate->cpu_profiler();
-    return profiler != NULL && profiler->is_profiling_;
-  }
+  INLINE(bool is_profiling() const) { return is_profiling_; }
 
  private:
-  CpuProfiler();
-  ~CpuProfiler();
-  void StartCollectingProfile(const char* title);
-  void StartCollectingProfile(String* title);
   void StartProcessorIfNotStarted();
-  CpuProfile* StopCollectingProfile(const char* title);
-  CpuProfile* StopCollectingProfile(Object* security_token, String* title);
   void StopProcessorIfLastProfile(const char* title);
   void StopProcessor();
   void ResetProfiles();
 
+  Isolate* isolate_;
   CpuProfilesCollection* profiles_;
   unsigned next_profile_uid_;
   TokenEnumerator* token_enumerator_;
diff --git a/src/d8.cc b/src/d8.cc
index 00b23fb..805a0cf 100644
--- a/src/d8.cc
+++ b/src/d8.cc
@@ -215,7 +215,9 @@
     } else {
       ASSERT(!try_catch.HasCaught());
       if (print_result) {
+#if !defined(V8_SHARED)
         if (options.test_shell) {
+#endif
           if (!result->IsUndefined()) {
             // If all went well and the result wasn't undefined then print
             // the returned value.
@@ -223,6 +225,7 @@
             fwrite(*str, sizeof(**str), str.length(), stdout);
             printf("\n");
           }
+#if !defined(V8_SHARED)
         } else {
           Context::Scope context_scope(utility_context_);
           Handle<Object> global = utility_context_->Global();
@@ -233,6 +236,7 @@
           fwrite(*str, sizeof(**str), str.length(), stdout);
           printf("\n");
         }
+#endif
       }
       return true;
     }
diff --git a/src/global-handles.cc b/src/global-handles.cc
index a6347bb..14c00f1 100644
--- a/src/global-handles.cc
+++ b/src/global-handles.cc
@@ -83,7 +83,6 @@
     set_partially_dependent(false);
     set_in_new_space_list(false);
     parameter_or_next_free_.next_free = NULL;
-    weak_reference_callback_ = NULL;
     near_death_callback_ = NULL;
   }
 #endif
@@ -105,7 +104,6 @@
     set_partially_dependent(false);
     set_state(NORMAL);
     parameter_or_next_free_.parameter = NULL;
-    weak_reference_callback_ = NULL;
     near_death_callback_ = NULL;
     IncreaseBlockUses(global_handles);
   }
@@ -120,7 +118,6 @@
     class_id_ = v8::HeapProfiler::kPersistentHandleNoClassId;
     set_independent(false);
     set_partially_dependent(false);
-    weak_reference_callback_ = NULL;
     near_death_callback_ = NULL;
 #endif
     parameter_or_next_free_.next_free = global_handles->first_free_;
@@ -235,8 +232,14 @@
     ASSERT(state() != FREE);
     set_state(WEAK);
     set_parameter(parameter);
-    weak_reference_callback_ = weak_reference_callback;
-    near_death_callback_ = near_death_callback;
+    if (weak_reference_callback != NULL) {
+      flags_ = IsWeakCallback::update(flags_, true);
+      near_death_callback_ =
+          reinterpret_cast<NearDeathCallback>(weak_reference_callback);
+    } else {
+      flags_ = IsWeakCallback::update(flags_, false);
+      near_death_callback_ = near_death_callback;
+    }
   }
 
   void ClearWeakness(GlobalHandles* global_handles) {
@@ -248,8 +251,7 @@
   bool PostGarbageCollectionProcessing(Isolate* isolate,
                                        GlobalHandles* global_handles) {
     if (state() != Node::PENDING) return false;
-    if (weak_reference_callback_ == NULL &&
-        near_death_callback_ == NULL) {
+    if (near_death_callback_ == NULL) {
       Release(global_handles);
       return false;
     }
@@ -267,13 +269,16 @@
              ExternalTwoByteString::cast(object_)->resource() != NULL);
       // Leaving V8.
       VMState state(isolate, EXTERNAL);
-      if (weak_reference_callback_ != NULL) {
-        weak_reference_callback_(object, par);
-      }
       if (near_death_callback_ != NULL) {
-        near_death_callback_(reinterpret_cast<v8::Isolate*>(isolate),
-                             object,
-                             par);
+        if (IsWeakCallback::decode(flags_)) {
+          WeakReferenceCallback callback =
+              reinterpret_cast<WeakReferenceCallback>(near_death_callback_);
+          callback(object, par);
+        } else {
+          near_death_callback_(reinterpret_cast<v8::Isolate*>(isolate),
+                               object,
+                               par);
+        }
       }
     }
     // Absence of explicit cleanup or revival of weak handle
@@ -306,11 +311,11 @@
   class IsIndependent:        public BitField<bool,  4, 1> {};
   class IsPartiallyDependent: public BitField<bool,  5, 1> {};
   class IsInNewSpaceList:     public BitField<bool,  6, 1> {};
+  class IsWeakCallback:       public BitField<bool,  7, 1> {};
 
   uint8_t flags_;
 
-  // Handle specific callback.
-  WeakReferenceCallback weak_reference_callback_;
+  // Handle specific callback - might be a weak reference in disguise.
   NearDeathCallback near_death_callback_;
 
   // Provided data for callback.  In FREE state, this is used for
@@ -481,8 +486,7 @@
                              void* parameter,
                              WeakReferenceCallback weak_reference_callback,
                              NearDeathCallback near_death_callback) {
-  ASSERT((weak_reference_callback != NULL) !=
-         (near_death_callback != NULL));
+  ASSERT(near_death_callback != NULL);
   Node::FromLocation(location)->MakeWeak(this,
                                          parameter,
                                          weak_reference_callback,
diff --git a/src/heap.cc b/src/heap.cc
index 67759e6..3cf23d0 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -1854,7 +1854,7 @@
       HEAP_PROFILE(heap, ObjectMoveEvent(source->address(), target->address()));
       Isolate* isolate = heap->isolate();
       if (isolate->logger()->is_logging_code_events() ||
-          CpuProfiler::is_profiling(isolate)) {
+          isolate->cpu_profiler()->is_profiling()) {
         if (target->IsSharedFunctionInfo()) {
           PROFILE(isolate, SharedFunctionInfoMoveEvent(
               source->address(), target->address()));
@@ -2110,7 +2110,7 @@
 void Heap::SelectScavengingVisitorsTable() {
   bool logging_and_profiling =
       isolate()->logger()->is_logging() ||
-      CpuProfiler::is_profiling(isolate()) ||
+      isolate()->cpu_profiler()->is_profiling() ||
       (isolate()->heap_profiler() != NULL &&
        isolate()->heap_profiler()->is_profiling());
 
@@ -3805,6 +3805,8 @@
   }
   // Allow self references to created code object by patching the handle to
   // point to the newly allocated Code object.
+  CHECK(code->IsCode());
+  CHECK(code->relocation_info()->IsByteArray());
   if (!self_reference.is_null()) {
     *(self_reference.location()) = code;
   }
@@ -3813,6 +3815,8 @@
   // that are dereferenced during the copy to point directly to the actual heap
   // objects. These pointers can include references to the code object itself,
   // through the self_reference parameter.
+  CHECK(code->IsCode());
+  CHECK(code->relocation_info()->IsByteArray());
   code->CopyFrom(desc);
 
 #ifdef VERIFY_HEAP
diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc
index 2aab369..fc80748 100644
--- a/src/hydrogen-instructions.cc
+++ b/src/hydrogen-instructions.cc
@@ -174,7 +174,7 @@
                             int offset,
                             int scale) {
   if (this == other) {
-    return NumericRelation::Eq().Implies(relation);
+    return scale == 0 && relation.IsExtendable(offset);
   }
 
   // Test the direct relation.
diff --git a/src/isolate.cc b/src/isolate.cc
index 632ecdc..5d4bc89 100644
--- a/src/isolate.cc
+++ b/src/isolate.cc
@@ -1678,6 +1678,7 @@
       date_cache_(NULL),
       code_stub_interface_descriptors_(NULL),
       context_exit_happened_(false),
+      cpu_profiler_(NULL),
       deferred_handles_head_(NULL),
       optimizing_compiler_thread_(this),
       marking_thread_(NULL),
@@ -1810,7 +1811,9 @@
     PreallocatedMemoryThreadStop();
 
     HeapProfiler::TearDown();
-    CpuProfiler::TearDown();
+    delete cpu_profiler_;
+    cpu_profiler_ = NULL;
+
     if (runtime_profiler_ != NULL) {
       runtime_profiler_->TearDown();
       delete runtime_profiler_;
@@ -2039,7 +2042,7 @@
   // Enable logging before setting up the heap
   logger_->SetUp();
 
-  CpuProfiler::SetUp();
+  cpu_profiler_ = new CpuProfiler(this);
   HeapProfiler::SetUp();
 
   // Initialize other runtime facilities
diff --git a/src/isolate.h b/src/isolate.h
index d6770cc..ad0b260 100644
--- a/src/isolate.h
+++ b/src/isolate.h
@@ -357,9 +357,6 @@
   V(FunctionInfoListener*, active_function_info_listener, NULL)                \
   /* State for Relocatable. */                                                 \
   V(Relocatable*, relocatable_top, NULL)                                       \
-  /* State for CodeEntry in profile-generator. */                              \
-  V(CodeGenerator*, current_code_generator, NULL)                              \
-  V(bool, jump_target_compiling_deferred_code, false)                          \
   V(DebugObjectCache*, string_stream_debug_object_cache, NULL)                 \
   V(Object*, string_stream_current_security_token, NULL)                       \
   /* TODO(isolates): Release this on destruction? */                           \
@@ -371,7 +368,6 @@
   V(unsigned, ast_node_count, 0)                                               \
   /* SafeStackFrameIterator activations count. */                              \
   V(int, safe_stack_iterator_counter, 0)                                       \
-  V(CpuProfiler*, cpu_profiler, NULL)                                          \
   V(HeapProfiler*, heap_profiler, NULL)                                        \
   V(bool, observer_delivery_pending, false)                                    \
   V(HStatistics*, hstatistics, NULL)                                           \
@@ -979,6 +975,8 @@
   inline bool IsDebuggerActive();
   inline bool DebuggerHasBreakPoints();
 
+  CpuProfiler* cpu_profiler() const { return cpu_profiler_; }
+
 #ifdef DEBUG
   HistogramInfo* heap_histograms() { return heap_histograms_; }
 
@@ -1314,6 +1312,7 @@
   Debugger* debugger_;
   Debug* debug_;
 #endif
+  CpuProfiler* cpu_profiler_;
 
 #define GLOBAL_BACKING_STORE(type, name, initialvalue)                         \
   type name##_;
diff --git a/src/log.cc b/src/log.cc
index 4ec981c..e9ef382 100644
--- a/src/log.cc
+++ b/src/log.cc
@@ -1615,7 +1615,7 @@
         tag = Logger::KEYED_CALL_IC_TAG;
         break;
     }
-    PROFILE(ISOLATE, CodeCreateEvent(tag, code_object, description));
+    PROFILE(isolate_, CodeCreateEvent(tag, code_object, description));
   }
 }
 
@@ -1719,20 +1719,20 @@
       Handle<String> script_name(String::cast(script->name()));
       int line_num = GetScriptLineNumber(script, shared->start_position());
       if (line_num > 0) {
-        PROFILE(ISOLATE,
+        PROFILE(isolate_,
                 CodeCreateEvent(
                     Logger::ToNativeByScript(Logger::LAZY_COMPILE_TAG, *script),
                     *code, *shared,
                     *script_name, line_num + 1));
       } else {
         // Can't distinguish eval and script here, so always use Script.
-        PROFILE(ISOLATE,
+        PROFILE(isolate_,
                 CodeCreateEvent(
                     Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script),
                     *code, *shared, *script_name));
       }
     } else {
-      PROFILE(ISOLATE,
+      PROFILE(isolate_,
               CodeCreateEvent(
                   Logger::ToNativeByScript(Logger::LAZY_COMPILE_TAG, *script),
                   *code, *shared, *func_name));
@@ -1745,10 +1745,10 @@
       CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data);
       Object* callback_obj = call_data->callback();
       Address entry_point = v8::ToCData<Address>(callback_obj);
-      PROFILE(ISOLATE, CallbackEvent(*func_name, entry_point));
+      PROFILE(isolate_, CallbackEvent(*func_name, entry_point));
     }
   } else {
-    PROFILE(ISOLATE,
+    PROFILE(isolate_,
             CodeCreateEvent(
                 Logger::LAZY_COMPILE_TAG, *code, *shared, *func_name));
   }
@@ -1789,11 +1789,11 @@
     Address getter_entry = v8::ToCData<Address>(ai->getter());
     Name* name = Name::cast(ai->name());
     if (getter_entry != 0) {
-      PROFILE(ISOLATE, GetterCallbackEvent(name, getter_entry));
+      PROFILE(isolate_, GetterCallbackEvent(name, getter_entry));
     }
     Address setter_entry = v8::ToCData<Address>(ai->setter());
     if (setter_entry != 0) {
-      PROFILE(ISOLATE, SetterCallbackEvent(name, setter_entry));
+      PROFILE(isolate_, SetterCallbackEvent(name, setter_entry));
     }
   }
 }
diff --git a/src/mips/builtins-mips.cc b/src/mips/builtins-mips.cc
index 2facd13..54efd94 100644
--- a/src/mips/builtins-mips.cc
+++ b/src/mips/builtins-mips.cc
@@ -128,12 +128,8 @@
   if (initial_capacity > 0) {
     size += FixedArray::SizeFor(initial_capacity);
   }
-  __ AllocateInNewSpace(size,
-                        result,
-                        scratch2,
-                        scratch3,
-                        gc_required,
-                        TAG_OBJECT);
+  __ Allocate(size, result, scratch2, scratch3, gc_required, TAG_OBJECT);
+
   // Allocated the JSArray. Now initialize the fields except for the elements
   // array.
   // result: JSObject
@@ -665,12 +661,12 @@
   // -----------------------------------
 
   Label gc_required;
-  __ AllocateInNewSpace(JSValue::kSize,
-                        v0,  // Result.
-                        a3,  // Scratch.
-                        t0,  // Scratch.
-                        &gc_required,
-                        TAG_OBJECT);
+  __ Allocate(JSValue::kSize,
+              v0,  // Result.
+              a3,  // Scratch.
+              t0,  // Scratch.
+              &gc_required,
+              TAG_OBJECT);
 
   // Initialising the String Object.
   Register map = a3;
diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc
index f398a4d..f5908d3 100644
--- a/src/mips/code-stubs-mips.cc
+++ b/src/mips/code-stubs-mips.cc
@@ -168,12 +168,7 @@
   __ pop(a3);
 
   // Attempt to allocate new JSFunction in new space.
-  __ AllocateInNewSpace(JSFunction::kSize,
-                        v0,
-                        a1,
-                        a2,
-                        &gc,
-                        TAG_OBJECT);
+  __ Allocate(JSFunction::kSize, v0, a1, a2, &gc, TAG_OBJECT);
 
   __ IncrementCounter(counters->fast_new_closure_total(), 1, t2, t3);
 
@@ -300,12 +295,7 @@
   int length = slots_ + Context::MIN_CONTEXT_SLOTS;
 
   // Attempt to allocate the context in new space.
-  __ AllocateInNewSpace(FixedArray::SizeFor(length),
-                        v0,
-                        a1,
-                        a2,
-                        &gc,
-                        TAG_OBJECT);
+  __ Allocate(FixedArray::SizeFor(length), v0, a1, a2, &gc, TAG_OBJECT);
 
   // Load the function from the stack.
   __ lw(a3, MemOperand(sp, 0));
@@ -349,8 +339,7 @@
   // Try to allocate the context in new space.
   Label gc;
   int length = slots_ + Context::MIN_CONTEXT_SLOTS;
-  __ AllocateInNewSpace(FixedArray::SizeFor(length),
-                        v0, a1, a2, &gc, TAG_OBJECT);
+  __ Allocate(FixedArray::SizeFor(length), v0, a1, a2, &gc, TAG_OBJECT);
 
   // Load the function from the stack.
   __ lw(a3, MemOperand(sp, 0));
@@ -429,12 +418,7 @@
 
   // Allocate both the JS array and the elements array in one big
   // allocation. This avoids multiple limit checks.
-  __ AllocateInNewSpace(size,
-                        v0,
-                        a1,
-                        a2,
-                        fail,
-                        TAG_OBJECT);
+  __ Allocate(size, v0, a1, a2, fail, TAG_OBJECT);
 
   if (allocation_site_mode == TRACK_ALLOCATION_SITE) {
     __ li(a2, Operand(Handle<Map>(masm->isolate()->heap()->
diff --git a/src/mips/full-codegen-mips.cc b/src/mips/full-codegen-mips.cc
index 056e2ee..bacec10 100644
--- a/src/mips/full-codegen-mips.cc
+++ b/src/mips/full-codegen-mips.cc
@@ -1553,7 +1553,7 @@
   __ bind(&materialized);
   int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize;
   Label allocated, runtime_allocate;
-  __ AllocateInNewSpace(size, v0, a2, a3, &runtime_allocate, TAG_OBJECT);
+  __ Allocate(size, v0, a2, a3, &runtime_allocate, TAG_OBJECT);
   __ jmp(&allocated);
 
   __ bind(&runtime_allocate);
diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc
index a16f5ed..cd48934 100644
--- a/src/mips/lithium-codegen-mips.cc
+++ b/src/mips/lithium-codegen-mips.cc
@@ -4005,6 +4005,13 @@
 }
 
 
+void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) {
+  Register result = ToRegister(instr->result());
+  Register base = ToRegister(instr->base_object());
+  __ Addu(result, base, Operand(instr->offset()));
+}
+
+
 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
   Register object = ToRegister(instr->object());
   Register value = ToRegister(instr->value());
@@ -5255,12 +5262,8 @@
   // the constructor's prototype changes, but instance size and property
   // counts remain unchanged (if slack tracking finished).
   ASSERT(!constructor->shared()->IsInobjectSlackTrackingInProgress());
-  __ AllocateInNewSpace(instance_size,
-                        result,
-                        scratch,
-                        scratch2,
-                        deferred->entry(),
-                        TAG_OBJECT);
+  __ Allocate(instance_size, result, scratch, scratch2, deferred->entry(),
+              TAG_OBJECT);
 
   __ bind(deferred->exit());
   if (FLAG_debug_code) {
@@ -5335,12 +5338,10 @@
   }
   if (instr->size()->IsConstantOperand()) {
     int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
-    __ AllocateInNewSpace(size,
-                          result,
-                          scratch,
-                          scratch2,
-                          deferred->entry(),
-                          flags);
+    if (instr->hydrogen()->CanAllocateInOldPointerSpace()) {
+      flags = static_cast<AllocationFlags>(flags | PRETENURE_OLD_POINTER_SPACE);
+    }
+    __ Allocate(size, result, scratch, scratch2, deferred->entry(), flags);
   } else {
     Register size = ToRegister(instr->size());
     __ AllocateInNewSpace(size,
@@ -5575,7 +5576,7 @@
   // Allocate all objects that are part of the literal in one big
   // allocation. This avoids multiple limit checks.
   Label allocated, runtime_allocate;
-  __ AllocateInNewSpace(size, v0, a2, a3, &runtime_allocate, TAG_OBJECT);
+  __ Allocate(size, v0, a2, a3, &runtime_allocate, TAG_OBJECT);
   __ jmp(&allocated);
 
   __ bind(&runtime_allocate);
@@ -5658,7 +5659,7 @@
   int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize;
   Label allocated, runtime_allocate;
 
-  __ AllocateInNewSpace(size, v0, a2, a3, &runtime_allocate, TAG_OBJECT);
+  __ Allocate(size, v0, a2, a3, &runtime_allocate, TAG_OBJECT);
   __ jmp(&allocated);
 
   __ bind(&runtime_allocate);
diff --git a/src/mips/lithium-mips.cc b/src/mips/lithium-mips.cc
index 31d1067..8848032 100644
--- a/src/mips/lithium-mips.cc
+++ b/src/mips/lithium-mips.cc
@@ -290,6 +290,13 @@
 }
 
 
+void LInnerAllocatedObject::PrintDataTo(StringStream* stream) {
+  stream->Add(" = ");
+  base_object()->PrintTo(stream);
+  stream->Add(" + %d", offset());
+}
+
+
 void LCallConstantFunction::PrintDataTo(StringStream* stream) {
   stream->Add("#%d / ", arity());
 }
@@ -1020,6 +1027,15 @@
 }
 
 
+LInstruction* LChunkBuilder::DoInnerAllocatedObject(
+    HInnerAllocatedObject* inner_object) {
+  LOperand* base_object = UseRegisterAtStart(inner_object->base_object());
+  LInnerAllocatedObject* result =
+    new(zone()) LInnerAllocatedObject(base_object);
+  return DefineAsRegister(result);
+}
+
+
 LInstruction* LChunkBuilder::DoThisFunction(HThisFunction* instr) {
   return instr->HasNoUses()
       ? NULL
diff --git a/src/mips/lithium-mips.h b/src/mips/lithium-mips.h
index ccaad71..80635c3 100644
--- a/src/mips/lithium-mips.h
+++ b/src/mips/lithium-mips.h
@@ -188,7 +188,9 @@
   V(LoadFieldByIndex)                           \
   V(DateField)                                  \
   V(WrapReceiver)                               \
-  V(Drop)
+  V(Drop)                                       \
+  V(InnerAllocatedObject)
+
 
 #define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic)              \
   virtual Opcode opcode() const { return LInstruction::k##type; } \
@@ -1600,6 +1602,22 @@
 };
 
 
+class LInnerAllocatedObject: public LTemplateInstruction<1, 1, 0> {
+ public:
+  explicit LInnerAllocatedObject(LOperand* base_object) {
+    inputs_[0] = base_object;
+  }
+
+  LOperand* base_object() { return inputs_[0]; }
+  int offset() { return hydrogen()->offset(); }
+
+  virtual void PrintDataTo(StringStream* stream);
+
+  DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject, "sub-allocated-object")
+  DECLARE_HYDROGEN_ACCESSOR(InnerAllocatedObject)
+};
+
+
 class LThisFunction: public LTemplateInstruction<1, 0, 0> {
  public:
   DECLARE_CONCRETE_INSTRUCTION(ThisFunction, "this-function")
diff --git a/src/mips/macro-assembler-mips.cc b/src/mips/macro-assembler-mips.cc
index af436b6..603f1be 100644
--- a/src/mips/macro-assembler-mips.cc
+++ b/src/mips/macro-assembler-mips.cc
@@ -2912,12 +2912,12 @@
 }
 
 
-void MacroAssembler::AllocateInNewSpace(int object_size,
-                                        Register result,
-                                        Register scratch1,
-                                        Register scratch2,
-                                        Label* gc_required,
-                                        AllocationFlags flags) {
+void MacroAssembler::Allocate(int object_size,
+                              Register result,
+                              Register scratch1,
+                              Register scratch2,
+                              Label* gc_required,
+                              AllocationFlags flags) {
   if (!FLAG_inline_new) {
     if (emit_debug_code()) {
       // Trash the registers to simulate an allocation failure.
@@ -2945,20 +2945,21 @@
   // Check relative positions of allocation top and limit addresses.
   // ARM adds additional checks to make sure the ldm instruction can be
   // used. On MIPS we don't have ldm so we don't need additional checks either.
-  ExternalReference new_space_allocation_top =
-      ExternalReference::new_space_allocation_top_address(isolate());
-  ExternalReference new_space_allocation_limit =
-      ExternalReference::new_space_allocation_limit_address(isolate());
+  ExternalReference allocation_top =
+      AllocationUtils::GetAllocationTopReference(isolate(), flags);
+  ExternalReference allocation_limit =
+      AllocationUtils::GetAllocationLimitReference(isolate(), flags);
+
   intptr_t top   =
-      reinterpret_cast<intptr_t>(new_space_allocation_top.address());
+      reinterpret_cast<intptr_t>(allocation_top.address());
   intptr_t limit =
-      reinterpret_cast<intptr_t>(new_space_allocation_limit.address());
+      reinterpret_cast<intptr_t>(allocation_limit.address());
   ASSERT((limit - top) == kPointerSize);
 
   // Set up allocation top address and object size registers.
   Register topaddr = scratch1;
   Register obj_size_reg = scratch2;
-  li(topaddr, Operand(new_space_allocation_top));
+  li(topaddr, Operand(allocation_top));
   li(obj_size_reg, Operand(object_size));
 
   // This code stores a temporary value in t9.
@@ -2997,6 +2998,7 @@
                                         Register scratch2,
                                         Label* gc_required,
                                         AllocationFlags flags) {
+  ASSERT((flags & PRETENURE_OLD_POINTER_SPACE) == 0);
   if (!FLAG_inline_new) {
     if (emit_debug_code()) {
       // Trash the registers to simulate an allocation failure.
@@ -3159,12 +3161,8 @@
                                                Register scratch1,
                                                Register scratch2,
                                                Label* gc_required) {
-  AllocateInNewSpace(ConsString::kSize,
-                     result,
-                     scratch1,
-                     scratch2,
-                     gc_required,
-                     TAG_OBJECT);
+  Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required,
+           TAG_OBJECT);
   InitializeNewString(result,
                       length,
                       Heap::kConsStringMapRootIndex,
@@ -3178,12 +3176,8 @@
                                              Register scratch1,
                                              Register scratch2,
                                              Label* gc_required) {
-  AllocateInNewSpace(ConsString::kSize,
-                     result,
-                     scratch1,
-                     scratch2,
-                     gc_required,
-                     TAG_OBJECT);
+  Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required,
+           TAG_OBJECT);
   InitializeNewString(result,
                       length,
                       Heap::kConsAsciiStringMapRootIndex,
@@ -3197,12 +3191,8 @@
                                                  Register scratch1,
                                                  Register scratch2,
                                                  Label* gc_required) {
-  AllocateInNewSpace(SlicedString::kSize,
-                     result,
-                     scratch1,
-                     scratch2,
-                     gc_required,
-                     TAG_OBJECT);
+  Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required,
+           TAG_OBJECT);
 
   InitializeNewString(result,
                       length,
@@ -3217,12 +3207,8 @@
                                                Register scratch1,
                                                Register scratch2,
                                                Label* gc_required) {
-  AllocateInNewSpace(SlicedString::kSize,
-                     result,
-                     scratch1,
-                     scratch2,
-                     gc_required,
-                     TAG_OBJECT);
+  Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required,
+           TAG_OBJECT);
 
   InitializeNewString(result,
                       length,
@@ -3242,13 +3228,8 @@
                                         TaggingMode tagging_mode) {
   // Allocate an object in the heap for the heap number and tag it as a heap
   // object.
-  AllocateInNewSpace(HeapNumber::kSize,
-                     result,
-                     scratch1,
-                     scratch2,
-                     need_gc,
-                     tagging_mode == TAG_RESULT ? TAG_OBJECT :
-                                                  NO_ALLOCATION_FLAGS);
+  Allocate(HeapNumber::kSize, result, scratch1, scratch2, need_gc,
+           tagging_mode == TAG_RESULT ? TAG_OBJECT : NO_ALLOCATION_FLAGS);
 
   // Store heap number map in the allocated object.
   AssertRegisterIsRoot(heap_number_map, Heap::kHeapNumberMapRootIndex);
diff --git a/src/mips/macro-assembler-mips.h b/src/mips/macro-assembler-mips.h
index 563c0dd..e4cf3bc 100644
--- a/src/mips/macro-assembler-mips.h
+++ b/src/mips/macro-assembler-mips.h
@@ -477,19 +477,20 @@
   // ---------------------------------------------------------------------------
   // Allocation support.
 
-  // Allocate an object in new space. The object_size is specified
-  // either in bytes or in words if the allocation flag SIZE_IN_WORDS
-  // is passed. If the new space is exhausted control continues at the
-  // gc_required label. The allocated object is returned in result. If
-  // the flag tag_allocated_object is true the result is tagged as as
-  // a heap object. All registers are clobbered also when control
-  // continues at the gc_required label.
-  void AllocateInNewSpace(int object_size,
-                          Register result,
-                          Register scratch1,
-                          Register scratch2,
-                          Label* gc_required,
-                          AllocationFlags flags);
+  // Allocate an object in new space or old pointer space. The object_size is
+  // specified either in bytes or in words if the allocation flag SIZE_IN_WORDS
+  // is passed. If the space is exhausted control continues at the gc_required
+  // label. The allocated object is returned in result. If the flag
+  // tag_allocated_object is true the result is tagged as as a heap object.
+  // All registers are clobbered also when control continues at the gc_required
+  // label.
+  void Allocate(int object_size,
+                Register result,
+                Register scratch1,
+                Register scratch2,
+                Label* gc_required,
+                AllocationFlags flags);
+
   void AllocateInNewSpace(Register object_size,
                           Register result,
                           Register scratch1,
diff --git a/src/mips/stub-cache-mips.cc b/src/mips/stub-cache-mips.cc
index 959da8e..d5cf6de 100644
--- a/src/mips/stub-cache-mips.cc
+++ b/src/mips/stub-cache-mips.cc
@@ -2604,27 +2604,22 @@
 
 Handle<Code> StoreStubCompiler::CompileStoreCallback(
     Handle<Name> name,
-    Handle<JSObject> receiver,
+    Handle<JSObject> object,
     Handle<JSObject> holder,
     Handle<ExecutableAccessorInfo> callback) {
-  // ----------- S t a t e -------------
-  //  -- a0    : value
-  //  -- a1    : receiver
-  //  -- a2    : name
-  //  -- ra    : return address
-  // -----------------------------------
   Label miss;
   // Check that the maps haven't changed.
-  __ JumpIfSmi(a1, &miss, a3);
-  CheckPrototypes(receiver, a1, holder, a3, t0, t1, name, &miss);
+  __ JumpIfSmi(receiver(), &miss);
+  CheckPrototypes(object, receiver(), holder,
+                  scratch1(), scratch2(), scratch3(), name, &miss);
 
   // Stub never generated for non-global objects that require access
   // checks.
   ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded());
 
-  __ push(a1);  // Receiver.
-  __ li(a3, Operand(callback));  // Callback info.
-  __ Push(a3, a2, a0);
+  __ push(receiver());  // Receiver.
+  __ li(at, Operand(callback));  // Callback info.
+  __ Push(at, this->name(), value());
 
   // Do tail-call to the runtime system.
   ExternalReference store_callback_property =
@@ -2687,61 +2682,28 @@
 #define __ ACCESS_MASM(masm())
 
 
-Handle<Code> StoreStubCompiler::CompileStoreViaSetter(
-    Handle<Name> name,
-    Handle<JSObject> receiver,
-    Handle<JSObject> holder,
-    Handle<JSFunction> setter) {
-  // ----------- S t a t e -------------
-  //  -- a0    : value
-  //  -- a1    : receiver
-  //  -- a2    : name
-  //  -- ra    : return address
-  // -----------------------------------
-  Label miss;
-
-  // Check that the maps haven't changed.
-  __ JumpIfSmi(a1, &miss);
-  CheckPrototypes(receiver, a1, holder, a3, t0, t1, name, &miss);
-
-  GenerateStoreViaSetter(masm(), setter);
-
-  __ bind(&miss);
-  TailCallBuiltin(masm(), MissBuiltin(kind()));
-
-  // Return the generated code.
-  return GetICCode(kind(), Code::CALLBACKS, name);
-}
-
-
 Handle<Code> StoreStubCompiler::CompileStoreInterceptor(
-    Handle<JSObject> receiver,
+    Handle<JSObject> object,
     Handle<Name> name) {
-  // ----------- S t a t e -------------
-  //  -- a0    : value
-  //  -- a1    : receiver
-  //  -- a2    : name
-  //  -- ra    : return address
-  // -----------------------------------
   Label miss;
 
   // Check that the map of the object hasn't changed.
-  __ CheckMap(a1, a3, Handle<Map>(receiver->map()), &miss,
+  __ CheckMap(receiver(), scratch1(), Handle<Map>(object->map()), &miss,
               DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS);
 
   // Perform global security token check if needed.
-  if (receiver->IsJSGlobalProxy()) {
-    __ CheckAccessGlobalProxy(a1, a3, &miss);
+  if (object->IsJSGlobalProxy()) {
+    __ CheckAccessGlobalProxy(receiver(), scratch1(), &miss);
   }
 
   // Stub is never generated for non-global objects that require access
   // checks.
-  ASSERT(receiver->IsJSGlobalProxy() || !receiver->IsAccessCheckNeeded());
+  ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
 
-  __ Push(a1, a2, a0);  // Receiver, name, value.
+  __ Push(receiver(), this->name(), value());
 
-  __ li(a0, Operand(Smi::FromInt(strict_mode())));
-  __ push(a0);  // Strict mode.
+  __ li(scratch1(), Operand(Smi::FromInt(strict_mode())));
+  __ push(scratch1());  // strict mode
 
   // Do tail-call to the runtime system.
   ExternalReference store_ic_property =
@@ -2762,39 +2724,37 @@
     Handle<GlobalObject> object,
     Handle<JSGlobalPropertyCell> cell,
     Handle<Name> name) {
-  // ----------- S t a t e -------------
-  //  -- a0    : value
-  //  -- a1    : receiver
-  //  -- a2    : name
-  //  -- ra    : return address
-  // -----------------------------------
   Label miss;
 
   // Check that the map of the global has not changed.
-  __ lw(a3, FieldMemOperand(a1, HeapObject::kMapOffset));
-  __ Branch(&miss, ne, a3, Operand(Handle<Map>(object->map())));
+  __ lw(scratch1(), FieldMemOperand(receiver(), HeapObject::kMapOffset));
+  __ Branch(&miss, ne, scratch1(), Operand(Handle<Map>(object->map())));
 
   // Check that the value in the cell is not the hole. If it is, this
   // cell could have been deleted and reintroducing the global needs
   // to update the property details in the property dictionary of the
   // global object. We bail out to the runtime system to do that.
-  __ li(t0, Operand(cell));
-  __ LoadRoot(t1, Heap::kTheHoleValueRootIndex);
-  __ lw(t2, FieldMemOperand(t0, JSGlobalPropertyCell::kValueOffset));
-  __ Branch(&miss, eq, t1, Operand(t2));
+  __ li(scratch1(), Operand(cell));
+  __ LoadRoot(scratch2(), Heap::kTheHoleValueRootIndex);
+  __ lw(scratch3(),
+        FieldMemOperand(scratch1(), JSGlobalPropertyCell::kValueOffset));
+  __ Branch(&miss, eq, scratch3(), Operand(scratch2()));
 
   // Store the value in the cell.
-  __ sw(a0, FieldMemOperand(t0, JSGlobalPropertyCell::kValueOffset));
+  __ sw(value(),
+        FieldMemOperand(scratch1(), JSGlobalPropertyCell::kValueOffset));
   __ mov(v0, a0);  // Stored value must be returned in v0.
   // Cells are always rescanned, so no write barrier here.
 
   Counters* counters = masm()->isolate()->counters();
-  __ IncrementCounter(counters->named_store_global_inline(), 1, a1, a3);
+  __ IncrementCounter(
+      counters->named_store_global_inline(), 1, scratch1(), scratch2());
   __ Ret();
 
   // Handle store cache miss.
   __ bind(&miss);
-  __ IncrementCounter(counters->named_store_global_inline_miss(), 1, a1, a3);
+  __ IncrementCounter(
+      counters->named_store_global_inline_miss(), 1, scratch1(), scratch2());
   TailCallBuiltin(masm(), MissBuiltin(kind()));
 
   // Return the generated code.
@@ -2936,33 +2896,6 @@
 }
 
 
-Handle<Code> KeyedLoadStubCompiler::CompileLoadElement(
-    Handle<Map> receiver_map) {
-  // ----------- S t a t e -------------
-  //  -- ra    : return address
-  //  -- a0    : key
-  //  -- a1    : receiver
-  // -----------------------------------
-  ElementsKind elements_kind = receiver_map->elements_kind();
-  if (receiver_map->has_fast_elements() ||
-      receiver_map->has_external_array_elements()) {
-    Handle<Code> stub = KeyedLoadFastElementStub(
-        receiver_map->instance_type() == JS_ARRAY_TYPE,
-        elements_kind).GetCode(isolate());
-    __ DispatchMap(a1, a2, receiver_map, stub, DO_SMI_CHECK);
-  } else {
-    Handle<Code> stub =
-        KeyedLoadDictionaryElementStub().GetCode(isolate());
-    __ DispatchMap(a1, a2, receiver_map, stub, DO_SMI_CHECK);
-  }
-
-  TailCallBuiltin(masm(), MissBuiltin(kind()));
-
-  // Return the generated code.
-  return GetICCode(kind(), Code::NORMAL, factory()->empty_string());
-}
-
-
 Handle<Code> BaseLoadStubCompiler::CompilePolymorphicIC(
     MapHandleList* receiver_maps,
     CodeHandleList* handlers,
@@ -2995,55 +2928,23 @@
 }
 
 
-Handle<Code> KeyedStoreStubCompiler::CompileStoreElement(
-    Handle<Map> receiver_map) {
-  // ----------- S t a t e -------------
-  //  -- a0    : value
-  //  -- a1    : key
-  //  -- a2    : receiver
-  //  -- ra    : return address
-  //  -- a3    : scratch
-  // -----------------------------------
-  ElementsKind elements_kind = receiver_map->elements_kind();
-  bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
-  Handle<Code> stub =
-      KeyedStoreElementStub(is_js_array,
-                            elements_kind,
-                            store_mode_).GetCode(isolate());
-
-  __ DispatchMap(a2, a3, receiver_map, stub, DO_SMI_CHECK);
-
-  TailCallBuiltin(masm(), MissBuiltin(kind()));
-
-  // Return the generated code.
-  return GetICCode(kind(), Code::NORMAL, factory()->empty_string());
-}
-
-
 Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic(
     MapHandleList* receiver_maps,
     CodeHandleList* handler_stubs,
     MapHandleList* transitioned_maps) {
-  // ----------- S t a t e -------------
-  //  -- a0    : value
-  //  -- a1    : key
-  //  -- a2    : receiver
-  //  -- ra    : return address
-  //  -- a3    : scratch
-  // -----------------------------------
   Label miss;
-  __ JumpIfSmi(a2, &miss);
+  __ JumpIfSmi(receiver(), &miss);
 
   int receiver_count = receiver_maps->length();
-  __ lw(a3, FieldMemOperand(a2, HeapObject::kMapOffset));
+  __ lw(scratch1(), FieldMemOperand(receiver(), HeapObject::kMapOffset));
   for (int i = 0; i < receiver_count; ++i) {
     if (transitioned_maps->at(i).is_null()) {
       __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET, eq,
-          a3, Operand(receiver_maps->at(i)));
+          scratch1(), Operand(receiver_maps->at(i)));
     } else {
       Label next_map;
-      __ Branch(&next_map, ne, a3, Operand(receiver_maps->at(i)));
-      __ li(a3, Operand(transitioned_maps->at(i)));
+      __ Branch(&next_map, ne, scratch1(), Operand(receiver_maps->at(i)));
+      __ li(transition_map(), Operand(transitioned_maps->at(i)));
       __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET);
       __ bind(&next_map);
     }
@@ -3830,8 +3731,7 @@
     __ Branch(&check_capacity, ne, elements_reg, Operand(at));
 
     int size = FixedArray::SizeFor(JSArray::kPreallocatedArrayElements);
-    __ AllocateInNewSpace(size, elements_reg, scratch, scratch2, &slow,
-                          TAG_OBJECT);
+    __ Allocate(size, elements_reg, scratch, scratch2, &slow, TAG_OBJECT);
 
     __ LoadRoot(scratch, Heap::kFixedArrayMapRootIndex);
     __ sw(scratch, FieldMemOperand(elements_reg, JSObject::kMapOffset));
@@ -3981,8 +3881,7 @@
     __ Branch(&check_capacity, ne, elements_reg, Operand(at));
 
     int size = FixedDoubleArray::SizeFor(JSArray::kPreallocatedArrayElements);
-    __ AllocateInNewSpace(size, elements_reg, scratch1, scratch2, &slow,
-                          TAG_OBJECT);
+    __ Allocate(size, elements_reg, scratch1, scratch2, &slow, TAG_OBJECT);
 
     // Initialize the new FixedDoubleArray.
     __ LoadRoot(scratch1, Heap::kFixedDoubleArrayMapRootIndex);
diff --git a/src/objects.cc b/src/objects.cc
index 9b7e0a7..00d00d5 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -8813,10 +8813,15 @@
   ASSERT(Marking::Color(this) == Marking::WHITE_OBJECT);
 
   // copy code
+  CHECK(IsCode());
+  CHECK(relocation_info()->IsByteArray());
+  CHECK(reinterpret_cast<intptr_t>(instruction_start()) ==
+        reinterpret_cast<intptr_t>(this) + Code::kHeaderSize - kHeapObjectTag);
   memmove(instruction_start(), desc.buffer, desc.instr_size);
 
   // copy reloc info
   // TODO(mstarzinger): Remove once we found the bug.
+  CHECK(IsCode());
   CHECK(relocation_info()->IsByteArray());
   memmove(relocation_start(),
           desc.buffer + desc.buffer_size - desc.reloc_size,
diff --git a/src/objects.h b/src/objects.h
index 96a3800..933a075 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -4299,12 +4299,7 @@
  public:
   // Opaque data type for encapsulating code flags like kind, inline
   // cache state, and arguments count.
-  // FLAGS_MIN_VALUE and FLAGS_MAX_VALUE are specified to ensure that
-  // enumeration type has correct value range (see Issue 830 for more details).
-  enum Flags {
-    FLAGS_MIN_VALUE = 0,
-    FLAGS_MAX_VALUE = kMaxUInt32
-  };
+  typedef uint32_t Flags;
 
 #define CODE_KIND_LIST(V) \
   V(FUNCTION)             \
diff --git a/src/platform-cygwin.cc b/src/platform-cygwin.cc
index 8914d63..67c389e 100644
--- a/src/platform-cygwin.cc
+++ b/src/platform-cygwin.cc
@@ -687,13 +687,14 @@
     CONTEXT context;
     memset(&context, 0, sizeof(context));
 
+    Isolate* isolate = sampler->isolate();
     TickSample sample_obj;
-    TickSample* sample = CpuProfiler::TickSampleEvent(sampler->isolate());
+    TickSample* sample = isolate->cpu_profiler()->TickSampleEvent();
     if (sample == NULL) sample = &sample_obj;
 
     static const DWORD kSuspendFailed = static_cast<DWORD>(-1);
     if (SuspendThread(profiled_thread) == kSuspendFailed) return;
-    sample->state = sampler->isolate()->current_vm_state();
+    sample->state = isolate->current_vm_state();
 
     context.ContextFlags = CONTEXT_FULL;
     if (GetThreadContext(profiled_thread, &context) != 0) {
diff --git a/src/platform-freebsd.cc b/src/platform-freebsd.cc
index 986c5af..14f7171 100644
--- a/src/platform-freebsd.cc
+++ b/src/platform-freebsd.cc
@@ -715,7 +715,7 @@
   if (sampler == NULL || !sampler->IsActive()) return;
 
   TickSample sample_obj;
-  TickSample* sample = CpuProfiler::TickSampleEvent(isolate);
+  TickSample* sample = isolate->cpu_profiler()->TickSampleEvent();
   if (sample == NULL) sample = &sample_obj;
 
   // Extracting the sample from the context is extremely machine dependent.
diff --git a/src/platform-linux.cc b/src/platform-linux.cc
index 0359b2d..d21f160 100644
--- a/src/platform-linux.cc
+++ b/src/platform-linux.cc
@@ -1088,7 +1088,7 @@
   if (sampler == NULL || !sampler->IsActive()) return;
 
   TickSample sample_obj;
-  TickSample* sample = CpuProfiler::TickSampleEvent(isolate);
+  TickSample* sample = isolate->cpu_profiler()->TickSampleEvent();
   if (sample == NULL) sample = &sample_obj;
 
   // Extracting the sample from the context is extremely machine dependent.
diff --git a/src/platform-macos.cc b/src/platform-macos.cc
index fde5217..30e2b89 100644
--- a/src/platform-macos.cc
+++ b/src/platform-macos.cc
@@ -818,8 +818,9 @@
 
   void SampleContext(Sampler* sampler) {
     thread_act_t profiled_thread = sampler->platform_data()->profiled_thread();
+    Isolate* isolate = sampler->isolate();
     TickSample sample_obj;
-    TickSample* sample = CpuProfiler::TickSampleEvent(sampler->isolate());
+    TickSample* sample = isolate->cpu_profiler()->TickSampleEvent();
     if (sample == NULL) sample = &sample_obj;
 
     if (KERN_SUCCESS != thread_suspend(profiled_thread)) return;
@@ -850,7 +851,7 @@
                          flavor,
                          reinterpret_cast<natural_t*>(&state),
                          &count) == KERN_SUCCESS) {
-      sample->state = sampler->isolate()->current_vm_state();
+      sample->state = isolate->current_vm_state();
       sample->pc = reinterpret_cast<Address>(state.REGISTER_FIELD(ip));
       sample->sp = reinterpret_cast<Address>(state.REGISTER_FIELD(sp));
       sample->fp = reinterpret_cast<Address>(state.REGISTER_FIELD(bp));
diff --git a/src/platform-openbsd.cc b/src/platform-openbsd.cc
index 66eac22..e48d4cb 100644
--- a/src/platform-openbsd.cc
+++ b/src/platform-openbsd.cc
@@ -748,7 +748,7 @@
   if (sampler == NULL || !sampler->IsActive()) return;
 
   TickSample sample_obj;
-  TickSample* sample = CpuProfiler::TickSampleEvent(isolate);
+  TickSample* sample = isolate->cpu_profiler()->TickSampleEvent();
   if (sample == NULL) sample = &sample_obj;
 
   // Extracting the sample from the context is extremely machine dependent.
diff --git a/src/platform-solaris.cc b/src/platform-solaris.cc
index 85ba95f..0e616d1 100644
--- a/src/platform-solaris.cc
+++ b/src/platform-solaris.cc
@@ -682,7 +682,7 @@
   if (sampler == NULL || !sampler->IsActive()) return;
 
   TickSample sample_obj;
-  TickSample* sample = CpuProfiler::TickSampleEvent(isolate);
+  TickSample* sample = isolate->cpu_profiler()->TickSampleEvent();
   if (sample == NULL) sample = &sample_obj;
 
   // Extracting the sample from the context is extremely machine dependent.
diff --git a/src/platform-win32.cc b/src/platform-win32.cc
index 66dbade..c1bae93 100644
--- a/src/platform-win32.cc
+++ b/src/platform-win32.cc
@@ -2064,13 +2064,14 @@
     CONTEXT context;
     memset(&context, 0, sizeof(context));
 
+    Isolate* isolate = sampler->isolate();
     TickSample sample_obj;
-    TickSample* sample = CpuProfiler::TickSampleEvent(sampler->isolate());
+    TickSample* sample = isolate->cpu_profiler()->TickSampleEvent();
     if (sample == NULL) sample = &sample_obj;
 
     static const DWORD kSuspendFailed = static_cast<DWORD>(-1);
     if (SuspendThread(profiled_thread) == kSuspendFailed) return;
-    sample->state = sampler->isolate()->current_vm_state();
+    sample->state = isolate->current_vm_state();
 
     context.ContextFlags = CONTEXT_FULL;
     if (GetThreadContext(profiled_thread, &context) != 0) {
diff --git a/src/profile-generator-inl.h b/src/profile-generator-inl.h
index 6e7f499..4e6302c 100644
--- a/src/profile-generator-inl.h
+++ b/src/profile-generator-inl.h
@@ -74,7 +74,8 @@
       entry_(entry),
       total_ticks_(0),
       self_ticks_(0),
-      children_(CodeEntriesMatch) {
+      children_(CodeEntriesMatch),
+      id_(tree->next_node_id()) {
 }
 
 
diff --git a/src/profile-generator.cc b/src/profile-generator.cc
index 2bf1724..ce07213 100644
--- a/src/profile-generator.cc
+++ b/src/profile-generator.cc
@@ -296,6 +296,7 @@
                   "",
                   0,
                   TokenEnumerator::kNoSecurityToken),
+      next_node_id_(1),
       root_(new ProfileNode(this, &root_entry_)) {
 }
 
@@ -306,7 +307,7 @@
 }
 
 
-void ProfileTree::AddPathFromEnd(const Vector<CodeEntry*>& path) {
+ProfileNode* ProfileTree::AddPathFromEnd(const Vector<CodeEntry*>& path) {
   ProfileNode* node = root_;
   for (CodeEntry** entry = path.start() + path.length() - 1;
        entry != path.start() - 1;
@@ -316,6 +317,7 @@
     }
   }
   node->IncrementSelfTicks();
+  return node;
 }
 
 
@@ -467,7 +469,8 @@
 
 
 void CpuProfile::AddPath(const Vector<CodeEntry*>& path) {
-  top_down_.AddPathFromEnd(path);
+  ProfileNode* top_frame_node = top_down_.AddPathFromEnd(path);
+  if (record_samples_) samples_.Add(top_frame_node);
 }
 
 
@@ -483,7 +486,7 @@
 
 CpuProfile* CpuProfile::FilteredClone(int security_token_id) {
   ASSERT(security_token_id != TokenEnumerator::kNoSecurityToken);
-  CpuProfile* clone = new CpuProfile(title_, uid_);
+  CpuProfile* clone = new CpuProfile(title_, uid_, false);
   clone->top_down_.FilteredClone(&top_down_, security_token_id);
   return clone;
 }
@@ -609,7 +612,8 @@
 }
 
 
-bool CpuProfilesCollection::StartProfiling(const char* title, unsigned uid) {
+bool CpuProfilesCollection::StartProfiling(const char* title, unsigned uid,
+                                           bool record_samples) {
   ASSERT(uid > 0);
   current_profiles_semaphore_->Wait();
   if (current_profiles_.length() >= kMaxSimultaneousProfiles) {
@@ -623,17 +627,12 @@
       return false;
     }
   }
-  current_profiles_.Add(new CpuProfile(title, uid));
+  current_profiles_.Add(new CpuProfile(title, uid, record_samples));
   current_profiles_semaphore_->Signal();
   return true;
 }
 
 
-bool CpuProfilesCollection::StartProfiling(String* title, unsigned uid) {
-  return StartProfiling(GetName(title), uid);
-}
-
-
 CpuProfile* CpuProfilesCollection::StopProfiling(int security_token_id,
                                                  const char* title,
                                                  double actual_sampling_rate) {
diff --git a/src/profile-generator.h b/src/profile-generator.h
index b128dad..4ddb753 100644
--- a/src/profile-generator.h
+++ b/src/profile-generator.h
@@ -150,6 +150,7 @@
   INLINE(const List<ProfileNode*>* children() const) { return &children_list_; }
   double GetSelfMillis() const;
   double GetTotalMillis() const;
+  unsigned id() const { return id_; }
 
   void Print(int indent);
 
@@ -170,6 +171,7 @@
   // Mapping from CodeEntry* to ProfileNode*
   HashMap children_;
   List<ProfileNode*> children_list_;
+  unsigned id_;
 
   DISALLOW_COPY_AND_ASSIGN(ProfileNode);
 };
@@ -180,7 +182,7 @@
   ProfileTree();
   ~ProfileTree();
 
-  void AddPathFromEnd(const Vector<CodeEntry*>& path);
+  ProfileNode* AddPathFromEnd(const Vector<CodeEntry*>& path);
   void AddPathFromStart(const Vector<CodeEntry*>& path);
   void CalculateTotalTicks();
   void FilteredClone(ProfileTree* src, int security_token_id);
@@ -191,6 +193,8 @@
   ProfileNode* root() const { return root_; }
   void SetTickRatePerMs(double ticks_per_ms);
 
+  unsigned next_node_id() { return next_node_id_++; }
+
   void ShortPrint();
   void Print() {
     root_->Print(0);
@@ -201,6 +205,7 @@
   void TraverseDepthFirst(Callback* callback);
 
   CodeEntry root_entry_;
+  unsigned next_node_id_;
   ProfileNode* root_;
   double ms_to_ticks_scale_;
 
@@ -210,8 +215,8 @@
 
 class CpuProfile {
  public:
-  CpuProfile(const char* title, unsigned uid)
-      : title_(title), uid_(uid) { }
+  CpuProfile(const char* title, unsigned uid, bool record_samples)
+      : title_(title), uid_(uid), record_samples_(record_samples) { }
 
   // Add pc -> ... -> main() call path to the profile.
   void AddPath(const Vector<CodeEntry*>& path);
@@ -223,6 +228,9 @@
   INLINE(unsigned uid() const) { return uid_; }
   INLINE(const ProfileTree* top_down() const) { return &top_down_; }
 
+  INLINE(int samples_count() const) { return samples_.length(); }
+  INLINE(ProfileNode* sample(int index) const) { return samples_.at(index); }
+
   void UpdateTicksScale();
 
   void ShortPrint();
@@ -231,6 +239,8 @@
  private:
   const char* title_;
   unsigned uid_;
+  bool record_samples_;
+  List<ProfileNode*> samples_;
   ProfileTree top_down_;
 
   DISALLOW_COPY_AND_ASSIGN(CpuProfile);
@@ -288,8 +298,7 @@
   CpuProfilesCollection();
   ~CpuProfilesCollection();
 
-  bool StartProfiling(const char* title, unsigned uid);
-  bool StartProfiling(String* title, unsigned uid);
+  bool StartProfiling(const char* title, unsigned uid, bool record_samples);
   CpuProfile* StopProfiling(int security_token_id,
                             const char* title,
                             double actual_sampling_rate);
diff --git a/src/runtime.cc b/src/runtime.cc
index 12777e7..e220d6b 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -2231,7 +2231,7 @@
   target->set_literals(*literals);
 
   if (isolate->logger()->is_logging_code_events() ||
-      CpuProfiler::is_profiling(isolate)) {
+      isolate->cpu_profiler()->is_profiling()) {
     isolate->logger()->LogExistingFunction(
         source_shared, Handle<Code>(source_shared->code()));
   }
diff --git a/src/version.cc b/src/version.cc
index 6a62f58..4bb5a49 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -34,7 +34,7 @@
 // cannot be changed without changing the SCons build script.
 #define MAJOR_VERSION     3
 #define MINOR_VERSION     17
-#define BUILD_NUMBER      12
+#define BUILD_NUMBER      13
 #define PATCH_LEVEL       0
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)