Version 3.4.12

Added --prof profiling option to d8 shell.

Fixed a bug where reading a directory in d8 shell hangs (issue 1533).

Fixed a potential assertion failure in const declarations.

Fixed an assertion failure in descriptor arrays (issue 1526).

Enabled fast thread-local storage by default on supported platforms.

Improved reporting of source position for global variable loads (issue 1527).



git-svn-id: http://v8.googlecode.com/svn/trunk@8635 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/ChangeLog b/ChangeLog
index 8cf7a14..7e7df06 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2011-07-13: Version 3.4.12
+
+        Added --prof profiling option to d8 shell.
+
+        Fixed a bug where reading a directory in d8 shell hangs (issue 1533).
+
+        Fixed a potential assertion failure in const declarations.
+
+        Fixed an assertion failure in descriptor arrays (issue 1526).
+
+        Enabled fast thread-local storage by default on supported platforms.
+
+        Improved reporting of source position for global variable loads
+        (issue 1527).
+
+
 2011-07-11: Version 3.4.11
 
         Fixed MinGW32 build.
diff --git a/SConstruct b/SConstruct
index d8d41c0..5276ce2 100644
--- a/SConstruct
+++ b/SConstruct
@@ -60,26 +60,17 @@
     'mode:debug': {
       'CPPDEFINES': ['V8_ENABLE_CHECKS', 'OBJECT_PRINT']
     },
-    'vmstate:on': {
-      'CPPDEFINES':   ['ENABLE_VMSTATE_TRACKING'],
-    },
     'objectprint:on': {
       'CPPDEFINES':   ['OBJECT_PRINT'],
     },
-    'protectheap:on': {
-      'CPPDEFINES':   ['ENABLE_VMSTATE_TRACKING', 'ENABLE_HEAP_PROTECTION'],
-    },
-    'profilingsupport:on': {
-      'CPPDEFINES':   ['ENABLE_VMSTATE_TRACKING', 'ENABLE_LOGGING_AND_PROFILING'],
-    },
     'debuggersupport:on': {
       'CPPDEFINES':   ['ENABLE_DEBUGGER_SUPPORT'],
     },
     'inspector:on': {
       'CPPDEFINES':   ['INSPECTOR'],
     },
-    'fasttls:on': {
-      'CPPDEFINES':   ['V8_FAST_TLS'],
+    'fasttls:off': {
+      'CPPDEFINES':   ['V8_NO_FAST_TLS'],
     },
     'liveobjectlist:on': {
       'CPPDEFINES':   ['ENABLE_DEBUGGER_SUPPORT', 'INSPECTOR',
@@ -929,21 +920,11 @@
     'default': 'static',
     'help': 'the type of library to produce'
   },
-  'vmstate': {
-    'values': ['on', 'off'],
-    'default': 'off',
-    'help': 'enable VM state tracking'
-  },
   'objectprint': {
     'values': ['on', 'off'],
     'default': 'off',
     'help': 'enable object printing'
   },
-  'protectheap': {
-    'values': ['on', 'off'],
-    'default': 'off',
-    'help': 'enable heap protection'
-  },
   'profilingsupport': {
     'values': ['on', 'off'],
     'default': 'on',
diff --git a/include/v8.h b/include/v8.h
index fb10c71..0872411 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -2984,31 +2984,6 @@
   static bool IsProfilerPaused();
 
   /**
-   * If logging is performed into a memory buffer (via --logfile=*), allows to
-   * retrieve previously written messages. This can be used for retrieving
-   * profiler log data in the application. This function is thread-safe.
-   *
-   * Caller provides a destination buffer that must exist during GetLogLines
-   * call. Only whole log lines are copied into the buffer.
-   *
-   * \param from_pos specified a point in a buffer to read from, 0 is the
-   *   beginning of a buffer. It is assumed that caller updates its current
-   *   position using returned size value from the previous call.
-   * \param dest_buf destination buffer for log data.
-   * \param max_size size of the destination buffer.
-   * \returns actual size of log data copied into buffer.
-   */
-  static int GetLogLines(int from_pos, char* dest_buf, int max_size);
-
-  /**
-   * The minimum allowed size for a log lines buffer.  If the size of
-   * the buffer given will not be enough to hold a line of the maximum
-   * length, an attempt to find a log line end in GetLogLines will
-   * fail, and an empty result will be returned.
-   */
-  static const int kMinimumSizeForLogLinesBuffer = 2048;
-
-  /**
    * Retrieve the V8 thread id of the calling thread.
    *
    * The thread id for a thread should only be retrieved after the V8
diff --git a/src/SConscript b/src/SConscript
index 4b0ba16..6b3059a 100755
--- a/src/SConscript
+++ b/src/SConscript
@@ -231,15 +231,11 @@
 PREPARSER_SOURCES = {
   'all': Split("""
     allocation.cc
-    bignum.cc
-    cached-powers.cc
-    conversions.cc
     hashmap.cc
     preparse-data.cc
     preparser.cc
     preparser-api.cc
     scanner-base.cc
-    strtod.cc
     token.cc
     unicode.cc
     utils.cc
@@ -317,10 +313,7 @@
   env.Replace(**context.flags['v8'])
   context.ApplyEnvOverrides(env)
   env['BUILDERS']['JS2C'] = Builder(action=js2c.JS2C)
-  if 'ENABLE_LOGGING_AND_PROFILING' in env['CPPDEFINES']:
-    env['BUILDERS']['Snapshot'] = Builder(action='$SOURCE $TARGET --logfile "$LOGFILE" --log-snapshot-positions')
-  else:
-    env['BUILDERS']['Snapshot'] = Builder(action='$SOURCE $TARGET')
+  env['BUILDERS']['Snapshot'] = Builder(action='$SOURCE $TARGET --logfile "$LOGFILE" --log-snapshot-positions')
 
   def BuildJS2CEnv(type):
     js2c_env = { 'TYPE': type, 'COMPRESSION': 'off' }
diff --git a/src/api.cc b/src/api.cc
index 71a715c..dc1f90c 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -54,16 +54,11 @@
 
 #define LOG_API(isolate, expr) LOG(isolate, ApiEntryCall(expr))
 
-#ifdef ENABLE_VMSTATE_TRACKING
 #define ENTER_V8(isolate)                                        \
   ASSERT((isolate)->IsInitialized());                           \
   i::VMState __state__((isolate), i::OTHER)
 #define LEAVE_V8(isolate) \
   i::VMState __state__((isolate), i::EXTERNAL)
-#else
-#define ENTER_V8(isolate) ((void) 0)
-#define LEAVE_V8(isolate) ((void) 0)
-#endif
 
 namespace v8 {
 
@@ -114,9 +109,7 @@
 
 static void DefaultFatalErrorHandler(const char* location,
                                      const char* message) {
-#ifdef ENABLE_VMSTATE_TRACKING
   i::VMState __state__(i::Isolate::Current(), i::OTHER);
-#endif
   API_Fatal(location, message);
 }
 
@@ -4832,37 +4825,20 @@
 
 
 void V8::PauseProfiler() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
   isolate->logger()->PauseProfiler();
-#endif
 }
 
 
 void V8::ResumeProfiler() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
   isolate->logger()->ResumeProfiler();
-#endif
 }
 
 
 bool V8::IsProfilerPaused() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
   return isolate->logger()->IsProfilerPaused();
-#else
-  return true;
-#endif
-}
-
-
-int V8::GetLogLines(int from_pos, char* dest_buf, int max_size) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
-  ASSERT(max_size >= kMinimumSizeForLogLinesBuffer);
-  return LOGGER->GetLogLines(from_pos, dest_buf, max_size);
-#endif
-  return 0;
 }
 
 
@@ -5327,7 +5303,6 @@
 
 
 Handle<String> CpuProfileNode::GetFunctionName() const {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::CpuProfileNode::GetFunctionName");
   const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
@@ -5340,117 +5315,77 @@
         isolate->factory()->LookupAsciiSymbol(entry->name_prefix()),
         isolate->factory()->LookupAsciiSymbol(entry->name()))));
   }
-#else
-  return v8::String::Empty();
-#endif
 }
 
 
 Handle<String> CpuProfileNode::GetScriptResourceName() const {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::CpuProfileNode::GetScriptResourceName");
   const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
   return Handle<String>(ToApi<String>(isolate->factory()->LookupAsciiSymbol(
       node->entry()->resource_name())));
-#else
-  return v8::String::Empty();
-#endif
 }
 
 
 int CpuProfileNode::GetLineNumber() const {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::CpuProfileNode::GetLineNumber");
   return reinterpret_cast<const i::ProfileNode*>(this)->entry()->line_number();
-#else
-  return 0;
-#endif
 }
 
 
 double CpuProfileNode::GetTotalTime() const {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::CpuProfileNode::GetTotalTime");
   return reinterpret_cast<const i::ProfileNode*>(this)->GetTotalMillis();
-#else
-  return 0.0;
-#endif
 }
 
 
 double CpuProfileNode::GetSelfTime() const {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::CpuProfileNode::GetSelfTime");
   return reinterpret_cast<const i::ProfileNode*>(this)->GetSelfMillis();
-#else
-  return 0.0;
-#endif
 }
 
 
 double CpuProfileNode::GetTotalSamplesCount() const {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::CpuProfileNode::GetTotalSamplesCount");
   return reinterpret_cast<const i::ProfileNode*>(this)->total_ticks();
-#else
-  return 0.0;
-#endif
 }
 
 
 double CpuProfileNode::GetSelfSamplesCount() const {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::CpuProfileNode::GetSelfSamplesCount");
   return reinterpret_cast<const i::ProfileNode*>(this)->self_ticks();
-#else
-  return 0.0;
-#endif
 }
 
 
 unsigned CpuProfileNode::GetCallUid() const {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::CpuProfileNode::GetCallUid");
   return reinterpret_cast<const i::ProfileNode*>(this)->entry()->GetCallUid();
-#else
-  return 0;
-#endif
 }
 
 
 int CpuProfileNode::GetChildrenCount() const {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::CpuProfileNode::GetChildrenCount");
   return reinterpret_cast<const i::ProfileNode*>(this)->children()->length();
-#else
-  return 0;
-#endif
 }
 
 
 const CpuProfileNode* CpuProfileNode::GetChild(int index) const {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::CpuProfileNode::GetChild");
   const i::ProfileNode* child =
       reinterpret_cast<const i::ProfileNode*>(this)->children()->at(index);
   return reinterpret_cast<const CpuProfileNode*>(child);
-#else
-  return NULL;
-#endif
 }
 
 
 void CpuProfile::Delete() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::CpuProfile::Delete");
   i::CpuProfiler::DeleteProfile(reinterpret_cast<i::CpuProfile*>(this));
@@ -5459,153 +5394,109 @@
     // If this was the last profile, clean up all accessory data as well.
     i::CpuProfiler::DeleteAllProfiles();
   }
-#endif
 }
 
 
 unsigned CpuProfile::GetUid() const {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::CpuProfile::GetUid");
   return reinterpret_cast<const i::CpuProfile*>(this)->uid();
-#else
-  return 0;
-#endif
 }
 
 
 Handle<String> CpuProfile::GetTitle() const {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::CpuProfile::GetTitle");
   const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
   return Handle<String>(ToApi<String>(isolate->factory()->LookupAsciiSymbol(
       profile->title())));
-#else
-  return v8::String::Empty();
-#endif
 }
 
 
 const CpuProfileNode* CpuProfile::GetBottomUpRoot() const {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::CpuProfile::GetBottomUpRoot");
   const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
   return reinterpret_cast<const CpuProfileNode*>(profile->bottom_up()->root());
-#else
-  return NULL;
-#endif
 }
 
 
 const CpuProfileNode* CpuProfile::GetTopDownRoot() const {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::CpuProfile::GetTopDownRoot");
   const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
   return reinterpret_cast<const CpuProfileNode*>(profile->top_down()->root());
-#else
-  return NULL;
-#endif
 }
 
 
 int CpuProfiler::GetProfilesCount() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::CpuProfiler::GetProfilesCount");
   return i::CpuProfiler::GetProfilesCount();
-#else
-  return 0;
-#endif
 }
 
 
 const CpuProfile* CpuProfiler::GetProfile(int index,
                                           Handle<Value> security_token) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::CpuProfiler::GetProfile");
   return reinterpret_cast<const CpuProfile*>(
       i::CpuProfiler::GetProfile(
           security_token.IsEmpty() ? NULL : *Utils::OpenHandle(*security_token),
           index));
-#else
-  return NULL;
-#endif
 }
 
 
 const CpuProfile* CpuProfiler::FindProfile(unsigned uid,
                                            Handle<Value> security_token) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::CpuProfiler::FindProfile");
   return reinterpret_cast<const CpuProfile*>(
       i::CpuProfiler::FindProfile(
           security_token.IsEmpty() ? NULL : *Utils::OpenHandle(*security_token),
           uid));
-#else
-  return NULL;
-#endif
 }
 
 
 void CpuProfiler::StartProfiling(Handle<String> title) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::CpuProfiler::StartProfiling");
   i::CpuProfiler::StartProfiling(*Utils::OpenHandle(*title));
-#endif
 }
 
 
 const CpuProfile* CpuProfiler::StopProfiling(Handle<String> title,
                                              Handle<Value> security_token) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::CpuProfiler::StopProfiling");
   return reinterpret_cast<const CpuProfile*>(
       i::CpuProfiler::StopProfiling(
           security_token.IsEmpty() ? NULL : *Utils::OpenHandle(*security_token),
           *Utils::OpenHandle(*title)));
-#else
-  return NULL;
-#endif
 }
 
 
 void CpuProfiler::DeleteAllProfiles() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::CpuProfiler::DeleteAllProfiles");
   i::CpuProfiler::DeleteAllProfiles();
-#endif
 }
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
 static i::HeapGraphEdge* ToInternal(const HeapGraphEdge* edge) {
   return const_cast<i::HeapGraphEdge*>(
       reinterpret_cast<const i::HeapGraphEdge*>(edge));
 }
-#endif
 
 
 HeapGraphEdge::Type HeapGraphEdge::GetType() const {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::HeapGraphEdge::GetType");
   return static_cast<HeapGraphEdge::Type>(ToInternal(this)->type());
-#else
-  return static_cast<HeapGraphEdge::Type>(0);
-#endif
 }
 
 
 Handle<Value> HeapGraphEdge::GetName() const {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::HeapGraphEdge::GetName");
   i::HeapGraphEdge* edge = ToInternal(this);
@@ -5622,166 +5513,112 @@
           edge->index())));
     default: UNREACHABLE();
   }
-#endif
   return v8::Undefined();
 }
 
 
 const HeapGraphNode* HeapGraphEdge::GetFromNode() const {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::HeapGraphEdge::GetFromNode");
   const i::HeapEntry* from = ToInternal(this)->From();
   return reinterpret_cast<const HeapGraphNode*>(from);
-#else
-  return NULL;
-#endif
 }
 
 
 const HeapGraphNode* HeapGraphEdge::GetToNode() const {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::HeapGraphEdge::GetToNode");
   const i::HeapEntry* to = ToInternal(this)->to();
   return reinterpret_cast<const HeapGraphNode*>(to);
-#else
-  return NULL;
-#endif
 }
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
 static i::HeapEntry* ToInternal(const HeapGraphNode* entry) {
   return const_cast<i::HeapEntry*>(
       reinterpret_cast<const i::HeapEntry*>(entry));
 }
-#endif
 
 
 HeapGraphNode::Type HeapGraphNode::GetType() const {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::HeapGraphNode::GetType");
   return static_cast<HeapGraphNode::Type>(ToInternal(this)->type());
-#else
-  return static_cast<HeapGraphNode::Type>(0);
-#endif
 }
 
 
 Handle<String> HeapGraphNode::GetName() const {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::HeapGraphNode::GetName");
   return Handle<String>(ToApi<String>(isolate->factory()->LookupAsciiSymbol(
       ToInternal(this)->name())));
-#else
-  return v8::String::Empty();
-#endif
 }
 
 
 uint64_t HeapGraphNode::GetId() const {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::HeapGraphNode::GetId");
   return ToInternal(this)->id();
-#else
-  return 0;
-#endif
 }
 
 
 int HeapGraphNode::GetSelfSize() const {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::HeapGraphNode::GetSelfSize");
   return ToInternal(this)->self_size();
-#else
-  return 0;
-#endif
 }
 
 
 int HeapGraphNode::GetRetainedSize(bool exact) const {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::HeapSnapshot::GetRetainedSize");
   return ToInternal(this)->RetainedSize(exact);
-#else
-  return 0;
-#endif
 }
 
 
 int HeapGraphNode::GetChildrenCount() const {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::HeapSnapshot::GetChildrenCount");
   return ToInternal(this)->children().length();
-#else
-  return 0;
-#endif
 }
 
 
 const HeapGraphEdge* HeapGraphNode::GetChild(int index) const {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::HeapSnapshot::GetChild");
   return reinterpret_cast<const HeapGraphEdge*>(
       &ToInternal(this)->children()[index]);
-#else
-  return NULL;
-#endif
 }
 
 
 int HeapGraphNode::GetRetainersCount() const {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::HeapSnapshot::GetRetainersCount");
   return ToInternal(this)->retainers().length();
-#else
-  return 0;
-#endif
 }
 
 
 const HeapGraphEdge* HeapGraphNode::GetRetainer(int index) const {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::HeapSnapshot::GetRetainer");
   return reinterpret_cast<const HeapGraphEdge*>(
       ToInternal(this)->retainers()[index]);
-#else
-  return NULL;
-#endif
 }
 
 
 const HeapGraphNode* HeapGraphNode::GetDominatorNode() const {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::HeapSnapshot::GetDominatorNode");
   return reinterpret_cast<const HeapGraphNode*>(ToInternal(this)->dominator());
-#else
-  return NULL;
-#endif
 }
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
 static i::HeapSnapshot* ToInternal(const HeapSnapshot* snapshot) {
   return const_cast<i::HeapSnapshot*>(
       reinterpret_cast<const i::HeapSnapshot*>(snapshot));
 }
-#endif
 
 
 void HeapSnapshot::Delete() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::HeapSnapshot::Delete");
   if (i::HeapProfiler::GetSnapshotsCount() > 1) {
@@ -5790,93 +5627,63 @@
     // If this is the last snapshot, clean up all accessory data as well.
     i::HeapProfiler::DeleteAllSnapshots();
   }
-#endif
 }
 
 
 HeapSnapshot::Type HeapSnapshot::GetType() const {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::HeapSnapshot::GetType");
   return static_cast<HeapSnapshot::Type>(ToInternal(this)->type());
-#else
-  return static_cast<HeapSnapshot::Type>(0);
-#endif
 }
 
 
 unsigned HeapSnapshot::GetUid() const {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::HeapSnapshot::GetUid");
   return ToInternal(this)->uid();
-#else
-  return 0;
-#endif
 }
 
 
 Handle<String> HeapSnapshot::GetTitle() const {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::HeapSnapshot::GetTitle");
   return Handle<String>(ToApi<String>(isolate->factory()->LookupAsciiSymbol(
       ToInternal(this)->title())));
-#else
-  return v8::String::Empty();
-#endif
 }
 
 
 const HeapGraphNode* HeapSnapshot::GetRoot() const {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::HeapSnapshot::GetHead");
   return reinterpret_cast<const HeapGraphNode*>(ToInternal(this)->root());
-#else
-  return 0;
-#endif
 }
 
 
 const HeapGraphNode* HeapSnapshot::GetNodeById(uint64_t id) const {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::HeapSnapshot::GetNodeById");
   return reinterpret_cast<const HeapGraphNode*>(
       ToInternal(this)->GetEntryById(id));
-#else
-  return NULL;
-#endif
 }
 
 
 int HeapSnapshot::GetNodesCount() const {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::HeapSnapshot::GetNodesCount");
   return ToInternal(this)->entries()->length();
-#else
-  return 0;
-#endif
 }
 
 
 const HeapGraphNode* HeapSnapshot::GetNode(int index) const {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::HeapSnapshot::GetNode");
   return reinterpret_cast<const HeapGraphNode*>(
       ToInternal(this)->entries()->at(index));
-#else
-  return 0;
-#endif
 }
 
 
 void HeapSnapshot::Serialize(OutputStream* stream,
                              HeapSnapshot::SerializationFormat format) const {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::HeapSnapshot::Serialize");
   ApiCheck(format == kJSON,
@@ -5890,49 +5697,35 @@
            "Invalid stream chunk size");
   i::HeapSnapshotJSONSerializer serializer(ToInternal(this));
   serializer.Serialize(stream);
-#endif
 }
 
 
 int HeapProfiler::GetSnapshotsCount() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::HeapProfiler::GetSnapshotsCount");
   return i::HeapProfiler::GetSnapshotsCount();
-#else
-  return 0;
-#endif
 }
 
 
 const HeapSnapshot* HeapProfiler::GetSnapshot(int index) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::HeapProfiler::GetSnapshot");
   return reinterpret_cast<const HeapSnapshot*>(
       i::HeapProfiler::GetSnapshot(index));
-#else
-  return NULL;
-#endif
 }
 
 
 const HeapSnapshot* HeapProfiler::FindSnapshot(unsigned uid) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::HeapProfiler::FindSnapshot");
   return reinterpret_cast<const HeapSnapshot*>(
       i::HeapProfiler::FindSnapshot(uid));
-#else
-  return NULL;
-#endif
 }
 
 
 const HeapSnapshot* HeapProfiler::TakeSnapshot(Handle<String> title,
                                                HeapSnapshot::Type type,
                                                ActivityControl* control) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::HeapProfiler::TakeSnapshot");
   i::HeapSnapshot::Type internal_type = i::HeapSnapshot::kFull;
@@ -5946,27 +5739,20 @@
   return reinterpret_cast<const HeapSnapshot*>(
       i::HeapProfiler::TakeSnapshot(
           *Utils::OpenHandle(*title), internal_type, control));
-#else
-  return NULL;
-#endif
 }
 
 
 void HeapProfiler::DeleteAllSnapshots() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate* isolate = i::Isolate::Current();
   IsDeadCheck(isolate, "v8::HeapProfiler::DeleteAllSnapshots");
   i::HeapProfiler::DeleteAllSnapshots();
-#endif
 }
 
 
 void HeapProfiler::DefineWrapperClass(uint16_t class_id,
                                       WrapperInfoCallback callback) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   i::Isolate::Current()->heap_profiler()->DefineWrapperClass(class_id,
                                                              callback);
-#endif
 }
 
 
diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc
index fdb47b9..ab7c6f2 100644
--- a/src/arm/code-stubs-arm.cc
+++ b/src/arm/code-stubs-arm.cc
@@ -1683,25 +1683,17 @@
 }
 
 
-const char* UnaryOpStub::GetName() {
-  if (name_ != NULL) return name_;
-  const int kMaxNameLength = 100;
-  name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
-      kMaxNameLength);
-  if (name_ == NULL) return "OOM";
+void UnaryOpStub::PrintName(StringStream* stream) {
   const char* op_name = Token::Name(op_);
   const char* overwrite_name = NULL;  // Make g++ happy.
   switch (mode_) {
     case UNARY_NO_OVERWRITE: overwrite_name = "Alloc"; break;
     case UNARY_OVERWRITE: overwrite_name = "Overwrite"; break;
   }
-
-  OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
-               "UnaryOpStub_%s_%s_%s",
-               op_name,
-               overwrite_name,
-               UnaryOpIC::GetName(operand_type_));
-  return name_;
+  stream->Add("UnaryOpStub_%s_%s_%s",
+              op_name,
+              overwrite_name,
+              UnaryOpIC::GetName(operand_type_));
 }
 
 
@@ -2037,12 +2029,7 @@
 }
 
 
-const char* BinaryOpStub::GetName() {
-  if (name_ != NULL) return name_;
-  const int kMaxNameLength = 100;
-  name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
-      kMaxNameLength);
-  if (name_ == NULL) return "OOM";
+void BinaryOpStub::PrintName(StringStream* stream) {
   const char* op_name = Token::Name(op_);
   const char* overwrite_name;
   switch (mode_) {
@@ -2051,13 +2038,10 @@
     case OVERWRITE_LEFT: overwrite_name = "OverwriteLeft"; break;
     default: overwrite_name = "UnknownOverwrite"; break;
   }
-
-  OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
-               "BinaryOpStub_%s_%s_%s",
-               op_name,
-               overwrite_name,
-               BinaryOpIC::GetName(operands_type_));
-  return name_;
+  stream->Add("BinaryOpStub_%s_%s_%s",
+              op_name,
+              overwrite_name,
+              BinaryOpIC::GetName(operands_type_));
 }
 
 
@@ -3562,7 +3546,6 @@
   // Setup frame pointer for the frame to be pushed.
   __ add(fp, sp, Operand(-EntryFrameConstants::kCallerFPOffset));
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
   // If this is the outermost JS call, set js_entry_sp value.
   Label non_outermost_js;
   ExternalReference js_entry_sp(Isolate::k_js_entry_sp_address, isolate);
@@ -3578,7 +3561,6 @@
   __ mov(ip, Operand(Smi::FromInt(StackFrame::INNER_JSENTRY_FRAME)));
   __ bind(&cont);
   __ push(ip);
-#endif
 
   // Call a faked try-block that does the invoke.
   __ bl(&invoke);
@@ -3639,7 +3621,6 @@
   __ PopTryHandler();
 
   __ bind(&exit);  // r0 holds result
-#ifdef ENABLE_LOGGING_AND_PROFILING
   // Check if the current stack frame is marked as the outermost JS frame.
   Label non_outermost_js_2;
   __ pop(r5);
@@ -3649,7 +3630,6 @@
   __ mov(r5, Operand(ExternalReference(js_entry_sp)));
   __ str(r6, MemOperand(r5));
   __ bind(&non_outermost_js_2);
-#endif
 
   // Restore the top frame descriptors from the stack.
   __ pop(r3);
@@ -4749,16 +4729,9 @@
 
 // Unfortunately you have to run without snapshots to see most of these
 // names in the profile since most compare stubs end up in the snapshot.
-const char* CompareStub::GetName() {
+void CompareStub::PrintName(StringStream* stream) {
   ASSERT((lhs_.is(r0) && rhs_.is(r1)) ||
          (lhs_.is(r1) && rhs_.is(r0)));
-
-  if (name_ != NULL) return name_;
-  const int kMaxNameLength = 100;
-  name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
-      kMaxNameLength);
-  if (name_ == NULL) return "OOM";
-
   const char* cc_name;
   switch (cc_) {
     case lt: cc_name = "LT"; break;
@@ -4769,40 +4742,14 @@
     case ne: cc_name = "NE"; break;
     default: cc_name = "UnknownCondition"; break;
   }
-
-  const char* lhs_name = lhs_.is(r0) ? "_r0" : "_r1";
-  const char* rhs_name = rhs_.is(r0) ? "_r0" : "_r1";
-
-  const char* strict_name = "";
-  if (strict_ && (cc_ == eq || cc_ == ne)) {
-    strict_name = "_STRICT";
-  }
-
-  const char* never_nan_nan_name = "";
-  if (never_nan_nan_ && (cc_ == eq || cc_ == ne)) {
-    never_nan_nan_name = "_NO_NAN";
-  }
-
-  const char* include_number_compare_name = "";
-  if (!include_number_compare_) {
-    include_number_compare_name = "_NO_NUMBER";
-  }
-
-  const char* include_smi_compare_name = "";
-  if (!include_smi_compare_) {
-    include_smi_compare_name = "_NO_SMI";
-  }
-
-  OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
-               "CompareStub_%s%s%s%s%s%s",
-               cc_name,
-               lhs_name,
-               rhs_name,
-               strict_name,
-               never_nan_nan_name,
-               include_number_compare_name,
-               include_smi_compare_name);
-  return name_;
+  bool is_equality = cc_ == eq || cc_ == ne;
+  stream->Add("CompareStub_%s", cc_name);
+  stream->Add(lhs_.is(r0) ? "_r0" : "_r1");
+  stream->Add(rhs_.is(r0) ? "_r0" : "_r1");
+  if (strict_ && is_equality) stream->Add("_STRICT");
+  if (never_nan_nan_ && is_equality) stream->Add("_NO_NAN");
+  if (!include_number_compare_) stream->Add("_NO_NUMBER");
+  if (!include_smi_compare_) stream->Add("_NO_SMI");
 }
 
 
diff --git a/src/arm/code-stubs-arm.h b/src/arm/code-stubs-arm.h
index b6cda70..557f7e6 100644
--- a/src/arm/code-stubs-arm.h
+++ b/src/arm/code-stubs-arm.h
@@ -65,8 +65,7 @@
               UnaryOpIC::TypeInfo operand_type = UnaryOpIC::UNINITIALIZED)
       : op_(op),
         mode_(mode),
-        operand_type_(operand_type),
-        name_(NULL) {
+        operand_type_(operand_type) {
   }
 
  private:
@@ -76,19 +75,7 @@
   // Operand type information determined at runtime.
   UnaryOpIC::TypeInfo operand_type_;
 
-  char* name_;
-
-  virtual const char* GetName();
-
-#ifdef DEBUG
-  void Print() {
-    PrintF("UnaryOpStub %d (op %s), (mode %d, runtime_type_info %s)\n",
-           MinorKey(),
-           Token::String(op_),
-           static_cast<int>(mode_),
-           UnaryOpIC::GetName(operand_type_));
-  }
-#endif
+  virtual void PrintName(StringStream* stream);
 
   class ModeBits: public BitField<UnaryOverwriteMode, 0, 1> {};
   class OpBits: public BitField<Token::Value, 1, 7> {};
@@ -142,8 +129,7 @@
       : op_(op),
         mode_(mode),
         operands_type_(BinaryOpIC::UNINITIALIZED),
-        result_type_(BinaryOpIC::UNINITIALIZED),
-        name_(NULL) {
+        result_type_(BinaryOpIC::UNINITIALIZED) {
     use_vfp3_ = CpuFeatures::IsSupported(VFP3);
     ASSERT(OpBits::is_valid(Token::NUM_TOKENS));
   }
@@ -156,8 +142,7 @@
         mode_(ModeBits::decode(key)),
         use_vfp3_(VFP3Bits::decode(key)),
         operands_type_(operands_type),
-        result_type_(result_type),
-        name_(NULL) { }
+        result_type_(result_type) { }
 
  private:
   enum SmiCodeGenerateHeapNumberResults {
@@ -173,20 +158,7 @@
   BinaryOpIC::TypeInfo operands_type_;
   BinaryOpIC::TypeInfo result_type_;
 
-  char* name_;
-
-  virtual const char* GetName();
-
-#ifdef DEBUG
-  void Print() {
-    PrintF("BinaryOpStub %d (op %s), "
-           "(mode %d, runtime_type_info %s)\n",
-           MinorKey(),
-           Token::String(op_),
-           static_cast<int>(mode_),
-           BinaryOpIC::GetName(operands_type_));
-  }
-#endif
+  virtual void PrintName(StringStream* stream);
 
   // Minor key encoding in 16 bits RRRTTTVOOOOOOOMM.
   class ModeBits: public BitField<OverwriteMode, 0, 2> {};
diff --git a/src/arm/codegen-arm.h b/src/arm/codegen-arm.h
index 01aa805..d27982a 100644
--- a/src/arm/codegen-arm.h
+++ b/src/arm/codegen-arm.h
@@ -58,9 +58,7 @@
   // Print the code after compiling it.
   static void PrintCode(Handle<Code> code, CompilationInfo* info);
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
   static bool ShouldGenerateLog(Expression* type);
-#endif
 
   static void SetFunctionInfo(Handle<JSFunction> fun,
                               FunctionLiteral* lit,
diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc
index 4b55915..c3440eb 100644
--- a/src/arm/full-codegen-arm.cc
+++ b/src/arm/full-codegen-arm.cc
@@ -776,7 +776,7 @@
       // IDs for bailouts from optimized code.
       ASSERT(prop->obj()->AsVariableProxy() != NULL);
       { AccumulatorValueContext for_object(this);
-        EmitVariableLoad(prop->obj()->AsVariableProxy()->var());
+        EmitVariableLoad(prop->obj()->AsVariableProxy());
       }
 
       __ push(r0);
@@ -1113,7 +1113,7 @@
 
 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
   Comment cmnt(masm_, "[ VariableProxy");
-  EmitVariableLoad(expr->var());
+  EmitVariableLoad(expr);
 }
 
 
@@ -1262,7 +1262,11 @@
 }
 
 
-void FullCodeGenerator::EmitVariableLoad(Variable* var) {
+void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
+  // Record position before possible IC call.
+  SetSourcePosition(proxy->position());
+  Variable* var = proxy->var();
+
   // Three cases: non-this global variables, lookup slots, and all other
   // types of slots.
   Slot* slot = var->AsSlot();
@@ -1593,7 +1597,7 @@
     { AccumulatorValueContext context(this);
       switch (assign_type) {
         case VARIABLE:
-          EmitVariableLoad(expr->target()->AsVariableProxy()->var());
+          EmitVariableLoad(expr->target()->AsVariableProxy());
           PrepareForBailout(expr->target(), TOS_REG);
           break;
         case NAMED_PROPERTY:
@@ -2772,13 +2776,12 @@
   //     with '%2s' (see Logger::LogRuntime for all the formats).
   //   2 (array): Arguments to the format string.
   ASSERT_EQ(args->length(), 3);
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (CodeGenerator::ShouldGenerateLog(args->at(0))) {
     VisitForStackValue(args->at(1));
     VisitForStackValue(args->at(2));
     __ CallRuntime(Runtime::kLog, 2);
   }
-#endif
+
   // Finally, we're expected to leave a value on the top of the stack.
   __ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
   context()->Plug(r0);
@@ -3816,7 +3819,7 @@
   if (assign_type == VARIABLE) {
     ASSERT(expr->expression()->AsVariableProxy()->var() != NULL);
     AccumulatorValueContext context(this);
-    EmitVariableLoad(expr->expression()->AsVariableProxy()->var());
+    EmitVariableLoad(expr->expression()->AsVariableProxy());
   } else {
     // Reserve space for result of postfix operation.
     if (expr->is_postfix() && !context()->IsEffect()) {
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index ee36314..dc93aea 100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -551,6 +551,13 @@
   RecordPosition(pointers->position());
   __ Call(code, mode);
   RegisterLazyDeoptimization(instr, safepoint_mode);
+
+  // Signal that we don't inline smi code before these stubs in the
+  // optimizing code generator.
+  if (code->kind() == Code::BINARY_OP_IC ||
+      code->kind() == Code::COMPARE_IC) {
+    __ nop();
+  }
 }
 
 
@@ -1506,6 +1513,7 @@
 
   BinaryOpStub stub(instr->op(), NO_OVERWRITE);
   CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
+  __ nop();  // Signals no inlined code.
 }
 
 
diff --git a/src/code-stubs.cc b/src/code-stubs.cc
index 4d6fd03..5c0ef5a 100644
--- a/src/code-stubs.cc
+++ b/src/code-stubs.cc
@@ -61,21 +61,29 @@
 }
 
 
+SmartPointer<const char> CodeStub::GetName() {
+  char buffer[100];
+  NoAllocationStringAllocator allocator(buffer,
+                                        static_cast<unsigned>(sizeof(buffer)));
+  StringStream stream(&allocator);
+  PrintName(&stream);
+  return stream.ToCString();
+}
+
+
 void CodeStub::RecordCodeGeneration(Code* code, MacroAssembler* masm) {
   code->set_major_key(MajorKey());
 
   Isolate* isolate = masm->isolate();
-  PROFILE(isolate, CodeCreateEvent(Logger::STUB_TAG, code, GetName()));
-  GDBJIT(AddCode(GDBJITInterface::STUB, GetName(), code));
+  SmartPointer<const char> name = GetName();
+  PROFILE(isolate, CodeCreateEvent(Logger::STUB_TAG, code, *name));
+  GDBJIT(AddCode(GDBJITInterface::STUB, *name, code));
   Counters* counters = isolate->counters();
   counters->total_stubs_code_size()->Increment(code->instruction_size());
 
 #ifdef ENABLE_DISASSEMBLER
   if (FLAG_print_code_stubs) {
-#ifdef DEBUG
-    Print();
-#endif
-    code->Disassemble(GetName());
+    code->Disassemble(*name);
     PrintF("\n");
   }
 #endif
@@ -213,13 +221,7 @@
 }
 
 
-const char* InstanceofStub::GetName() {
-  if (name_ != NULL) return name_;
-  const int kMaxNameLength = 100;
-  name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
-      kMaxNameLength);
-  if (name_ == NULL) return "OOM";
-
+void InstanceofStub::PrintName(StringStream* stream) {
   const char* args = "";
   if (HasArgsInRegisters()) {
     args = "_REGS";
@@ -235,12 +237,10 @@
     return_true_false_object = "_TRUEFALSE";
   }
 
-  OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
-               "InstanceofStub%s%s%s",
-               args,
-               inline_check,
-               return_true_false_object);
-  return name_;
+  stream->Add("InstanceofStub%s%s%s",
+              args,
+              inline_check,
+              return_true_false_object);
 }
 
 
@@ -302,4 +302,30 @@
 }
 
 
+void ArgumentsAccessStub::PrintName(StringStream* stream) {
+  const char* type_name = NULL;  // Make g++ happy.
+  switch (type_) {
+    case READ_ELEMENT: type_name = "ReadElement"; break;
+    case NEW_NON_STRICT_FAST: type_name = "NewNonStrictFast"; break;
+    case NEW_NON_STRICT_SLOW: type_name = "NewNonStrictSlow"; break;
+    case NEW_STRICT: type_name = "NewStrict"; break;
+  }
+  stream->Add("ArgumentsAccessStub_%s", type_name);
+}
+
+
+void CallFunctionStub::PrintName(StringStream* stream) {
+  const char* in_loop_name = NULL;  // Make g++ happy.
+  switch (in_loop_) {
+    case NOT_IN_LOOP: in_loop_name = ""; break;
+    case IN_LOOP: in_loop_name = "_InLoop"; break;
+  }
+  const char* flags_name = NULL;  // Make g++ happy.
+  switch (flags_) {
+    case NO_CALL_FUNCTION_FLAGS: flags_name = ""; break;
+    case RECEIVER_MIGHT_BE_IMPLICIT: flags_name = "_Implicit"; break;
+  }
+  stream->Add("CallFunctionStub_Args%d%s%s", argc_, in_loop_name, flags_name);
+}
+
 } }  // namespace v8::internal
diff --git a/src/code-stubs.h b/src/code-stubs.h
index 1670ddf..17c245c 100644
--- a/src/code-stubs.h
+++ b/src/code-stubs.h
@@ -181,16 +181,15 @@
   }
 
   // Returns a name for logging/debugging purposes.
-  virtual const char* GetName() { return MajorName(MajorKey(), false); }
+  SmartPointer<const char> GetName();
+  virtual void PrintName(StringStream* stream) {
+    stream->Add("%s", MajorName(MajorKey(), false));
+  }
 
   // Returns whether the code generated for this stub needs to be allocated as
   // a fixed (non-moveable) code object.
   virtual bool NeedsImmovableCode() { return false; }
 
-#ifdef DEBUG
-  virtual void Print() { PrintF("%s\n", GetName()); }
-#endif
-
   // Computes the key based on major and minor.
   uint32_t GetKey() {
     ASSERT(static_cast<int>(MajorKey()) < NUMBER_OF_IDS);
@@ -362,7 +361,7 @@
     kReturnTrueFalseObject = 1 << 2
   };
 
-  explicit InstanceofStub(Flags flags) : flags_(flags), name_(NULL) { }
+  explicit InstanceofStub(Flags flags) : flags_(flags) { }
 
   static Register left();
   static Register right();
@@ -385,10 +384,9 @@
     return (flags_ & kReturnTrueFalseObject) != 0;
   }
 
-  virtual const char* GetName();
+  virtual void PrintName(StringStream* stream);
 
   Flags flags_;
-  char* name_;
 };
 
 
@@ -466,8 +464,7 @@
       include_number_compare_((flags & NO_NUMBER_COMPARE_IN_STUB) == 0),
       include_smi_compare_((flags & NO_SMI_COMPARE_IN_STUB) == 0),
       lhs_(lhs),
-      rhs_(rhs),
-      name_(NULL) { }
+      rhs_(rhs) { }
 
   CompareStub(Condition cc,
               bool strict,
@@ -478,8 +475,7 @@
       include_number_compare_((flags & NO_NUMBER_COMPARE_IN_STUB) == 0),
       include_smi_compare_((flags & NO_SMI_COMPARE_IN_STUB) == 0),
       lhs_(no_reg),
-      rhs_(no_reg),
-      name_(NULL) { }
+      rhs_(no_reg) { }
 
   void Generate(MacroAssembler* masm);
 
@@ -533,26 +529,7 @@
 
   // Unfortunately you have to run without snapshots to see most of these
   // names in the profile since most compare stubs end up in the snapshot.
-  char* name_;
-  virtual const char* GetName();
-#ifdef DEBUG
-  void Print() {
-    PrintF("CompareStub (minor %d) (cc %d), (strict %s), "
-           "(never_nan_nan %s), (smi_compare %s) (number_compare %s) ",
-           MinorKey(),
-           static_cast<int>(cc_),
-           strict_ ? "true" : "false",
-           never_nan_nan_ ? "true" : "false",
-           include_smi_compare_ ? "inluded" : "not included",
-           include_number_compare_ ? "included" : "not included");
-
-    if (!lhs_.is(no_reg) && !rhs_.is(no_reg)) {
-      PrintF("(lhs r%d), (rhs r%d)\n", lhs_.code(), rhs_.code());
-    } else {
-      PrintF("\n");
-    }
-  }
-#endif
+  virtual void PrintName(StringStream* stream);
 };
 
 
@@ -610,7 +587,9 @@
  private:
   int MinorKey() { return 1; }
 
-  virtual const char* GetName() { return "JSConstructEntryStub"; }
+  virtual void PrintName(StringStream* stream) {
+    stream->Add("JSConstructEntryStub");
+  }
 };
 
 
@@ -637,11 +616,7 @@
   void GenerateNewNonStrictFast(MacroAssembler* masm);
   void GenerateNewNonStrictSlow(MacroAssembler* masm);
 
-#ifdef DEBUG
-  void Print() {
-    PrintF("ArgumentsAccessStub (type %d)\n", type_);
-  }
-#endif
+  virtual void PrintName(StringStream* stream);
 };
 
 
@@ -685,14 +660,7 @@
   InLoopFlag in_loop_;
   CallFunctionFlags flags_;
 
-#ifdef DEBUG
-  void Print() {
-    PrintF("CallFunctionStub (args %d, in_loop %d, flags %d)\n",
-           argc_,
-           static_cast<int>(in_loop_),
-           static_cast<int>(flags_));
-  }
-#endif
+  virtual void PrintName(StringStream* stream);
 
   // Minor key encoding in 32 bits with Bitfield <Type, shift, size>.
   class InLoopBits: public BitField<InLoopFlag, 0, 1> {};
diff --git a/src/codegen.cc b/src/codegen.cc
index 4e5c781..fb723a3 100644
--- a/src/codegen.cc
+++ b/src/codegen.cc
@@ -169,8 +169,6 @@
 #endif  // ENABLE_DISASSEMBLER
 }
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
 static Vector<const char> kRegexp = CStrVector("regexp");
 
 bool CodeGenerator::ShouldGenerateLog(Expression* type) {
@@ -187,8 +185,6 @@
   return false;
 }
 
-#endif
-
 
 bool CodeGenerator::RecordPositions(MacroAssembler* masm,
                                     int pos,
diff --git a/src/conversions.cc b/src/conversions.cc
index 232eda0..c34fe51 100644
--- a/src/conversions.cc
+++ b/src/conversions.cc
@@ -430,24 +430,4 @@
   return builder.Finalize();
 }
 
-
-static Mutex* dtoa_lock_one = OS::CreateMutex();
-static Mutex* dtoa_lock_zero = OS::CreateMutex();
-
-
 } }  // namespace v8::internal
-
-
-extern "C" {
-void ACQUIRE_DTOA_LOCK(int n) {
-  ASSERT(n == 0 || n == 1);
-  (n == 0 ? v8::internal::dtoa_lock_zero : v8::internal::dtoa_lock_one)->Lock();
-}
-
-
-void FREE_DTOA_LOCK(int n) {
-  ASSERT(n == 0 || n == 1);
-  (n == 0 ? v8::internal::dtoa_lock_zero : v8::internal::dtoa_lock_one)->
-      Unlock();
-}
-}
diff --git a/src/cpu-profiler-inl.h b/src/cpu-profiler-inl.h
index d7a23a5..938b632 100644
--- a/src/cpu-profiler-inl.h
+++ b/src/cpu-profiler-inl.h
@@ -30,8 +30,6 @@
 
 #include "cpu-profiler.h"
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
 #include <new>
 #include "circular-queue-inl.h"
 #include "profile-generator-inl.h"
@@ -83,6 +81,4 @@
 
 } }  // namespace v8::internal
 
-#endif  // ENABLE_LOGGING_AND_PROFILING
-
 #endif  // V8_CPU_PROFILER_INL_H_
diff --git a/src/cpu-profiler.cc b/src/cpu-profiler.cc
index 8b10e81..bb480fc 100644
--- a/src/cpu-profiler.cc
+++ b/src/cpu-profiler.cc
@@ -29,8 +29,6 @@
 
 #include "cpu-profiler-inl.h"
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
 #include "frames-inl.h"
 #include "hashmap.h"
 #include "log-inl.h"
@@ -574,31 +572,21 @@
   logger->logging_nesting_ = saved_logging_nesting_;
 }
 
-} }  // namespace v8::internal
-
-#endif  // ENABLE_LOGGING_AND_PROFILING
-
-namespace v8 {
-namespace internal {
 
 void CpuProfiler::Setup() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   Isolate* isolate = Isolate::Current();
   if (isolate->cpu_profiler() == NULL) {
     isolate->set_cpu_profiler(new CpuProfiler());
   }
-#endif
 }
 
 
 void CpuProfiler::TearDown() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   Isolate* isolate = Isolate::Current();
   if (isolate->cpu_profiler() != NULL) {
     delete isolate->cpu_profiler();
   }
   isolate->set_cpu_profiler(NULL);
-#endif
 }
 
 } }  // namespace v8::internal
diff --git a/src/cpu-profiler.h b/src/cpu-profiler.h
index 42d79a5..4175e8f 100644
--- a/src/cpu-profiler.h
+++ b/src/cpu-profiler.h
@@ -28,8 +28,6 @@
 #ifndef V8_CPU_PROFILER_H_
 #define V8_CPU_PROFILER_H_
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
 #include "allocation.h"
 #include "atomicops.h"
 #include "circular-queue.h"
@@ -206,9 +204,6 @@
       v8::internal::CpuProfiler::Call;                        \
     }                                                         \
   } while (false)
-#else
-#define PROFILE(isolate, Call) LOG(isolate, Call)
-#endif  // ENABLE_LOGGING_AND_PROFILING
 
 
 namespace v8 {
@@ -221,7 +216,6 @@
   static void Setup();
   static void TearDown();
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
   static void StartProfiling(const char* title);
   static void StartProfiling(String* title);
   static CpuProfile* StopProfiling(const char* title);
@@ -289,10 +283,6 @@
   bool need_to_stop_sampler_;
   Atomic32 is_profiling_;
 
-#else
-  static INLINE(bool is_profiling(Isolate* isolate)) { return false; }
-#endif  // ENABLE_LOGGING_AND_PROFILING
-
  private:
   DISALLOW_COPY_AND_ASSIGN(CpuProfiler);
 };
diff --git a/src/d8.cc b/src/d8.cc
index 4ce4ef3..5f57350 100644
--- a/src/d8.cc
+++ b/src/d8.cc
@@ -968,8 +968,6 @@
 
 
 bool Shell::SetOptions(int argc, char* argv[]) {
-  Locker lock;
-
   for (int i = 0; i < argc; i++) {
     if (strcmp(argv[i], "--stress-opt") == 0) {
       options.stress_opt = true;
diff --git a/src/d8.gyp b/src/d8.gyp
index 8b52ed9..85914ec 100644
--- a/src/d8.gyp
+++ b/src/d8.gyp
@@ -38,10 +38,7 @@
         '../src',
       ],
       'defines': [
-        'ENABLE_LOGGING_AND_PROFILING',
         'ENABLE_DEBUGGER_SUPPORT',
-        'ENABLE_VMSTATE_TRACKING',
-        'V8_FAST_TLS',
       ],
       'sources': [
         'd8.cc',
diff --git a/src/debug.h b/src/debug.h
index c4d3c7e..c614844 100644
--- a/src/debug.h
+++ b/src/debug.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -35,6 +35,7 @@
 #include "execution.h"
 #include "factory.h"
 #include "flags.h"
+#include "frames-inl.h"
 #include "hashmap.h"
 #include "platform.h"
 #include "string-stream.h"
diff --git a/src/flag-definitions.h b/src/flag-definitions.h
index 6e13dd2..2db44c3 100644
--- a/src/flag-definitions.h
+++ b/src/flag-definitions.h
@@ -452,14 +452,10 @@
             "trace regexp macro assembler calls.")
 
 //
-// Logging and profiling only flags
+// Logging and profiling flags
 //
 #undef FLAG
-#ifdef ENABLE_LOGGING_AND_PROFILING
 #define FLAG FLAG_FULL
-#else
-#define FLAG FLAG_READONLY
-#endif
 
 // log.cc
 DEFINE_bool(log, false,
@@ -491,19 +487,6 @@
 DEFINE_bool(ll_prof, false, "Enable low-level linux profiler.")
 
 //
-// Heap protection flags
-// Using heap protection requires ENABLE_LOGGING_AND_PROFILING as well.
-//
-#ifdef ENABLE_HEAP_PROTECTION
-#undef FLAG
-#define FLAG FLAG_FULL
-
-DEFINE_bool(protect_heap, false,
-            "Protect/unprotect V8's heap when leaving/entring the VM.")
-
-#endif
-
-//
 // Disassembler only flags
 //
 #undef FLAG
diff --git a/src/frames.cc b/src/frames.cc
index 4e67463..eaf09eb 100644
--- a/src/frames.cc
+++ b/src/frames.cc
@@ -36,6 +36,8 @@
 #include "scopeinfo.h"
 #include "string-stream.h"
 
+#include "allocation-inl.h"
+
 namespace v8 {
 namespace internal {
 
@@ -346,7 +348,6 @@
 // -------------------------------------------------------------------------
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
 SafeStackTraceFrameIterator::SafeStackTraceFrameIterator(
     Isolate* isolate,
     Address fp, Address sp, Address low_bound, Address high_bound) :
@@ -362,7 +363,6 @@
     if (frame()->is_java_script()) return;
   }
 }
-#endif
 
 
 Code* StackFrame::GetSafepointData(Isolate* isolate,
diff --git a/src/frames.h b/src/frames.h
index 9e93dae..f542a92 100644
--- a/src/frames.h
+++ b/src/frames.h
@@ -843,7 +843,6 @@
 };
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
 typedef JavaScriptFrameIteratorTemp<SafeStackFrameIterator>
     SafeJavaScriptFrameIterator;
 
@@ -855,7 +854,6 @@
                                        Address low_bound, Address high_bound);
   void Advance();
 };
-#endif
 
 
 class StackFrameLocator BASE_EMBEDDED {
diff --git a/src/full-codegen.h b/src/full-codegen.h
index d25ca49..6b174f7 100644
--- a/src/full-codegen.h
+++ b/src/full-codegen.h
@@ -444,7 +444,7 @@
                                        TypeofState typeof_state,
                                        Label* slow,
                                        Label* done);
-  void EmitVariableLoad(Variable* expr);
+  void EmitVariableLoad(VariableProxy* proxy);
 
   enum ResolveEvalFlag {
     SKIP_CONTEXT_LOOKUP,
diff --git a/src/handles.cc b/src/handles.cc
index d8cc742..d73aaf0 100644
--- a/src/handles.cc
+++ b/src/handles.cc
@@ -543,11 +543,6 @@
 // associated with the wrapper and get rid of both the wrapper and the
 // handle.
 static void ClearWrapperCache(Persistent<v8::Value> handle, void*) {
-#ifdef ENABLE_HEAP_PROTECTION
-  // Weak reference callbacks are called as if from outside V8.  We
-  // need to reeenter to unprotect the heap.
-  VMState state(OTHER);
-#endif
   Handle<Object> cache = Utils::OpenHandle(*handle);
   JSValue* wrapper = JSValue::cast(*cache);
   Foreign* foreign = Script::cast(wrapper->value())->wrapper();
diff --git a/src/heap-profiler.cc b/src/heap-profiler.cc
index fb1ea8a..7e613e9 100644
--- a/src/heap-profiler.cc
+++ b/src/heap-profiler.cc
@@ -34,7 +34,6 @@
 namespace internal {
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
 HeapProfiler::HeapProfiler()
     : snapshots_(new HeapSnapshotsCollection()),
       next_snapshot_uid_(1) {
@@ -52,29 +51,21 @@
 }
 
 
-#endif  // ENABLE_LOGGING_AND_PROFILING
-
 void HeapProfiler::Setup() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   Isolate* isolate = Isolate::Current();
   if (isolate->heap_profiler() == NULL) {
     isolate->set_heap_profiler(new HeapProfiler());
   }
-#endif
 }
 
 
 void HeapProfiler::TearDown() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   Isolate* isolate = Isolate::Current();
   delete isolate->heap_profiler();
   isolate->set_heap_profiler(NULL);
-#endif
 }
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
 HeapSnapshot* HeapProfiler::TakeSnapshot(const char* name,
                                          int type,
                                          v8::ActivityControl* control) {
@@ -179,7 +170,5 @@
   snapshots_->ObjectMoveEvent(from, to);
 }
 
-#endif  // ENABLE_LOGGING_AND_PROFILING
-
 
 } }  // namespace v8::internal
diff --git a/src/heap-profiler.h b/src/heap-profiler.h
index c32f4c4..b1bc91c 100644
--- a/src/heap-profiler.h
+++ b/src/heap-profiler.h
@@ -33,8 +33,6 @@
 namespace v8 {
 namespace internal {
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
 class HeapSnapshot;
 class HeapSnapshotsCollection;
 
@@ -45,9 +43,6 @@
       profiler->call;                                                        \
     }                                                                        \
   } while (false)
-#else
-#define HEAP_PROFILE(heap, call) ((void) 0)
-#endif  // ENABLE_LOGGING_AND_PROFILING
 
 // The HeapProfiler writes data to the log files, which can be postprocessed
 // to generate .hp files for use by the GHC/Valgrind tool hp2ps.
@@ -56,7 +51,6 @@
   static void Setup();
   static void TearDown();
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
   static HeapSnapshot* TakeSnapshot(const char* name,
                                     int type,
                                     v8::ActivityControl* control);
@@ -93,8 +87,6 @@
   HeapSnapshotsCollection* snapshots_;
   unsigned next_snapshot_uid_;
   List<v8::HeapProfiler::WrapperInfoCallback> wrapper_callbacks_;
-
-#endif  // ENABLE_LOGGING_AND_PROFILING
 };
 
 } }  // namespace v8::internal
diff --git a/src/heap.cc b/src/heap.cc
index 508bdf3..98a2d33 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -293,12 +293,11 @@
 
 // TODO(1238405): Combine the infrastructure for --heap-stats and
 // --log-gc to avoid the complicated preprocessor and flag testing.
-#if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
 void Heap::ReportStatisticsBeforeGC() {
   // Heap::ReportHeapStatistics will also log NewSpace statistics when
-  // compiled with ENABLE_LOGGING_AND_PROFILING and --log-gc is set.  The
-  // following logic is used to avoid double logging.
-#if defined(DEBUG) && defined(ENABLE_LOGGING_AND_PROFILING)
+  // compiled --log-gc is set.  The following logic is used to avoid
+  // double logging.
+#ifdef DEBUG
   if (FLAG_heap_stats || FLAG_log_gc) new_space_.CollectStatistics();
   if (FLAG_heap_stats) {
     ReportHeapStatistics("Before GC");
@@ -306,23 +305,16 @@
     new_space_.ReportStatistics();
   }
   if (FLAG_heap_stats || FLAG_log_gc) new_space_.ClearHistograms();
-#elif defined(DEBUG)
-  if (FLAG_heap_stats) {
-    new_space_.CollectStatistics();
-    ReportHeapStatistics("Before GC");
-    new_space_.ClearHistograms();
-  }
-#elif defined(ENABLE_LOGGING_AND_PROFILING)
+#else
   if (FLAG_log_gc) {
     new_space_.CollectStatistics();
     new_space_.ReportStatistics();
     new_space_.ClearHistograms();
   }
-#endif
+#endif  // DEBUG
 }
 
 
-#if defined(ENABLE_LOGGING_AND_PROFILING)
 void Heap::PrintShortHeapStatistics() {
   if (!FLAG_trace_gc_verbose) return;
   PrintF("Memory allocator,   used: %8" V8_PTR_PREFIX "d"
@@ -368,7 +360,6 @@
          lo_space_->Size(),
          lo_space_->Available());
 }
-#endif
 
 
 // TODO(1238405): Combine the infrastructure for --heap-stats and
@@ -376,20 +367,17 @@
 void Heap::ReportStatisticsAfterGC() {
   // Similar to the before GC, we use some complicated logic to ensure that
   // NewSpace statistics are logged exactly once when --log-gc is turned on.
-#if defined(DEBUG) && defined(ENABLE_LOGGING_AND_PROFILING)
+#if defined(DEBUG)
   if (FLAG_heap_stats) {
     new_space_.CollectStatistics();
     ReportHeapStatistics("After GC");
   } else if (FLAG_log_gc) {
     new_space_.ReportStatistics();
   }
-#elif defined(DEBUG)
-  if (FLAG_heap_stats) ReportHeapStatistics("After GC");
-#elif defined(ENABLE_LOGGING_AND_PROFILING)
+#else
   if (FLAG_log_gc) new_space_.ReportStatistics();
-#endif
+#endif  // DEBUG
 }
-#endif  // defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
 
 
 void Heap::GarbageCollectionPrologue() {
@@ -406,11 +394,11 @@
   }
 
   if (FLAG_gc_verbose) Print();
-#endif
+#endif  // DEBUG
 
-#if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
+#if defined(DEBUG)
   ReportStatisticsBeforeGC();
-#endif
+#endif  // DEBUG
 
   LiveObjectList::GCPrologue();
 }
@@ -447,12 +435,10 @@
       symbol_table()->Capacity());
   isolate_->counters()->number_of_symbols()->Set(
       symbol_table()->NumberOfElements());
-#if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
+#if defined(DEBUG)
   ReportStatisticsAfterGC();
-#endif
-#ifdef ENABLE_DEBUGGER_SUPPORT
+#endif  // DEBUG
   isolate_->debug()->AfterGarbageCollection();
-#endif
 }
 
 
@@ -1335,15 +1321,12 @@
   enum ObjectContents  { DATA_OBJECT, POINTER_OBJECT };
   enum SizeRestriction { SMALL, UNKNOWN_SIZE };
 
-#if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
   static void RecordCopiedObject(Heap* heap, HeapObject* obj) {
     bool should_record = false;
 #ifdef DEBUG
     should_record = FLAG_heap_stats;
 #endif
-#ifdef ENABLE_LOGGING_AND_PROFILING
     should_record = should_record || FLAG_log_gc;
-#endif
     if (should_record) {
       if (heap->new_space()->Contains(obj)) {
         heap->new_space()->RecordAllocation(obj);
@@ -1352,7 +1335,6 @@
       }
     }
   }
-#endif  // defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
 
   // Helper function used by CopyObject to copy a source object to an
   // allocated target object and update the forwarding pointer in the source
@@ -1368,12 +1350,9 @@
     source->set_map_word(MapWord::FromForwardingAddress(target));
 
     if (logging_and_profiling_mode == LOGGING_AND_PROFILING_ENABLED) {
-#if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
       // Update NewSpace stats if necessary.
       RecordCopiedObject(heap, target);
-#endif
       HEAP_PROFILE(heap, ObjectMoveEvent(source->address(), target->address()));
-#if defined(ENABLE_LOGGING_AND_PROFILING)
       Isolate* isolate = heap->isolate();
       if (isolate->logger()->is_logging() ||
           CpuProfiler::is_profiling(isolate)) {
@@ -1382,7 +1361,6 @@
               source->address(), target->address()));
         }
       }
-#endif
     }
 
     return target;
@@ -1558,7 +1536,6 @@
 
 
 void Heap::SwitchScavengingVisitorsTableIfProfilingWasEnabled() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (scavenging_visitors_table_mode_ == LOGGING_AND_PROFILING_ENABLED) {
     // Table was already updated by some isolate.
     return;
@@ -1584,7 +1561,6 @@
     Release_Store(&scavenging_visitors_table_mode_,
                   LOGGING_AND_PROFILING_ENABLED);
   }
-#endif
 }
 
 
@@ -5213,28 +5189,6 @@
 }
 
 
-#ifdef ENABLE_HEAP_PROTECTION
-
-void Heap::Protect() {
-  if (HasBeenSetup()) {
-    AllSpaces spaces;
-    for (Space* space = spaces.next(); space != NULL; space = spaces.next())
-      space->Protect();
-  }
-}
-
-
-void Heap::Unprotect() {
-  if (HasBeenSetup()) {
-    AllSpaces spaces;
-    for (Space* space = spaces.next(); space != NULL; space = spaces.next())
-      space->Unprotect();
-  }
-}
-
-#endif
-
-
 void Heap::AddGCPrologueCallback(GCPrologueCallback callback, GCType gc_type) {
   ASSERT(callback != NULL);
   GCPrologueCallbackPair pair(callback, gc_type);
@@ -5930,9 +5884,7 @@
     PrintF("\n");
   }
 
-#if defined(ENABLE_LOGGING_AND_PROFILING)
   heap_->PrintShortHeapStatistics();
-#endif
 }
 
 
diff --git a/src/heap.h b/src/heap.h
index 5aba05d..d90a681 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -409,12 +409,6 @@
   // Uncommit unused semi space.
   bool UncommitFromSpace() { return new_space_.UncommitFromSpace(); }
 
-#ifdef ENABLE_HEAP_PROTECTION
-  // Protect/unprotect the heap by marking all spaces read-only/writable.
-  void Protect();
-  void Unprotect();
-#endif
-
   // Allocates and initializes a new JavaScript object based on a
   // constructor.
   // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
@@ -1052,10 +1046,8 @@
   void ZapFromSpace();
 #endif
 
-#if defined(ENABLE_LOGGING_AND_PROFILING)
   // Print short heap statistics.
   void PrintShortHeapStatistics();
-#endif
 
   // Makes a new symbol object
   // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
@@ -1514,11 +1506,9 @@
   // around a GC).
   inline void CompletelyClearInstanceofCache();
 
-#if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
   // Record statistics before and after garbage collection.
   void ReportStatisticsBeforeGC();
   void ReportStatisticsAfterGC();
-#endif
 
   // Slow part of scavenge object.
   static void ScavengeObjectSlow(HeapObject** p, HeapObject* object);
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc
index e3eb122..48bd8b1 100644
--- a/src/ia32/code-stubs-ia32.cc
+++ b/src/ia32/code-stubs-ia32.cc
@@ -511,25 +511,17 @@
 }
 
 
-const char* UnaryOpStub::GetName() {
-  if (name_ != NULL) return name_;
-  const int kMaxNameLength = 100;
-  name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
-      kMaxNameLength);
-  if (name_ == NULL) return "OOM";
+void UnaryOpStub::PrintName(StringStream* stream) {
   const char* op_name = Token::Name(op_);
   const char* overwrite_name = NULL;  // Make g++ happy.
   switch (mode_) {
     case UNARY_NO_OVERWRITE: overwrite_name = "Alloc"; break;
     case UNARY_OVERWRITE: overwrite_name = "Overwrite"; break;
   }
-
-  OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
-               "UnaryOpStub_%s_%s_%s",
-               op_name,
-               overwrite_name,
-               UnaryOpIC::GetName(operand_type_));
-  return name_;
+  stream->Add("UnaryOpStub_%s_%s_%s",
+              op_name,
+              overwrite_name,
+              UnaryOpIC::GetName(operand_type_));
 }
 
 
@@ -914,12 +906,7 @@
 }
 
 
-const char* BinaryOpStub::GetName() {
-  if (name_ != NULL) return name_;
-  const int kMaxNameLength = 100;
-  name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
-      kMaxNameLength);
-  if (name_ == NULL) return "OOM";
+void BinaryOpStub::PrintName(StringStream* stream) {
   const char* op_name = Token::Name(op_);
   const char* overwrite_name;
   switch (mode_) {
@@ -928,13 +915,10 @@
     case OVERWRITE_LEFT: overwrite_name = "OverwriteLeft"; break;
     default: overwrite_name = "UnknownOverwrite"; break;
   }
-
-  OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
-               "BinaryOpStub_%s_%s_%s",
-               op_name,
-               overwrite_name,
-               BinaryOpIC::GetName(operands_type_));
-  return name_;
+  stream->Add("BinaryOpStub_%s_%s_%s",
+              op_name,
+              overwrite_name,
+              BinaryOpIC::GetName(operands_type_));
 }
 
 
@@ -4380,9 +4364,7 @@
 
 void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
   Label invoke, exit;
-#ifdef ENABLE_LOGGING_AND_PROFILING
   Label not_outermost_js, not_outermost_js_2;
-#endif
 
   // Setup frame.
   __ push(ebp);
@@ -4401,7 +4383,6 @@
   ExternalReference c_entry_fp(Isolate::k_c_entry_fp_address, masm->isolate());
   __ push(Operand::StaticVariable(c_entry_fp));
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
   // If this is the outermost JS call, set js_entry_sp value.
   ExternalReference js_entry_sp(Isolate::k_js_entry_sp_address,
                                 masm->isolate());
@@ -4414,7 +4395,6 @@
   __ bind(&not_outermost_js);
   __ push(Immediate(Smi::FromInt(StackFrame::INNER_JSENTRY_FRAME)));
   __ bind(&cont);
-#endif
 
   // Call a faked try-block that does the invoke.
   __ call(&invoke);
@@ -4462,7 +4442,6 @@
   __ PopTryHandler();
 
   __ bind(&exit);
-#ifdef ENABLE_LOGGING_AND_PROFILING
   // Check if the current stack frame is marked as the outermost JS frame.
   __ pop(ebx);
   __ cmp(Operand(ebx),
@@ -4470,7 +4449,6 @@
   __ j(not_equal, &not_outermost_js_2);
   __ mov(Operand::StaticVariable(js_entry_sp), Immediate(0));
   __ bind(&not_outermost_js_2);
-#endif
 
   // Restore the top frame descriptor from the stack.
   __ pop(Operand::StaticVariable(ExternalReference(
@@ -4732,15 +4710,8 @@
 
 // Unfortunately you have to run without snapshots to see most of these
 // names in the profile since most compare stubs end up in the snapshot.
-const char* CompareStub::GetName() {
+void CompareStub::PrintName(StringStream* stream) {
   ASSERT(lhs_.is(no_reg) && rhs_.is(no_reg));
-
-  if (name_ != NULL) return name_;
-  const int kMaxNameLength = 100;
-  name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
-      kMaxNameLength);
-  if (name_ == NULL) return "OOM";
-
   const char* cc_name;
   switch (cc_) {
     case less: cc_name = "LT"; break;
@@ -4751,35 +4722,12 @@
     case not_equal: cc_name = "NE"; break;
     default: cc_name = "UnknownCondition"; break;
   }
-
-  const char* strict_name = "";
-  if (strict_ && (cc_ == equal || cc_ == not_equal)) {
-    strict_name = "_STRICT";
-  }
-
-  const char* never_nan_nan_name = "";
-  if (never_nan_nan_ && (cc_ == equal || cc_ == not_equal)) {
-    never_nan_nan_name = "_NO_NAN";
-  }
-
-  const char* include_number_compare_name = "";
-  if (!include_number_compare_) {
-    include_number_compare_name = "_NO_NUMBER";
-  }
-
-  const char* include_smi_compare_name = "";
-  if (!include_smi_compare_) {
-    include_smi_compare_name = "_NO_SMI";
-  }
-
-  OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
-               "CompareStub_%s%s%s%s%s",
-               cc_name,
-               strict_name,
-               never_nan_nan_name,
-               include_number_compare_name,
-               include_smi_compare_name);
-  return name_;
+  bool is_equality = cc_ == equal || cc_ == not_equal;
+  stream->Add("CompareStub_%s", cc_name);
+  if (strict_ && is_equality) stream->Add("_STRICT");
+  if (never_nan_nan_ && is_equality) stream->Add("_NO_NAN");
+  if (!include_number_compare_) stream->Add("_NO_NUMBER");
+  if (!include_smi_compare_) stream->Add("_NO_SMI");
 }
 
 
diff --git a/src/ia32/code-stubs-ia32.h b/src/ia32/code-stubs-ia32.h
index 816f9b8..fa255da 100644
--- a/src/ia32/code-stubs-ia32.h
+++ b/src/ia32/code-stubs-ia32.h
@@ -67,8 +67,7 @@
               UnaryOpIC::TypeInfo operand_type = UnaryOpIC::UNINITIALIZED)
       : op_(op),
         mode_(mode),
-        operand_type_(operand_type),
-        name_(NULL) {
+        operand_type_(operand_type) {
   }
 
  private:
@@ -78,19 +77,7 @@
   // Operand type information determined at runtime.
   UnaryOpIC::TypeInfo operand_type_;
 
-  char* name_;
-
-  virtual const char* GetName();
-
-#ifdef DEBUG
-  void Print() {
-    PrintF("UnaryOpStub %d (op %s), (mode %d, runtime_type_info %s)\n",
-           MinorKey(),
-           Token::String(op_),
-           static_cast<int>(mode_),
-           UnaryOpIC::GetName(operand_type_));
-  }
-#endif
+  virtual void PrintName(StringStream* stream);
 
   class ModeBits: public BitField<UnaryOverwriteMode, 0, 1> {};
   class OpBits: public BitField<Token::Value, 1, 7> {};
@@ -153,8 +140,7 @@
       : op_(op),
         mode_(mode),
         operands_type_(BinaryOpIC::UNINITIALIZED),
-        result_type_(BinaryOpIC::UNINITIALIZED),
-        name_(NULL) {
+        result_type_(BinaryOpIC::UNINITIALIZED) {
     use_sse3_ = CpuFeatures::IsSupported(SSE3);
     ASSERT(OpBits::is_valid(Token::NUM_TOKENS));
   }
@@ -167,8 +153,7 @@
         mode_(ModeBits::decode(key)),
         use_sse3_(SSE3Bits::decode(key)),
         operands_type_(operands_type),
-        result_type_(result_type),
-        name_(NULL) { }
+        result_type_(result_type) { }
 
  private:
   enum SmiCodeGenerateHeapNumberResults {
@@ -184,20 +169,7 @@
   BinaryOpIC::TypeInfo operands_type_;
   BinaryOpIC::TypeInfo result_type_;
 
-  char* name_;
-
-  virtual const char* GetName();
-
-#ifdef DEBUG
-  void Print() {
-    PrintF("BinaryOpStub %d (op %s), "
-           "(mode %d, runtime_type_info %s)\n",
-           MinorKey(),
-           Token::String(op_),
-           static_cast<int>(mode_),
-           BinaryOpIC::GetName(operands_type_));
-  }
-#endif
+  virtual void PrintName(StringStream* stream);
 
   // Minor key encoding in 16 bits RRRTTTSOOOOOOOMM.
   class ModeBits: public BitField<OverwriteMode, 0, 2> {};
diff --git a/src/ia32/codegen-ia32.h b/src/ia32/codegen-ia32.h
index 8f090b1..c85fa83 100644
--- a/src/ia32/codegen-ia32.h
+++ b/src/ia32/codegen-ia32.h
@@ -53,9 +53,7 @@
   // Print the code after compiling it.
   static void PrintCode(Handle<Code> code, CompilationInfo* info);
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
   static bool ShouldGenerateLog(Expression* type);
-#endif
 
   static bool RecordPositions(MacroAssembler* masm,
                               int pos,
diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc
index 75cc4b8..f9f63a7 100644
--- a/src/ia32/full-codegen-ia32.cc
+++ b/src/ia32/full-codegen-ia32.cc
@@ -744,7 +744,7 @@
       // IDs for bailouts from optimized code.
       ASSERT(prop->obj()->AsVariableProxy() != NULL);
       { AccumulatorValueContext for_object(this);
-        EmitVariableLoad(prop->obj()->AsVariableProxy()->var());
+        EmitVariableLoad(prop->obj()->AsVariableProxy());
       }
 
       __ push(eax);
@@ -1064,7 +1064,7 @@
 
 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
   Comment cmnt(masm_, "[ VariableProxy");
-  EmitVariableLoad(expr->var());
+  EmitVariableLoad(expr);
 }
 
 
@@ -1214,7 +1214,11 @@
 }
 
 
-void FullCodeGenerator::EmitVariableLoad(Variable* var) {
+void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
+  // Record position before possible IC call.
+  SetSourcePosition(proxy->position());
+  Variable* var = proxy->var();
+
   // Three cases: non-this global variables, lookup slots, and all other
   // types of slots.
   Slot* slot = var->AsSlot();
@@ -1540,7 +1544,7 @@
     { AccumulatorValueContext context(this);
       switch (assign_type) {
         case VARIABLE:
-          EmitVariableLoad(expr->target()->AsVariableProxy()->var());
+          EmitVariableLoad(expr->target()->AsVariableProxy());
           PrepareForBailout(expr->target(), TOS_REG);
           break;
         case NAMED_PROPERTY:
@@ -1769,7 +1773,7 @@
         ASSERT(prop->obj()->AsVariableProxy() != NULL);
         ASSERT(prop->key()->AsLiteral() != NULL);
         { AccumulatorValueContext for_object(this);
-          EmitVariableLoad(prop->obj()->AsVariableProxy()->var());
+          EmitVariableLoad(prop->obj()->AsVariableProxy());
         }
         __ mov(edx, eax);
         __ SafeSet(ecx, Immediate(prop->key()->AsLiteral()->handle()));
@@ -2701,13 +2705,11 @@
   //     with '%2s' (see Logger::LogRuntime for all the formats).
   //   2 (array): Arguments to the format string.
   ASSERT_EQ(args->length(), 3);
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (CodeGenerator::ShouldGenerateLog(args->at(0))) {
     VisitForStackValue(args->at(1));
     VisitForStackValue(args->at(2));
     __ CallRuntime(Runtime::kLog, 2);
   }
-#endif
   // Finally, we're expected to leave a value on the top of the stack.
   __ mov(eax, isolate()->factory()->undefined_value());
   context()->Plug(eax);
@@ -3768,7 +3770,7 @@
   if (assign_type == VARIABLE) {
     ASSERT(expr->expression()->AsVariableProxy()->var() != NULL);
     AccumulatorValueContext context(this);
-    EmitVariableLoad(expr->expression()->AsVariableProxy()->var());
+    EmitVariableLoad(expr->expression()->AsVariableProxy());
   } else {
     // Reserve space for result of postfix operation.
     if (expr->is_postfix() && !context()->IsEffect()) {
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
index 2f1b88e..6293718 100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -1345,6 +1345,7 @@
 
   BinaryOpStub stub(instr->op(), NO_OVERWRITE);
   CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
+  __ nop();  // Signals no inlined code.
 }
 
 
diff --git a/src/isolate.cc b/src/isolate.cc
index 7423274..8a30e79 100644
--- a/src/isolate.cc
+++ b/src/isolate.cc
@@ -85,13 +85,9 @@
 #ifdef USE_SIMULATOR
   simulator_ = NULL;
 #endif
-#ifdef ENABLE_LOGGING_AND_PROFILING
   js_entry_sp_ = NULL;
   external_callback_ = NULL;
-#endif
-#ifdef ENABLE_VMSTATE_TRACKING
   current_vm_state_ = EXTERNAL;
-#endif
   try_catch_handler_address_ = NULL;
   context_ = NULL;
   thread_id_ = ThreadId::Invalid();
@@ -1279,11 +1275,9 @@
 
 
 char* Isolate::ArchiveThread(char* to) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (RuntimeProfiler::IsEnabled() && current_vm_state() == JS) {
     RuntimeProfiler::IsolateExitedJS(this);
   }
-#endif
   memcpy(to, reinterpret_cast<char*>(thread_local_top()),
          sizeof(ThreadLocalTop));
   InitializeThreadLocal();
@@ -1303,12 +1297,10 @@
   thread_local_top()->simulator_ = Simulator::current(this);
 #endif
 #endif
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (RuntimeProfiler::IsEnabled() && current_vm_state() == JS) {
     RuntimeProfiler::IsolateEnteredJS(this);
   }
   ASSERT(context() == NULL || context()->IsContext());
-#endif
   return from + sizeof(ThreadLocalTop);
 }
 
@@ -1627,7 +1619,6 @@
 #define C(name) isolate_addresses_[Isolate::k_##name] =                        \
     reinterpret_cast<Address>(name());
   ISOLATE_ADDRESS_LIST(C)
-  ISOLATE_ADDRESS_LIST_PROF(C)
 #undef C
 
   string_tracker_ = new StringTracker();
diff --git a/src/isolate.h b/src/isolate.h
index a4af136..f2281aa 100644
--- a/src/isolate.h
+++ b/src/isolate.h
@@ -125,14 +125,8 @@
   C(c_entry_fp_address)                    \
   C(context_address)                       \
   C(pending_exception_address)             \
-  C(external_caught_exception_address)
-
-#ifdef ENABLE_LOGGING_AND_PROFILING
-#define ISOLATE_ADDRESS_LIST_PROF(C)       \
+  C(external_caught_exception_address)     \
   C(js_entry_sp_address)
-#else
-#define ISOLATE_ADDRESS_LIST_PROF(C)
-#endif
 
 
 // Platform-independent, reliable thread identifier.
@@ -252,14 +246,9 @@
 #endif
 #endif  // USE_SIMULATOR
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
   Address js_entry_sp_;  // the stack pointer of the bottom js entry frame
   Address external_callback_;  // the external callback we're currently in
-#endif
-
-#ifdef ENABLE_VMSTATE_TRACKING
   StateTag current_vm_state_;
-#endif
 
   // Generated code scratch locations.
   int32_t formal_count_;
@@ -313,18 +302,6 @@
 
 #endif
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
-#define ISOLATE_LOGGING_INIT_LIST(V)                                           \
-  V(CpuProfiler*, cpu_profiler, NULL)                                          \
-  V(HeapProfiler*, heap_profiler, NULL)
-
-#else
-
-#define ISOLATE_LOGGING_INIT_LIST(V)
-
-#endif
-
 #define ISOLATE_INIT_ARRAY_LIST(V)                                             \
   /* SerializerDeserializer state. */                                          \
   V(Object*, serialize_partial_snapshot_cache, kPartialSnapshotCacheCapacity)  \
@@ -373,8 +350,9 @@
   /* SafeStackFrameIterator activations count. */                              \
   V(int, safe_stack_iterator_counter, 0)                                       \
   V(uint64_t, enabled_cpu_features, 0)                                         \
+  V(CpuProfiler*, cpu_profiler, NULL)                                          \
+  V(HeapProfiler*, heap_profiler, NULL)                                        \
   ISOLATE_PLATFORM_INIT_LIST(V)                                                \
-  ISOLATE_LOGGING_INIT_LIST(V)                                                 \
   ISOLATE_DEBUGGER_INIT_LIST(V)
 
 class Isolate {
@@ -445,7 +423,6 @@
   enum AddressId {
 #define C(name) k_##name,
     ISOLATE_ADDRESS_LIST(C)
-    ISOLATE_ADDRESS_LIST_PROF(C)
 #undef C
     k_isolate_address_count
   };
@@ -620,7 +597,6 @@
   }
   inline Address* handler_address() { return &thread_local_top_.handler_; }
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
   // Bottom JS entry (see StackTracer::Trace in log.cc).
   static Address js_entry_sp(ThreadLocalTop* thread) {
     return thread->js_entry_sp_;
@@ -628,7 +604,6 @@
   inline Address* js_entry_sp_address() {
     return &thread_local_top_.js_entry_sp_;
   }
-#endif
 
   // Generated code scratch locations.
   void* formal_count_address() { return &thread_local_top_.formal_count_; }
@@ -945,16 +920,13 @@
 
   static const int kJSRegexpStaticOffsetsVectorSize = 50;
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
   Address external_callback() {
     return thread_local_top_.external_callback_;
   }
   void set_external_callback(Address callback) {
     thread_local_top_.external_callback_ = callback;
   }
-#endif
 
-#ifdef ENABLE_VMSTATE_TRACKING
   StateTag current_vm_state() {
     return thread_local_top_.current_vm_state_;
   }
@@ -980,7 +952,6 @@
     }
     thread_local_top_.current_vm_state_ = state;
   }
-#endif
 
   void SetData(void* data) { embedder_data_ = data; }
   void* GetData() { return embedder_data_; }
@@ -1356,10 +1327,4 @@
 
 } }  // namespace v8::internal
 
-// TODO(isolates): Get rid of these -inl.h includes and place them only where
-//                 they're needed.
-#include "allocation-inl.h"
-#include "zone-inl.h"
-#include "frames-inl.h"
-
 #endif  // V8_ISOLATE_H_
diff --git a/src/log-inl.h b/src/log-inl.h
index 02238fe..8aebbc7 100644
--- a/src/log-inl.h
+++ b/src/log-inl.h
@@ -34,8 +34,6 @@
 namespace v8 {
 namespace internal {
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
 Logger::LogEventsAndTags Logger::ToNativeByScript(Logger::LogEventsAndTags tag,
                                                   Script* script) {
   if ((tag == FUNCTION_TAG || tag == LAZY_COMPILE_TAG || tag == SCRIPT_TAG)
@@ -51,8 +49,6 @@
   }
 }
 
-#endif  // ENABLE_LOGGING_AND_PROFILING
-
 
 } }  // namespace v8::internal
 
diff --git a/src/log-utils.cc b/src/log-utils.cc
index 1bba7cd..2d1ce23 100644
--- a/src/log-utils.cc
+++ b/src/log-utils.cc
@@ -33,101 +33,14 @@
 namespace v8 {
 namespace internal {
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
 
-LogDynamicBuffer::LogDynamicBuffer(
-    int block_size, int max_size, const char* seal, int seal_size)
-    : block_size_(block_size),
-      max_size_(max_size - (max_size % block_size_)),
-      seal_(seal),
-      seal_size_(seal_size),
-      blocks_(max_size_ / block_size_ + 1),
-      write_pos_(0), block_index_(0), block_write_pos_(0), is_sealed_(false) {
-  ASSERT(BlocksCount() > 0);
-  AllocateBlock(0);
-  for (int i = 1; i < BlocksCount(); ++i) {
-    blocks_[i] = NULL;
-  }
-}
+const char* Log::kLogToTemporaryFile = "&";
 
 
-LogDynamicBuffer::~LogDynamicBuffer() {
-  for (int i = 0; i < BlocksCount(); ++i) {
-    DeleteArray(blocks_[i]);
-  }
-}
-
-
-int LogDynamicBuffer::Read(int from_pos, char* dest_buf, int buf_size) {
-  if (buf_size == 0) return 0;
-  int read_pos = from_pos;
-  int block_read_index = BlockIndex(from_pos);
-  int block_read_pos = PosInBlock(from_pos);
-  int dest_buf_pos = 0;
-  // Read until dest_buf is filled, or write_pos_ encountered.
-  while (read_pos < write_pos_ && dest_buf_pos < buf_size) {
-    const int read_size = Min(write_pos_ - read_pos,
-        Min(buf_size - dest_buf_pos, block_size_ - block_read_pos));
-    memcpy(dest_buf + dest_buf_pos,
-           blocks_[block_read_index] + block_read_pos, read_size);
-    block_read_pos += read_size;
-    dest_buf_pos += read_size;
-    read_pos += read_size;
-    if (block_read_pos == block_size_) {
-      block_read_pos = 0;
-      ++block_read_index;
-    }
-  }
-  return dest_buf_pos;
-}
-
-
-int LogDynamicBuffer::Seal() {
-  WriteInternal(seal_, seal_size_);
-  is_sealed_ = true;
-  return 0;
-}
-
-
-int LogDynamicBuffer::Write(const char* data, int data_size) {
-  if (is_sealed_) {
-    return 0;
-  }
-  if ((write_pos_ + data_size) <= (max_size_ - seal_size_)) {
-    return WriteInternal(data, data_size);
-  } else {
-    return Seal();
-  }
-}
-
-
-int LogDynamicBuffer::WriteInternal(const char* data, int data_size) {
-  int data_pos = 0;
-  while (data_pos < data_size) {
-    const int write_size =
-        Min(data_size - data_pos, block_size_ - block_write_pos_);
-    memcpy(blocks_[block_index_] + block_write_pos_, data + data_pos,
-           write_size);
-    block_write_pos_ += write_size;
-    data_pos += write_size;
-    if (block_write_pos_ == block_size_) {
-      block_write_pos_ = 0;
-      AllocateBlock(++block_index_);
-    }
-  }
-  write_pos_ += data_size;
-  return data_size;
-}
-
-// Must be the same message as in Logger::PauseProfiler.
-const char* const Log::kDynamicBufferSeal = "profiler,\"pause\"\n";
-
 Log::Log(Logger* logger)
-  : write_to_file_(false),
-    is_stopped_(false),
+  : is_stopped_(false),
     output_handle_(NULL),
     ll_output_handle_(NULL),
-    output_buffer_(NULL),
     mutex_(NULL),
     message_buffer_(NULL),
     logger_(logger) {
@@ -142,7 +55,6 @@
 
 
 void Log::Initialize() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   mutex_ = OS::CreateMutex();
   message_buffer_ = NewArray<char>(kMessageBufferSize);
 
@@ -166,19 +78,19 @@
     FLAG_prof_auto = false;
   }
 
-  bool start_logging = FLAG_log || FLAG_log_runtime || FLAG_log_api
+  bool open_log_file = FLAG_log || FLAG_log_runtime || FLAG_log_api
       || FLAG_log_code || FLAG_log_gc || FLAG_log_handles || FLAG_log_suspect
       || FLAG_log_regexp || FLAG_log_state_changes || FLAG_ll_prof;
 
-  bool open_log_file = start_logging || FLAG_prof_lazy;
-
   // If we're logging anything, we need to open the log file.
   if (open_log_file) {
     if (strcmp(FLAG_logfile, "-") == 0) {
       OpenStdout();
     } else if (strcmp(FLAG_logfile, "*") == 0) {
-      OpenMemoryBuffer();
-    } else  {
+      // Does nothing for now. Will be removed.
+    } else if (strcmp(FLAG_logfile, kLogToTemporaryFile) == 0) {
+      OpenTemporaryFile();
+    } else {
       if (strchr(FLAG_logfile, '%') != NULL ||
           !Isolate::Current()->IsDefaultIsolate()) {
         // If there's a '%' in the log file name we have to expand
@@ -222,14 +134,18 @@
       }
     }
   }
-#endif
 }
 
 
 void Log::OpenStdout() {
   ASSERT(!IsEnabled());
   output_handle_ = stdout;
-  write_to_file_ = true;
+}
+
+
+void Log::OpenTemporaryFile() {
+  ASSERT(!IsEnabled());
+  output_handle_ = i::OS::OpenTemporaryFile();
 }
 
 
@@ -244,7 +160,6 @@
 void Log::OpenFile(const char* name) {
   ASSERT(!IsEnabled());
   output_handle_ = OS::FOpen(name, OS::LogFileOpenMode);
-  write_to_file_ = true;
   if (FLAG_ll_prof) {
     // Open the low-level log file.
     size_t len = strlen(name);
@@ -257,25 +172,18 @@
 }
 
 
-void Log::OpenMemoryBuffer() {
-  ASSERT(!IsEnabled());
-  output_buffer_ = new LogDynamicBuffer(
-      kDynamicBufferBlockSize, kMaxDynamicBufferSize,
-      kDynamicBufferSeal, StrLength(kDynamicBufferSeal));
-  write_to_file_ = false;
-}
-
-
-void Log::Close() {
-  if (write_to_file_) {
-    if (output_handle_ != NULL) fclose(output_handle_);
-    output_handle_ = NULL;
-    if (ll_output_handle_ != NULL) fclose(ll_output_handle_);
-    ll_output_handle_ = NULL;
-  } else {
-    delete output_buffer_;
-    output_buffer_ = NULL;
+FILE* Log::Close() {
+  FILE* result = NULL;
+  if (output_handle_ != NULL) {
+    if (strcmp(FLAG_logfile, kLogToTemporaryFile) != 0) {
+      fclose(output_handle_);
+    } else {
+      result = output_handle_;
+    }
   }
+  output_handle_ = NULL;
+  if (ll_output_handle_ != NULL) fclose(ll_output_handle_);
+  ll_output_handle_ = NULL;
 
   DeleteArray(message_buffer_);
   message_buffer_ = NULL;
@@ -284,27 +192,7 @@
   mutex_ = NULL;
 
   is_stopped_ = false;
-}
-
-
-int Log::GetLogLines(int from_pos, char* dest_buf, int max_size) {
-  if (write_to_file_) return 0;
-  ASSERT(output_buffer_ != NULL);
-  ASSERT(from_pos >= 0);
-  ASSERT(max_size >= 0);
-  int actual_size = output_buffer_->Read(from_pos, dest_buf, max_size);
-  ASSERT(actual_size <= max_size);
-  if (actual_size == 0) return 0;
-
-  // Find previous log line boundary.
-  char* end_pos = dest_buf + actual_size - 1;
-  while (end_pos >= dest_buf && *end_pos != '\n') --end_pos;
-  actual_size = static_cast<int>(end_pos - dest_buf + 1);
-  // If the assertion below is hit, it means that there was no line end
-  // found --- something wrong has happened.
-  ASSERT(actual_size > 0);
-  ASSERT(actual_size <= max_size);
-  return actual_size;
+  return result;
 }
 
 
@@ -413,9 +301,7 @@
 
 void LogMessageBuilder::WriteToLogFile() {
   ASSERT(pos_ <= Log::kMessageBufferSize);
-  const int written = log_->write_to_file_ ?
-      log_->WriteToFile(log_->message_buffer_, pos_) :
-      log_->WriteToMemory(log_->message_buffer_, pos_);
+  const int written = log_->WriteToFile(log_->message_buffer_, pos_);
   if (written != pos_) {
     log_->stop();
     log_->logger_->LogFailure();
@@ -423,6 +309,4 @@
 }
 
 
-#endif  // ENABLE_LOGGING_AND_PROFILING
-
 } }  // namespace v8::internal
diff --git a/src/log-utils.h b/src/log-utils.h
index 81bbf77..d336d71 100644
--- a/src/log-utils.h
+++ b/src/log-utils.h
@@ -33,69 +33,11 @@
 namespace v8 {
 namespace internal {
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
 class Logger;
 
-// A memory buffer that increments its size as you write in it.  Size
-// is incremented with 'block_size' steps, never exceeding 'max_size'.
-// During growth, memory contents are never copied.  At the end of the
-// buffer an amount of memory specified in 'seal_size' is reserved.
-// When writing position reaches max_size - seal_size, buffer auto-seals
-// itself with 'seal' and allows no further writes. Data pointed by
-// 'seal' must be available during entire LogDynamicBuffer lifetime.
-//
-// An instance of this class is created dynamically by Log.
-class LogDynamicBuffer {
- public:
-  LogDynamicBuffer(
-      int block_size, int max_size, const char* seal, int seal_size);
-
-  ~LogDynamicBuffer();
-
-  // Reads contents of the buffer starting from 'from_pos'.  Upon
-  // return, 'dest_buf' is filled with the data. Actual amount of data
-  // filled is returned, it is <= 'buf_size'.
-  int Read(int from_pos, char* dest_buf, int buf_size);
-
-  // Writes 'data' to the buffer, making it larger if necessary.  If
-  // data is too big to fit in the buffer, it doesn't get written at
-  // all. In that case, buffer auto-seals itself and stops to accept
-  // any incoming writes. Returns amount of data written (it is either
-  // 'data_size', or 0, if 'data' is too big).
-  int Write(const char* data, int data_size);
-
- private:
-  void AllocateBlock(int index) {
-    blocks_[index] = NewArray<char>(block_size_);
-  }
-
-  int BlockIndex(int pos) const { return pos / block_size_; }
-
-  int BlocksCount() const { return BlockIndex(max_size_) + 1; }
-
-  int PosInBlock(int pos) const { return pos % block_size_; }
-
-  int Seal();
-
-  int WriteInternal(const char* data, int data_size);
-
-  const int block_size_;
-  const int max_size_;
-  const char* seal_;
-  const int seal_size_;
-  ScopedVector<char*> blocks_;
-  int write_pos_;
-  int block_index_;
-  int block_write_pos_;
-  bool is_sealed_;
-};
-
-
 // Functions and data for performing output of log messages.
 class Log {
  public:
-
   // Performs process-wide initialization.
   void Initialize();
 
@@ -103,18 +45,21 @@
   void stop() { is_stopped_ = true; }
 
   // Frees all resources acquired in Initialize and Open... functions.
-  void Close();
-
-  // See description in include/v8.h.
-  int GetLogLines(int from_pos, char* dest_buf, int max_size);
+  // When a temporary file is used for the log, returns its stream descriptor,
+  // leaving the file open.
+  FILE* Close();
 
   // Returns whether logging is enabled.
   bool IsEnabled() {
-    return !is_stopped_ && (output_handle_ != NULL || output_buffer_ != NULL);
+    return !is_stopped_ && output_handle_ != NULL;
   }
 
   // Size of buffer used for formatting log messages.
-  static const int kMessageBufferSize = v8::V8::kMinimumSizeForLogLinesBuffer;
+  static const int kMessageBufferSize = 2048;
+
+  // This mode is only used in tests, as temporary files are automatically
+  // deleted on close and thus can't be accessed afterwards.
+  static const char* kLogToTemporaryFile;
 
  private:
   explicit Log(Logger* logger);
@@ -125,8 +70,8 @@
   // Opens file for logging.
   void OpenFile(const char* name);
 
-  // Opens memory buffer for logging.
-  void OpenMemoryBuffer();
+  // Opens a temporary file for logging.
+  void OpenTemporaryFile();
 
   // Implementation of writing to a log file.
   int WriteToFile(const char* msg, int length) {
@@ -138,38 +83,16 @@
     return length;
   }
 
-  // Implementation of writing to a memory buffer.
-  int WriteToMemory(const char* msg, int length) {
-    ASSERT(output_buffer_ != NULL);
-    return output_buffer_->Write(msg, length);
-  }
-
-  bool write_to_file_;
-
   // Whether logging is stopped (e.g. due to insufficient resources).
   bool is_stopped_;
 
-  // When logging is active, either output_handle_ or output_buffer_ is used
-  // to store a pointer to log destination. If logging was opened via OpenStdout
-  // or OpenFile, then output_handle_ is used. If logging was opened
-  // via OpenMemoryBuffer, then output_buffer_ is used.
-  // mutex_ should be acquired before using output_handle_ or output_buffer_.
+  // When logging is active output_handle_ is used to store a pointer to log
+  // destination.  mutex_ should be acquired before using output_handle_.
   FILE* output_handle_;
 
   // Used when low-level profiling is active.
   FILE* ll_output_handle_;
 
-  LogDynamicBuffer* output_buffer_;
-
-  // Size of dynamic buffer block (and dynamic buffer initial size).
-  static const int kDynamicBufferBlockSize = 65536;
-
-  // Maximum size of dynamic buffer.
-  static const int kMaxDynamicBufferSize = 50 * 1024 * 1024;
-
-  // Message to "seal" dynamic buffer with.
-  static const char* const kDynamicBufferSeal;
-
   // mutex_ is a Mutex used for enforcing exclusive
   // access to the formatting buffer and the log file or log memory buffer.
   Mutex* mutex_;
@@ -224,8 +147,6 @@
   int pos_;
 };
 
-#endif  // ENABLE_LOGGING_AND_PROFILING
-
 } }  // namespace v8::internal
 
 #endif  // V8_LOG_UTILS_H_
diff --git a/src/log.cc b/src/log.cc
index 004e21a..04fd22e 100644
--- a/src/log.cc
+++ b/src/log.cc
@@ -43,8 +43,6 @@
 namespace v8 {
 namespace internal {
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
 //
 // Sliding state window.  Updates counters to keep track of the last
 // window of kBufferSize states.  This is useful to track where we
@@ -554,71 +552,54 @@
   msg.WriteToLogFile();
 }
 
-#endif  // ENABLE_LOGGING_AND_PROFILING
-
 
 void Logger::StringEvent(const char* name, const char* value) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (FLAG_log) UncheckedStringEvent(name, value);
-#endif
 }
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
 void Logger::UncheckedStringEvent(const char* name, const char* value) {
   if (!log_->IsEnabled()) return;
   LogMessageBuilder msg(this);
   msg.Append("%s,\"%s\"\n", name, value);
   msg.WriteToLogFile();
 }
-#endif
 
 
 void Logger::IntEvent(const char* name, int value) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (FLAG_log) UncheckedIntEvent(name, value);
-#endif
 }
 
 
 void Logger::IntPtrTEvent(const char* name, intptr_t value) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (FLAG_log) UncheckedIntPtrTEvent(name, value);
-#endif
 }
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
 void Logger::UncheckedIntEvent(const char* name, int value) {
   if (!log_->IsEnabled()) return;
   LogMessageBuilder msg(this);
   msg.Append("%s,%d\n", name, value);
   msg.WriteToLogFile();
 }
-#endif
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
 void Logger::UncheckedIntPtrTEvent(const char* name, intptr_t value) {
   if (!log_->IsEnabled()) return;
   LogMessageBuilder msg(this);
   msg.Append("%s,%" V8_PTR_PREFIX "d\n", name, value);
   msg.WriteToLogFile();
 }
-#endif
 
 
 void Logger::HandleEvent(const char* name, Object** location) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled() || !FLAG_log_handles) return;
   LogMessageBuilder msg(this);
   msg.Append("%s,0x%" V8PRIxPTR "\n", name, location);
   msg.WriteToLogFile();
-#endif
 }
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
 // ApiEvent is private so all the calls come from the Logger class.  It is the
 // caller's responsibility to ensure that log is enabled and that
 // FLAG_log_api is true.
@@ -631,11 +612,9 @@
   va_end(ap);
   msg.WriteToLogFile();
 }
-#endif
 
 
 void Logger::ApiNamedSecurityCheck(Object* key) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled() || !FLAG_log_api) return;
   if (key->IsString()) {
     SmartPointer<char> str =
@@ -646,14 +625,12 @@
   } else {
     ApiEvent("api,check-security,['no-name']\n");
   }
-#endif
 }
 
 
 void Logger::SharedLibraryEvent(const char* library_path,
                                 uintptr_t start,
                                 uintptr_t end) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled() || !FLAG_prof) return;
   LogMessageBuilder msg(this);
   msg.Append("shared-library,\"%s\",0x%08" V8PRIxPTR ",0x%08" V8PRIxPTR "\n",
@@ -661,14 +638,12 @@
              start,
              end);
   msg.WriteToLogFile();
-#endif
 }
 
 
 void Logger::SharedLibraryEvent(const wchar_t* library_path,
                                 uintptr_t start,
                                 uintptr_t end) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled() || !FLAG_prof) return;
   LogMessageBuilder msg(this);
   msg.Append("shared-library,\"%ls\",0x%08" V8PRIxPTR ",0x%08" V8PRIxPTR "\n",
@@ -676,11 +651,9 @@
              start,
              end);
   msg.WriteToLogFile();
-#endif
 }
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
 void Logger::LogRegExpSource(Handle<JSRegExp> regexp) {
   // Prints "/" + re.source + "/" +
   //      (re.global?"g":"") + (re.ignorecase?"i":"") + (re.multiline?"m":"")
@@ -721,23 +694,19 @@
 
   msg.WriteToLogFile();
 }
-#endif  // ENABLE_LOGGING_AND_PROFILING
 
 
 void Logger::RegExpCompileEvent(Handle<JSRegExp> regexp, bool in_cache) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled() || !FLAG_log_regexp) return;
   LogMessageBuilder msg(this);
   msg.Append("regexp-compile,");
   LogRegExpSource(regexp);
   msg.Append(in_cache ? ",hit\n" : ",miss\n");
   msg.WriteToLogFile();
-#endif
 }
 
 
 void Logger::LogRuntime(Vector<const char> format, JSArray* args) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled() || !FLAG_log_runtime) return;
   HandleScope scope;
   LogMessageBuilder msg(this);
@@ -778,22 +747,18 @@
   }
   msg.Append('\n');
   msg.WriteToLogFile();
-#endif
 }
 
 
 void Logger::ApiIndexedSecurityCheck(uint32_t index) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled() || !FLAG_log_api) return;
   ApiEvent("api,check-security,%u\n", index);
-#endif
 }
 
 
 void Logger::ApiNamedPropertyAccess(const char* tag,
                                     JSObject* holder,
                                     Object* name) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   ASSERT(name->IsString());
   if (!log_->IsEnabled() || !FLAG_log_api) return;
   String* class_name_obj = holder->class_name();
@@ -802,58 +767,47 @@
   SmartPointer<char> property_name =
       String::cast(name)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
   ApiEvent("api,%s,\"%s\",\"%s\"\n", tag, *class_name, *property_name);
-#endif
 }
 
 void Logger::ApiIndexedPropertyAccess(const char* tag,
                                       JSObject* holder,
                                       uint32_t index) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled() || !FLAG_log_api) return;
   String* class_name_obj = holder->class_name();
   SmartPointer<char> class_name =
       class_name_obj->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
   ApiEvent("api,%s,\"%s\",%u\n", tag, *class_name, index);
-#endif
 }
 
 void Logger::ApiObjectAccess(const char* tag, JSObject* object) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled() || !FLAG_log_api) return;
   String* class_name_obj = object->class_name();
   SmartPointer<char> class_name =
       class_name_obj->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
   ApiEvent("api,%s,\"%s\"\n", tag, *class_name);
-#endif
 }
 
 
 void Logger::ApiEntryCall(const char* name) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled() || !FLAG_log_api) return;
   ApiEvent("api,%s\n", name);
-#endif
 }
 
 
 void Logger::NewEvent(const char* name, void* object, size_t size) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled() || !FLAG_log) return;
   LogMessageBuilder msg(this);
   msg.Append("new,%s,0x%" V8PRIxPTR ",%u\n", name, object,
              static_cast<unsigned int>(size));
   msg.WriteToLogFile();
-#endif
 }
 
 
 void Logger::DeleteEvent(const char* name, void* object) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled() || !FLAG_log) return;
   LogMessageBuilder msg(this);
   msg.Append("delete,%s,0x%" V8PRIxPTR "\n", name, object);
   msg.WriteToLogFile();
-#endif
 }
 
 
@@ -866,7 +820,6 @@
   LOGGER->DeleteEvent(name, object);
 }
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
 void Logger::CallbackEventInternal(const char* prefix, const char* name,
                                    Address entry_point) {
   if (!log_->IsEnabled() || !FLAG_log_code) return;
@@ -879,43 +832,35 @@
   msg.Append('\n');
   msg.WriteToLogFile();
 }
-#endif
 
 
 void Logger::CallbackEvent(String* name, Address entry_point) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled() || !FLAG_log_code) return;
   SmartPointer<char> str =
       name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
   CallbackEventInternal("", *str, entry_point);
-#endif
 }
 
 
 void Logger::GetterCallbackEvent(String* name, Address entry_point) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled() || !FLAG_log_code) return;
   SmartPointer<char> str =
       name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
   CallbackEventInternal("get ", *str, entry_point);
-#endif
 }
 
 
 void Logger::SetterCallbackEvent(String* name, Address entry_point) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled() || !FLAG_log_code) return;
   SmartPointer<char> str =
       name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
   CallbackEventInternal("set ", *str, entry_point);
-#endif
 }
 
 
 void Logger::CodeCreateEvent(LogEventsAndTags tag,
                              Code* code,
                              const char* comment) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled()) return;
   if (FLAG_ll_prof || Serializer::enabled()) {
     name_buffer_->Reset();
@@ -945,14 +890,12 @@
   msg.Append('"');
   msg.Append('\n');
   msg.WriteToLogFile();
-#endif
 }
 
 
 void Logger::CodeCreateEvent(LogEventsAndTags tag,
                              Code* code,
                              String* name) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled()) return;
   if (FLAG_ll_prof || Serializer::enabled()) {
     name_buffer_->Reset();
@@ -977,11 +920,9 @@
   msg.Append('"');
   msg.Append('\n');
   msg.WriteToLogFile();
-#endif
 }
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
 // ComputeMarker must only be used when SharedFunctionInfo is known.
 static const char* ComputeMarker(Code* code) {
   switch (code->kind()) {
@@ -990,14 +931,12 @@
     default: return "";
   }
 }
-#endif
 
 
 void Logger::CodeCreateEvent(LogEventsAndTags tag,
                              Code* code,
                              SharedFunctionInfo* shared,
                              String* name) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled()) return;
   if (FLAG_ll_prof || Serializer::enabled()) {
     name_buffer_->Reset();
@@ -1029,7 +968,6 @@
   msg.Append(",%s", ComputeMarker(code));
   msg.Append('\n');
   msg.WriteToLogFile();
-#endif
 }
 
 
@@ -1040,7 +978,6 @@
                              Code* code,
                              SharedFunctionInfo* shared,
                              String* source, int line) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled()) return;
   if (FLAG_ll_prof || Serializer::enabled()) {
     name_buffer_->Reset();
@@ -1078,12 +1015,10 @@
   msg.Append(",%s", ComputeMarker(code));
   msg.Append('\n');
   msg.WriteToLogFile();
-#endif
 }
 
 
 void Logger::CodeCreateEvent(LogEventsAndTags tag, Code* code, int args_count) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled()) return;
   if (FLAG_ll_prof || Serializer::enabled()) {
     name_buffer_->Reset();
@@ -1106,21 +1041,17 @@
   msg.Append(",%d,\"args_count: %d\"", code->ExecutableSize(), args_count);
   msg.Append('\n');
   msg.WriteToLogFile();
-#endif
 }
 
 
 void Logger::CodeMovingGCEvent() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled() || !FLAG_ll_prof) return;
   LowLevelLogWriteBytes(&kCodeMovingGCTag, sizeof(kCodeMovingGCTag));
   OS::SignalCodeMovingGC();
-#endif
 }
 
 
 void Logger::RegExpCodeCreateEvent(Code* code, String* source) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled()) return;
   if (FLAG_ll_prof || Serializer::enabled()) {
     name_buffer_->Reset();
@@ -1145,36 +1076,30 @@
   msg.Append('\"');
   msg.Append('\n');
   msg.WriteToLogFile();
-#endif
 }
 
 
 void Logger::CodeMoveEvent(Address from, Address to) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled()) return;
   if (FLAG_ll_prof) LowLevelCodeMoveEvent(from, to);
   if (Serializer::enabled() && address_to_name_map_ != NULL) {
     address_to_name_map_->Move(from, to);
   }
   MoveEventInternal(CODE_MOVE_EVENT, from, to);
-#endif
 }
 
 
 void Logger::CodeDeleteEvent(Address from) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled()) return;
   if (FLAG_ll_prof) LowLevelCodeDeleteEvent(from);
   if (Serializer::enabled() && address_to_name_map_ != NULL) {
     address_to_name_map_->Remove(from);
   }
   DeleteEventInternal(CODE_DELETE_EVENT, from);
-#endif
 }
 
 
 void Logger::SnapshotPositionEvent(Address addr, int pos) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled()) return;
   if (FLAG_ll_prof) LowLevelSnapshotPositionEvent(addr, pos);
   if (Serializer::enabled() && address_to_name_map_ != NULL) {
@@ -1196,18 +1121,14 @@
   msg.Append(",%d", pos);
   msg.Append('\n');
   msg.WriteToLogFile();
-#endif
 }
 
 
 void Logger::SharedFunctionInfoMoveEvent(Address from, Address to) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   MoveEventInternal(SHARED_FUNC_MOVE_EVENT, from, to);
-#endif
 }
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
 void Logger::MoveEventInternal(LogEventsAndTags event,
                                Address from,
                                Address to) {
@@ -1220,10 +1141,8 @@
   msg.Append('\n');
   msg.WriteToLogFile();
 }
-#endif
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
 void Logger::DeleteEventInternal(LogEventsAndTags event, Address from) {
   if (!log_->IsEnabled() || !FLAG_log_code) return;
   LogMessageBuilder msg(this);
@@ -1232,11 +1151,9 @@
   msg.Append('\n');
   msg.WriteToLogFile();
 }
-#endif
 
 
 void Logger::ResourceEvent(const char* name, const char* tag) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled() || !FLAG_log) return;
   LogMessageBuilder msg(this);
   msg.Append("%s,%s,", name, tag);
@@ -1249,12 +1166,10 @@
 
   msg.Append('\n');
   msg.WriteToLogFile();
-#endif
 }
 
 
 void Logger::SuspectReadEvent(String* name, Object* obj) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled() || !FLAG_log_suspect) return;
   LogMessageBuilder msg(this);
   String* class_name = obj->IsJSObject()
@@ -1268,12 +1183,10 @@
   msg.Append('"');
   msg.Append('\n');
   msg.WriteToLogFile();
-#endif
 }
 
 
 void Logger::HeapSampleBeginEvent(const char* space, const char* kind) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled() || !FLAG_log_gc) return;
   LogMessageBuilder msg(this);
   // Using non-relative system time in order to be able to synchronize with
@@ -1281,42 +1194,34 @@
   msg.Append("heap-sample-begin,\"%s\",\"%s\",%.0f\n",
              space, kind, OS::TimeCurrentMillis());
   msg.WriteToLogFile();
-#endif
 }
 
 
 void Logger::HeapSampleEndEvent(const char* space, const char* kind) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled() || !FLAG_log_gc) return;
   LogMessageBuilder msg(this);
   msg.Append("heap-sample-end,\"%s\",\"%s\"\n", space, kind);
   msg.WriteToLogFile();
-#endif
 }
 
 
 void Logger::HeapSampleItemEvent(const char* type, int number, int bytes) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled() || !FLAG_log_gc) return;
   LogMessageBuilder msg(this);
   msg.Append("heap-sample-item,%s,%d,%d\n", type, number, bytes);
   msg.WriteToLogFile();
-#endif
 }
 
 
 void Logger::DebugTag(const char* call_site_tag) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled() || !FLAG_log) return;
   LogMessageBuilder msg(this);
   msg.Append("debug-tag,%s\n", call_site_tag);
   msg.WriteToLogFile();
-#endif
 }
 
 
 void Logger::DebugEvent(const char* event_type, Vector<uint16_t> parameter) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled() || !FLAG_log) return;
   StringBuilder s(parameter.length() + 1);
   for (int i = 0; i < parameter.length(); ++i) {
@@ -1330,11 +1235,9 @@
              parameter_string);
   DeleteArray(parameter_string);
   msg.WriteToLogFile();
-#endif
 }
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
 void Logger::TickEvent(TickSample* sample, bool overflow) {
   if (!log_->IsEnabled() || !FLAG_prof) return;
   LogMessageBuilder msg(this);
@@ -1378,7 +1281,6 @@
           ticker_->Stop();
         }
         FLAG_log_code = false;
-        // Must be the same message as Log::kDynamicBufferSeal.
         LOG(ISOLATE, UncheckedStringEvent("profiler", "pause"));
       }
       --logging_nesting_;
@@ -1420,11 +1322,6 @@
 }
 
 
-int Logger::GetLogLines(int from_pos, char* dest_buf, int max_size) {
-  return log_->GetLogLines(from_pos, dest_buf, max_size);
-}
-
-
 class EnumerateOptimizedFunctionsVisitor: public OptimizedFunctionVisitor {
  public:
   EnumerateOptimizedFunctionsVisitor(Handle<SharedFunctionInfo>* sfis,
@@ -1545,7 +1442,6 @@
 
 
 void Logger::LogCodeInfo() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled() || !FLAG_ll_prof) return;
 #if V8_TARGET_ARCH_IA32
   const char arch[] = "ia32";
@@ -1557,7 +1453,6 @@
   const char arch[] = "unknown";
 #endif
   LowLevelLogWriteBytes(arch, sizeof(arch));
-#endif  // ENABLE_LOGGING_AND_PROFILING
 }
 
 
@@ -1710,11 +1605,8 @@
   }
 }
 
-#endif
-
 
 bool Logger::Setup() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   // Tests and EnsureInitialize() can call this twice in a row. It's harmless.
   if (is_initialized_) return true;
   is_initialized_ = true;
@@ -1766,40 +1658,27 @@
   }
 
   return true;
-
-#else
-  return false;
-#endif
 }
 
 
 Sampler* Logger::sampler() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   return ticker_;
-#else
-  return NULL;
-#endif
 }
 
 
 void Logger::EnsureTickerStarted() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   ASSERT(ticker_ != NULL);
   if (!ticker_->IsActive()) ticker_->Start();
-#endif
 }
 
 
 void Logger::EnsureTickerStopped() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (ticker_ != NULL && ticker_->IsActive()) ticker_->Stop();
-#endif
 }
 
 
-void Logger::TearDown() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
-  if (!is_initialized_) return;
+FILE* Logger::TearDown() {
+  if (!is_initialized_) return NULL;
   is_initialized_ = false;
 
   // Stop the profiler before closing the file.
@@ -1815,13 +1694,11 @@
   delete ticker_;
   ticker_ = NULL;
 
-  log_->Close();
-#endif
+  return log_->Close();
 }
 
 
 void Logger::EnableSlidingStateWindow() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   // If the ticker is NULL, Logger::Setup has not been called yet.  In
   // that case, we set the sliding_state_window flag so that the
   // sliding window computation will be started when Logger::Setup is
@@ -1835,7 +1712,6 @@
   if (sliding_state_window_ == NULL) {
     sliding_state_window_ = new SlidingStateWindow(Isolate::Current());
   }
-#endif
 }
 
 
@@ -1855,10 +1731,8 @@
 
 
 static void ComputeCpuProfiling(Sampler* sampler, void* flag_ptr) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   bool* flag = reinterpret_cast<bool*>(flag_ptr);
   *flag |= sampler->IsProfiling();
-#endif
 }
 
 
diff --git a/src/log.h b/src/log.h
index 6ffd18c..0225059 100644
--- a/src/log.h
+++ b/src/log.h
@@ -78,7 +78,6 @@
 class Ticker;
 
 #undef LOG
-#ifdef ENABLE_LOGGING_AND_PROFILING
 #define LOG(isolate, Call)                          \
   do {                                              \
     v8::internal::Logger* logger =                  \
@@ -86,9 +85,6 @@
     if (logger->is_logging())                       \
       logger->Call;                                 \
   } while (false)
-#else
-#define LOG(isolate, Call) ((void) 0)
-#endif
 
 #define LOG_EVENTS_AND_TAGS_LIST(V)                                     \
   V(CODE_CREATION_EVENT,            "code-creation")                    \
@@ -161,7 +157,9 @@
   Sampler* sampler();
 
   // Frees resources acquired in Setup.
-  void TearDown();
+  // When a temporary file is used for the log, returns its stream descriptor,
+  // leaving the file open.
+  FILE* TearDown();
 
   // Enable the computation of a sliding window of states.
   void EnableSlidingStateWindow();
@@ -272,7 +270,6 @@
   // Log an event reported from generated code
   void LogRuntime(Vector<const char> format, JSArray* args);
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
   bool is_logging() {
     return logging_nesting_ > 0;
   }
@@ -284,10 +281,6 @@
   void ResumeProfiler();
   bool IsProfilerPaused();
 
-  // If logging is performed into a memory buffer, allows to
-  // retrieve previously written messages. See v8.h.
-  int GetLogLines(int from_pos, char* dest_buf, int max_size);
-
   // Logs all compiled functions found in the heap.
   void LogCompiledFunctions();
   // Logs all accessor callbacks found in the heap.
@@ -424,9 +417,6 @@
   Address prev_code_;
 
   friend class CpuProfiler;
-#else
-  bool is_logging() { return false; }
-#endif
 };
 
 
diff --git a/src/mark-compact.cc b/src/mark-compact.cc
index 5792f6c..8e2fe2f 100644
--- a/src/mark-compact.cc
+++ b/src/mark-compact.cc
@@ -3255,11 +3255,9 @@
     GDBJITInterface::RemoveCode(reinterpret_cast<Code*>(obj));
   }
 #endif
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (obj->IsCode()) {
     PROFILE(isolate, CodeDeleteEvent(obj->address()));
   }
-#endif
 }
 
 
diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc
index 273afb7..d03443f 100644
--- a/src/mips/code-stubs-mips.cc
+++ b/src/mips/code-stubs-mips.cc
@@ -1797,25 +1797,17 @@
 }
 
 
-const char* UnaryOpStub::GetName() {
-  if (name_ != NULL) return name_;
-  const int kMaxNameLength = 100;
-  name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
-      kMaxNameLength);
-  if (name_ == NULL) return "OOM";
+void UnaryOpStub::PrintName(StringStream* stream) {
   const char* op_name = Token::Name(op_);
   const char* overwrite_name = NULL;  // Make g++ happy.
   switch (mode_) {
     case UNARY_NO_OVERWRITE: overwrite_name = "Alloc"; break;
     case UNARY_OVERWRITE: overwrite_name = "Overwrite"; break;
   }
-
-  OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
-               "UnaryOpStub_%s_%s_%s",
-               op_name,
-               overwrite_name,
-               UnaryOpIC::GetName(operand_type_));
-  return name_;
+  stream->Add("UnaryOpStub_%s_%s_%s",
+              op_name,
+              overwrite_name,
+              UnaryOpIC::GetName(operand_type_));
 }
 
 
@@ -2154,12 +2146,7 @@
 }
 
 
-const char* BinaryOpStub::GetName() {
-  if (name_ != NULL) return name_;
-  const int kMaxNameLength = 100;
-  name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
-      kMaxNameLength);
-  if (name_ == NULL) return "OOM";
+void BinaryOpStub::PrintName(StringStream* stream) {
   const char* op_name = Token::Name(op_);
   const char* overwrite_name;
   switch (mode_) {
@@ -2168,13 +2155,10 @@
     case OVERWRITE_LEFT: overwrite_name = "OverwriteLeft"; break;
     default: overwrite_name = "UnknownOverwrite"; break;
   }
-
-  OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
-               "BinaryOpStub_%s_%s_%s",
-               op_name,
-               overwrite_name,
-               BinaryOpIC::GetName(operands_type_));
-  return name_;
+  stream->Add("BinaryOpStub_%s_%s_%s",
+              op_name,
+              overwrite_name,
+              BinaryOpIC::GetName(operands_type_));
 }
 
 
@@ -3743,24 +3727,22 @@
   // 4 args slots
   // args
 
-  #ifdef ENABLE_LOGGING_AND_PROFILING
-    // If this is the outermost JS call, set js_entry_sp value.
-    Label non_outermost_js;
-    ExternalReference js_entry_sp(Isolate::k_js_entry_sp_address,
-                                  masm->isolate());
-    __ li(t1, Operand(ExternalReference(js_entry_sp)));
-    __ lw(t2, MemOperand(t1));
-    __ Branch(&non_outermost_js, ne, t2, Operand(zero_reg));
-    __ sw(fp, MemOperand(t1));
-    __ li(t0, Operand(Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME)));
-    Label cont;
-    __ b(&cont);
-    __ nop();   // Branch delay slot nop.
-    __ bind(&non_outermost_js);
-    __ li(t0, Operand(Smi::FromInt(StackFrame::INNER_JSENTRY_FRAME)));
-    __ bind(&cont);
-    __ push(t0);
-  #endif
+  // If this is the outermost JS call, set js_entry_sp value.
+  Label non_outermost_js;
+  ExternalReference js_entry_sp(Isolate::k_js_entry_sp_address,
+                                masm->isolate());
+  __ li(t1, Operand(ExternalReference(js_entry_sp)));
+  __ lw(t2, MemOperand(t1));
+  __ Branch(&non_outermost_js, ne, t2, Operand(zero_reg));
+  __ sw(fp, MemOperand(t1));
+  __ li(t0, Operand(Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME)));
+  Label cont;
+  __ b(&cont);
+  __ nop();   // Branch delay slot nop.
+  __ bind(&non_outermost_js);
+  __ li(t0, Operand(Smi::FromInt(StackFrame::INNER_JSENTRY_FRAME)));
+  __ bind(&cont);
+  __ push(t0);
 
   // Call a faked try-block that does the invoke.
   __ bal(&invoke);  // bal exposes branch delay slot.
@@ -3829,16 +3811,14 @@
   __ PopTryHandler();
 
   __ bind(&exit);  // v0 holds result
-  #ifdef ENABLE_LOGGING_AND_PROFILING
-    // Check if the current stack frame is marked as the outermost JS frame.
-    Label non_outermost_js_2;
-    __ pop(t1);
-    __ Branch(&non_outermost_js_2, ne, t1,
-              Operand(Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME)));
-    __ li(t1, Operand(ExternalReference(js_entry_sp)));
-    __ sw(zero_reg, MemOperand(t1));
-    __ bind(&non_outermost_js_2);
-  #endif
+  // Check if the current stack frame is marked as the outermost JS frame.
+  Label non_outermost_js_2;
+  __ pop(t1);
+  __ Branch(&non_outermost_js_2, ne, t1,
+            Operand(Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME)));
+  __ li(t1, Operand(ExternalReference(js_entry_sp)));
+  __ sw(zero_reg, MemOperand(t1));
+  __ bind(&non_outermost_js_2);
 
   // Restore the top frame descriptors from the stack.
   __ pop(t1);
@@ -4940,16 +4920,9 @@
 
 // Unfortunately you have to run without snapshots to see most of these
 // names in the profile since most compare stubs end up in the snapshot.
-const char* CompareStub::GetName() {
+void CompareStub::PrintName(StringStream* stream) {
   ASSERT((lhs_.is(a0) && rhs_.is(a1)) ||
          (lhs_.is(a1) && rhs_.is(a0)));
-
-  if (name_ != NULL) return name_;
-  const int kMaxNameLength = 100;
-  name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
-      kMaxNameLength);
-  if (name_ == NULL) return "OOM";
-
   const char* cc_name;
   switch (cc_) {
     case lt: cc_name = "LT"; break;
@@ -4960,40 +4933,14 @@
     case ne: cc_name = "NE"; break;
     default: cc_name = "UnknownCondition"; break;
   }
-
-  const char* lhs_name = lhs_.is(a0) ? "_a0" : "_a1";
-  const char* rhs_name = rhs_.is(a0) ? "_a0" : "_a1";
-
-  const char* strict_name = "";
-  if (strict_ && (cc_ == eq || cc_ == ne)) {
-    strict_name = "_STRICT";
-  }
-
-  const char* never_nan_nan_name = "";
-  if (never_nan_nan_ && (cc_ == eq || cc_ == ne)) {
-    never_nan_nan_name = "_NO_NAN";
-  }
-
-  const char* include_number_compare_name = "";
-  if (!include_number_compare_) {
-    include_number_compare_name = "_NO_NUMBER";
-  }
-
-  const char* include_smi_compare_name = "";
-  if (!include_smi_compare_) {
-    include_smi_compare_name = "_NO_SMI";
-  }
-
-  OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
-               "CompareStub_%s%s%s%s%s%s",
-               cc_name,
-               lhs_name,
-               rhs_name,
-               strict_name,
-               never_nan_nan_name,
-               include_number_compare_name,
-               include_smi_compare_name);
-  return name_;
+  bool is_equality = cc_ == eq || cc_ == ne;
+  stream->Add("CompareStub_%s", cc_name);
+  stream->Add(lhs_.is(a0) ? "_a0" : "_a1");
+  stream->Add(rhs_.is(a0) ? "_a0" : "_a1");
+  if (strict_ && is_equality) stream->Add("_STRICT");
+  if (never_nan_nan_ && is_equality) stream->Add("_NO_NAN");
+  if (!include_number_compare_) stream->Add("_NO_NUMBER");
+  if (!include_smi_compare_) stream->Add("_NO_SMI");
 }
 
 
diff --git a/src/mips/code-stubs-mips.h b/src/mips/code-stubs-mips.h
index 3eaed44..aa224bc 100644
--- a/src/mips/code-stubs-mips.h
+++ b/src/mips/code-stubs-mips.h
@@ -66,8 +66,7 @@
               UnaryOpIC::TypeInfo operand_type = UnaryOpIC::UNINITIALIZED)
       : op_(op),
         mode_(mode),
-        operand_type_(operand_type),
-        name_(NULL) {
+        operand_type_(operand_type) {
   }
 
  private:
@@ -77,19 +76,7 @@
   // Operand type information determined at runtime.
   UnaryOpIC::TypeInfo operand_type_;
 
-  char* name_;
-
-  virtual const char* GetName();
-
-#ifdef DEBUG
-  void Print() {
-    PrintF("UnaryOpStub %d (op %s), (mode %d, runtime_type_info %s)\n",
-           MinorKey(),
-           Token::String(op_),
-           static_cast<int>(mode_),
-           UnaryOpIC::GetName(operand_type_));
-  }
-#endif
+  virtual void PrintName(StringStream* stream);
 
   class ModeBits: public BitField<UnaryOverwriteMode, 0, 1> {};
   class OpBits: public BitField<Token::Value, 1, 7> {};
@@ -143,8 +130,7 @@
       : op_(op),
         mode_(mode),
         operands_type_(BinaryOpIC::UNINITIALIZED),
-        result_type_(BinaryOpIC::UNINITIALIZED),
-        name_(NULL) {
+        result_type_(BinaryOpIC::UNINITIALIZED) {
     use_fpu_ = CpuFeatures::IsSupported(FPU);
     ASSERT(OpBits::is_valid(Token::NUM_TOKENS));
   }
@@ -157,8 +143,7 @@
         mode_(ModeBits::decode(key)),
         use_fpu_(FPUBits::decode(key)),
         operands_type_(operands_type),
-        result_type_(result_type),
-        name_(NULL) { }
+        result_type_(result_type) { }
 
  private:
   enum SmiCodeGenerateHeapNumberResults {
@@ -174,20 +159,7 @@
   BinaryOpIC::TypeInfo operands_type_;
   BinaryOpIC::TypeInfo result_type_;
 
-  char* name_;
-
-  virtual const char* GetName();
-
-#ifdef DEBUG
-  void Print() {
-    PrintF("BinaryOpStub %d (op %s), "
-           "(mode %d, runtime_type_info %s)\n",
-           MinorKey(),
-           Token::String(op_),
-           static_cast<int>(mode_),
-           BinaryOpIC::GetName(operands_type_));
-  }
-#endif
+  virtual void PrintName(StringStream* stream);
 
   // Minor key encoding in 16 bits RRRTTTVOOOOOOOMM.
   class ModeBits: public BitField<OverwriteMode, 0, 2> {};
diff --git a/src/mips/codegen-mips.h b/src/mips/codegen-mips.h
index fecd321..a8de9c8 100644
--- a/src/mips/codegen-mips.h
+++ b/src/mips/codegen-mips.h
@@ -60,9 +60,7 @@
   // Print the code after compiling it.
   static void PrintCode(Handle<Code> code, CompilationInfo* info);
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
   static bool ShouldGenerateLog(Expression* type);
-#endif
 
   static void SetFunctionInfo(Handle<JSFunction> fun,
                               FunctionLiteral* lit,
diff --git a/src/mips/full-codegen-mips.cc b/src/mips/full-codegen-mips.cc
index 2645bdd..3f5ea7b 100644
--- a/src/mips/full-codegen-mips.cc
+++ b/src/mips/full-codegen-mips.cc
@@ -783,7 +783,7 @@
       // IDs for bailouts from optimized code.
       ASSERT(prop->obj()->AsVariableProxy() != NULL);
       { AccumulatorValueContext for_object(this);
-        EmitVariableLoad(prop->obj()->AsVariableProxy()->var());
+        EmitVariableLoad(prop->obj()->AsVariableProxy());
       }
 
       __ push(result_register());
@@ -1117,7 +1117,7 @@
 
 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
   Comment cmnt(masm_, "[ VariableProxy");
-  EmitVariableLoad(expr->var());
+  EmitVariableLoad(expr);
 }
 
 
@@ -1262,7 +1262,11 @@
 }
 
 
-void FullCodeGenerator::EmitVariableLoad(Variable* var) {
+void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
+  // Record position before possible IC call.
+  SetSourcePosition(proxy->position());
+  Variable* var = proxy->var();
+
   // Three cases: non-this global variables, lookup slots, and all other
   // types of slots.
   Slot* slot = var->AsSlot();
@@ -1598,7 +1602,7 @@
     { AccumulatorValueContext context(this);
       switch (assign_type) {
         case VARIABLE:
-          EmitVariableLoad(expr->target()->AsVariableProxy()->var());
+          EmitVariableLoad(expr->target()->AsVariableProxy());
           PrepareForBailout(expr->target(), TOS_REG);
           break;
         case NAMED_PROPERTY:
@@ -2780,13 +2784,12 @@
   //     with '%2s' (see Logger::LogRuntime for all the formats).
   //   2 (array): Arguments to the format string.
   ASSERT_EQ(args->length(), 3);
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (CodeGenerator::ShouldGenerateLog(args->at(0))) {
     VisitForStackValue(args->at(1));
     VisitForStackValue(args->at(2));
     __ CallRuntime(Runtime::kLog, 2);
   }
-#endif
+
   // Finally, we're expected to leave a value on the top of the stack.
   __ LoadRoot(v0, Heap::kUndefinedValueRootIndex);
   context()->Plug(v0);
@@ -3839,7 +3842,7 @@
   if (assign_type == VARIABLE) {
     ASSERT(expr->expression()->AsVariableProxy()->var() != NULL);
     AccumulatorValueContext context(this);
-    EmitVariableLoad(expr->expression()->AsVariableProxy()->var());
+    EmitVariableLoad(expr->expression()->AsVariableProxy());
   } else {
     // Reserve space for result of postfix operation.
     if (expr->is_postfix() && !context()->IsEffect()) {
diff --git a/src/mksnapshot.cc b/src/mksnapshot.cc
index 1ed6103..c5ce12f 100644
--- a/src/mksnapshot.cc
+++ b/src/mksnapshot.cc
@@ -296,10 +296,9 @@
 
 
 int main(int argc, char** argv) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   // By default, log code create information in the snapshot.
   i::FLAG_log_code = true;
-#endif
+
   // Print the usage if an error occurs when parsing the command line
   // flags or if the help flag is set.
   int result = i::FlagList::SetFlagsFromCommandLine(&argc, argv, true);
diff --git a/src/objects.cc b/src/objects.cc
index 44741fd..ca780db 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -1883,13 +1883,9 @@
        pt = pt->GetPrototype()) {
     JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result);
     if (result->IsProperty()) {
-      if (result->IsReadOnly()) {
-        result->NotFound();
-        return;
-      }
-      if (result->type() == CALLBACKS) {
-        return;
-      }
+      if (result->type() == CALLBACKS && !result->IsReadOnly()) return;
+      // Found non-callback or read-only callback, stop looking.
+      break;
     }
   }
   result->NotFound();
@@ -2273,10 +2269,10 @@
 
 
 MaybeObject* JSObject::SetPropertyForResult(LookupResult* result,
-                                   String* name,
-                                   Object* value,
-                                   PropertyAttributes attributes,
-                                   StrictModeFlag strict_mode) {
+                                            String* name,
+                                            Object* value,
+                                            PropertyAttributes attributes,
+                                            StrictModeFlag strict_mode) {
   Heap* heap = GetHeap();
   // Make sure that the top context does not change when doing callbacks or
   // interceptor calls.
@@ -4122,6 +4118,8 @@
         }
       }
       if (!map_done) continue;
+    } else {
+      map_or_index_field = NULL;
     }
     // That was the regular transitions, now for the prototype transitions.
     FixedArray* prototype_transitions =
diff --git a/src/platform-cygwin.cc b/src/platform-cygwin.cc
index 0242f7b..5f283c3 100644
--- a/src/platform-cygwin.cc
+++ b/src/platform-cygwin.cc
@@ -166,23 +166,6 @@
 }
 
 
-#ifdef ENABLE_HEAP_PROTECTION
-
-void OS::Protect(void* address, size_t size) {
-  // TODO(1240712): mprotect has a return value which is ignored here.
-  mprotect(address, size, PROT_READ);
-}
-
-
-void OS::Unprotect(void* address, size_t size, bool is_executable) {
-  // TODO(1240712): mprotect has a return value which is ignored here.
-  int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0);
-  mprotect(address, size, prot);
-}
-
-#endif
-
-
 void OS::Sleep(int milliseconds) {
   unsigned int ms = static_cast<unsigned int>(milliseconds);
   usleep(1000 * ms);
@@ -249,7 +232,6 @@
 
 
 void OS::LogSharedLibraryAddresses() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   // This function assumes that the layout of the file is as follows:
   // hex_start_addr-hex_end_addr rwxp <unused data> [binary_file_name]
   // If we encounter an unexpected situation we abort scanning further entries.
@@ -306,7 +288,6 @@
   }
   free(lib_name);
   fclose(fp);
-#endif
 }
 
 
@@ -591,8 +572,6 @@
 }
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
 // ----------------------------------------------------------------------------
 // Cygwin profiler support.
 //
@@ -769,7 +748,5 @@
   SetActive(false);
 }
 
-#endif  // ENABLE_LOGGING_AND_PROFILING
 
 } }  // namespace v8::internal
-
diff --git a/src/platform-freebsd.cc b/src/platform-freebsd.cc
index 755475a..9d9f1b7 100644
--- a/src/platform-freebsd.cc
+++ b/src/platform-freebsd.cc
@@ -181,20 +181,6 @@
 }
 
 
-#ifdef ENABLE_HEAP_PROTECTION
-
-void OS::Protect(void* address, size_t size) {
-  UNIMPLEMENTED();
-}
-
-
-void OS::Unprotect(void* address, size_t size, bool is_executable) {
-  UNIMPLEMENTED();
-}
-
-#endif
-
-
 void OS::Sleep(int milliseconds) {
   unsigned int ms = static_cast<unsigned int>(milliseconds);
   usleep(1000 * ms);
@@ -266,15 +252,12 @@
 }
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
 static unsigned StringToLong(char* buffer) {
   return static_cast<unsigned>(strtol(buffer, NULL, 16));  // NOLINT
 }
-#endif
 
 
 void OS::LogSharedLibraryAddresses() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   static const int MAP_LENGTH = 1024;
   int fd = open("/proc/self/maps", O_RDONLY);
   if (fd < 0) return;
@@ -311,7 +294,6 @@
     LOG(i::Isolate::Current(), SharedLibraryEvent(start_of_path, start, end));
   }
   close(fd);
-#endif
 }
 
 
@@ -588,8 +570,6 @@
 }
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
 static pthread_t GetThreadID() {
   pthread_t thread_id = pthread_self();
   return thread_id;
@@ -817,6 +797,5 @@
   SetActive(false);
 }
 
-#endif  // ENABLE_LOGGING_AND_PROFILING
 
 } }  // namespace v8::internal
diff --git a/src/platform-linux.cc b/src/platform-linux.cc
index d2866ca..ab22a79 100644
--- a/src/platform-linux.cc
+++ b/src/platform-linux.cc
@@ -390,23 +390,6 @@
 }
 
 
-#ifdef ENABLE_HEAP_PROTECTION
-
-void OS::Protect(void* address, size_t size) {
-  // TODO(1240712): mprotect has a return value which is ignored here.
-  mprotect(address, size, PROT_READ);
-}
-
-
-void OS::Unprotect(void* address, size_t size, bool is_executable) {
-  // TODO(1240712): mprotect has a return value which is ignored here.
-  int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0);
-  mprotect(address, size, prot);
-}
-
-#endif
-
-
 void OS::Sleep(int milliseconds) {
   unsigned int ms = static_cast<unsigned int>(milliseconds);
   usleep(1000 * ms);
@@ -483,7 +466,6 @@
 
 
 void OS::LogSharedLibraryAddresses() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   // This function assumes that the layout of the file is as follows:
   // hex_start_addr-hex_end_addr rwxp <unused data> [binary_file_name]
   // If we encounter an unexpected situation we abort scanning further entries.
@@ -540,7 +522,6 @@
   }
   free(lib_name);
   fclose(fp);
-#endif
 }
 
 
@@ -548,7 +529,6 @@
 
 
 void OS::SignalCodeMovingGC() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   // Support for ll_prof.py.
   //
   // The Linux profiler built into the kernel logs all mmap's with
@@ -564,7 +544,6 @@
   ASSERT(addr != MAP_FAILED);
   munmap(addr, size);
   fclose(f);
-#endif
 }
 
 
@@ -859,8 +838,6 @@
 }
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
 #if !defined(__GLIBC__) && (defined(__arm__) || defined(__thumb__))
 // Android runs a fairly new Linux kernel, so signal info is there,
 // but the C library doesn't have the structs defined.
@@ -1148,6 +1125,5 @@
   SetActive(false);
 }
 
-#endif  // ENABLE_LOGGING_AND_PROFILING
 
 } }  // namespace v8::internal
diff --git a/src/platform-macos.cc b/src/platform-macos.cc
index 104729a..be6e157 100644
--- a/src/platform-macos.cc
+++ b/src/platform-macos.cc
@@ -169,20 +169,6 @@
 }
 
 
-#ifdef ENABLE_HEAP_PROTECTION
-
-void OS::Protect(void* address, size_t size) {
-  UNIMPLEMENTED();
-}
-
-
-void OS::Unprotect(void* address, size_t size, bool is_executable) {
-  UNIMPLEMENTED();
-}
-
-#endif
-
-
 void OS::Sleep(int milliseconds) {
   usleep(1000 * milliseconds);
 }
@@ -248,7 +234,6 @@
 
 
 void OS::LogSharedLibraryAddresses() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   unsigned int images_count = _dyld_image_count();
   for (unsigned int i = 0; i < images_count; ++i) {
     const mach_header* header = _dyld_get_image_header(i);
@@ -270,7 +255,6 @@
     LOG(Isolate::Current(),
         SharedLibraryEvent(_dyld_get_image_name(i), start, start + size));
   }
-#endif  // ENABLE_LOGGING_AND_PROFILING
 }
 
 
@@ -644,8 +628,6 @@
 }
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
 class Sampler::PlatformData : public Malloced {
  public:
   PlatformData() : profiled_thread_(mach_thread_self()) {}
@@ -821,6 +803,5 @@
   SetActive(false);
 }
 
-#endif  // ENABLE_LOGGING_AND_PROFILING
 
 } }  // namespace v8::internal
diff --git a/src/platform-nullos.cc b/src/platform-nullos.cc
index d309806..08480ca 100644
--- a/src/platform-nullos.cc
+++ b/src/platform-nullos.cc
@@ -217,20 +217,6 @@
 }
 
 
-#ifdef ENABLE_HEAP_PROTECTION
-
-void OS::Protect(void* address, size_t size) {
-  UNIMPLEMENTED();
-}
-
-
-void OS::Unprotect(void* address, size_t size, bool is_executable) {
-  UNIMPLEMENTED();
-}
-
-#endif
-
-
 void OS::Sleep(int milliseconds) {
   UNIMPLEMENTED();
 }
@@ -437,7 +423,6 @@
   return new NullSemaphore(count);
 }
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
 
 class ProfileSampler::PlatformData  : public Malloced {
  public:
@@ -472,6 +457,5 @@
   UNIMPLEMENTED();
 }
 
-#endif  // ENABLE_LOGGING_AND_PROFILING
 
 } }  // namespace v8::internal
diff --git a/src/platform-openbsd.cc b/src/platform-openbsd.cc
index ceabb51..973329b 100644
--- a/src/platform-openbsd.cc
+++ b/src/platform-openbsd.cc
@@ -179,20 +179,6 @@
 }
 
 
-#ifdef ENABLE_HEAP_PROTECTION
-
-void OS::Protect(void* address, size_t size) {
-  UNIMPLEMENTED();
-}
-
-
-void OS::Unprotect(void* address, size_t size, bool is_executable) {
-  UNIMPLEMENTED();
-}
-
-#endif
-
-
 void OS::Sleep(int milliseconds) {
   unsigned int ms = static_cast<unsigned int>(milliseconds);
   usleep(1000 * ms);
@@ -264,15 +250,12 @@
 }
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
 static unsigned StringToLong(char* buffer) {
   return static_cast<unsigned>(strtol(buffer, NULL, 16));  // NOLINT
 }
-#endif
 
 
 void OS::LogSharedLibraryAddresses() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   static const int MAP_LENGTH = 1024;
   int fd = open("/proc/self/maps", O_RDONLY);
   if (fd < 0) return;
@@ -309,7 +292,6 @@
     LOG(i::Isolate::Current(), SharedLibraryEvent(start_of_path, start, end));
   }
   close(fd);
-#endif
 }
 
 
@@ -590,8 +572,6 @@
 }
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
 static pthread_t GetThreadID() {
   pthread_t thread_id = pthread_self();
   return thread_id;
@@ -818,6 +798,5 @@
   SetActive(false);
 }
 
-#endif  // ENABLE_LOGGING_AND_PROFILING
 
 } }  // namespace v8::internal
diff --git a/src/platform-posix.cc b/src/platform-posix.cc
index 83f6c81..5be305a 100644
--- a/src/platform-posix.cc
+++ b/src/platform-posix.cc
@@ -37,6 +37,7 @@
 #include <sys/resource.h>
 #include <sys/time.h>
 #include <sys/types.h>
+#include <sys/stat.h>
 
 #include <arpa/inet.h>
 #include <netinet/in.h>
@@ -130,7 +131,14 @@
 //
 
 FILE* OS::FOpen(const char* path, const char* mode) {
-  return fopen(path, mode);
+  FILE* file = fopen(path, mode);
+  if (file == NULL) return NULL;
+  struct stat file_stat;
+  if (fstat(fileno(file), &file_stat) != 0) return NULL;
+  bool is_regular_file = ((file_stat.st_mode & S_IFREG) != 0);
+  if (is_regular_file) return file;
+  fclose(file);
+  return NULL;
 }
 
 
@@ -139,6 +147,11 @@
 }
 
 
+FILE* OS::OpenTemporaryFile() {
+  return tmpfile();
+}
+
+
 const char* const OS::LogFileOpenMode = "w";
 
 
diff --git a/src/platform-solaris.cc b/src/platform-solaris.cc
index ca15b07..1e79f10 100644
--- a/src/platform-solaris.cc
+++ b/src/platform-solaris.cc
@@ -192,23 +192,6 @@
 }
 
 
-#ifdef ENABLE_HEAP_PROTECTION
-
-void OS::Protect(void* address, size_t size) {
-  // TODO(1240712): mprotect has a return value which is ignored here.
-  mprotect(address, size, PROT_READ);
-}
-
-
-void OS::Unprotect(void* address, size_t size, bool is_executable) {
-  // TODO(1240712): mprotect has a return value which is ignored here.
-  int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0);
-  mprotect(address, size, prot);
-}
-
-#endif
-
-
 void OS::Sleep(int milliseconds) {
   useconds_t ms = static_cast<useconds_t>(milliseconds);
   usleep(1000 * ms);
@@ -589,8 +572,6 @@
 }
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
 static pthread_t GetThreadID() {
   return pthread_self();
 }
@@ -817,6 +798,4 @@
   SetActive(false);
 }
 
-#endif  // ENABLE_LOGGING_AND_PROFILING
-
 } }  // namespace v8::internal
diff --git a/src/platform-tls.h b/src/platform-tls.h
index 5649175..3251663 100644
--- a/src/platform-tls.h
+++ b/src/platform-tls.h
@@ -30,7 +30,7 @@
 #ifndef V8_PLATFORM_TLS_H_
 #define V8_PLATFORM_TLS_H_
 
-#ifdef V8_FAST_TLS
+#ifndef V8_NO_FAST_TLS
 
 // When fast TLS is requested we include the appropriate
 // implementation header.
diff --git a/src/platform-win32.cc b/src/platform-win32.cc
index b403b37..35b1a8e 100644
--- a/src/platform-win32.cc
+++ b/src/platform-win32.cc
@@ -740,6 +740,24 @@
 }
 
 
+FILE* OS::OpenTemporaryFile() {
+  // tmpfile_s tries to use the root dir, don't use it.
+  char tempPathBuffer[MAX_PATH];
+  DWORD path_result = 0;
+  path_result = GetTempPathA(MAX_PATH, tempPathBuffer);
+  if (path_result > MAX_PATH || path_result == 0) return NULL;
+  UINT name_result = 0;
+  char tempNameBuffer[MAX_PATH];
+  name_result = GetTempFileNameA(tempPathBuffer, "", 0, tempNameBuffer);
+  if (name_result == 0) return NULL;
+  FILE* result = FOpen(tempNameBuffer, "w+");  // Same mode as tmpfile uses.
+  if (result != NULL) {
+    Remove(tempNameBuffer);  // Delete on close.
+  }
+  return result;
+}
+
+
 // Open log file in binary mode to avoid /n -> /r/n conversion.
 const char* const OS::LogFileOpenMode = "wb";
 
@@ -939,25 +957,6 @@
 }
 
 
-#ifdef ENABLE_HEAP_PROTECTION
-
-void OS::Protect(void* address, size_t size) {
-  // TODO(1240712): VirtualProtect has a return value which is ignored here.
-  DWORD old_protect;
-  VirtualProtect(address, size, PAGE_READONLY, &old_protect);
-}
-
-
-void OS::Unprotect(void* address, size_t size, bool is_executable) {
-  // TODO(1240712): VirtualProtect has a return value which is ignored here.
-  DWORD new_protect = is_executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
-  DWORD old_protect;
-  VirtualProtect(address, size, new_protect, &old_protect);
-}
-
-#endif
-
-
 void OS::Sleep(int milliseconds) {
   ::Sleep(milliseconds);
 }
@@ -1858,8 +1857,6 @@
 }
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
 // ----------------------------------------------------------------------------
 // Win32 profiler support.
 
@@ -2034,6 +2031,5 @@
   SetActive(false);
 }
 
-#endif  // ENABLE_LOGGING_AND_PROFILING
 
 } }  // namespace v8::internal
diff --git a/src/platform.h b/src/platform.h
index 06d3ca4..c7fe984 100644
--- a/src/platform.h
+++ b/src/platform.h
@@ -177,6 +177,9 @@
   static FILE* FOpen(const char* path, const char* mode);
   static bool Remove(const char* path);
 
+  // Opens a temporary file, the file is auto removed on close.
+  static FILE* OpenTemporaryFile();
+
   // Log file open mode is platform-dependent due to line ends issues.
   static const char* const LogFileOpenMode;
 
@@ -206,12 +209,6 @@
   // Get the Alignment guaranteed by Allocate().
   static size_t AllocateAlignment();
 
-#ifdef ENABLE_HEAP_PROTECTION
-  // Protect/unprotect a block of memory by marking it read-only/writable.
-  static void Protect(void* address, size_t size);
-  static void Unprotect(void* address, size_t size, bool is_executable);
-#endif
-
   // Returns an indication of whether a pointer is in a space that
   // has been allocated by Allocate().  This method may conservatively
   // always return false, but giving more accurate information may
@@ -603,7 +600,6 @@
   bool has_external_callback : 1;
 };
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
 class Sampler {
  public:
   // Initialize sampler.
@@ -662,8 +658,6 @@
 };
 
 
-#endif  // ENABLE_LOGGING_AND_PROFILING
-
 } }  // namespace v8::internal
 
 #endif  // V8_PLATFORM_H_
diff --git a/src/profile-generator-inl.h b/src/profile-generator-inl.h
index 747e5c7..8f4bc6c 100644
--- a/src/profile-generator-inl.h
+++ b/src/profile-generator-inl.h
@@ -28,8 +28,6 @@
 #ifndef V8_PROFILE_GENERATOR_INL_H_
 #define V8_PROFILE_GENERATOR_INL_H_
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
 #include "profile-generator.h"
 
 namespace v8 {
@@ -123,6 +121,4 @@
 
 } }  // namespace v8::internal
 
-#endif  // ENABLE_LOGGING_AND_PROFILING
-
 #endif  // V8_PROFILE_GENERATOR_INL_H_
diff --git a/src/profile-generator.cc b/src/profile-generator.cc
index 34d7aa6..07426f2 100644
--- a/src/profile-generator.cc
+++ b/src/profile-generator.cc
@@ -25,8 +25,6 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
 #include "v8.h"
 
 #include "profile-generator-inl.h"
@@ -3259,5 +3257,3 @@
 }
 
 } }  // namespace v8::internal
-
-#endif  // ENABLE_LOGGING_AND_PROFILING
diff --git a/src/profile-generator.h b/src/profile-generator.h
index 3d0584b..d1c2b38 100644
--- a/src/profile-generator.h
+++ b/src/profile-generator.h
@@ -28,8 +28,6 @@
 #ifndef V8_PROFILE_GENERATOR_H_
 #define V8_PROFILE_GENERATOR_H_
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
 #include "allocation.h"
 #include "hashmap.h"
 #include "../include/v8-profiler.h"
@@ -1126,6 +1124,4 @@
 
 } }  // namespace v8::internal
 
-#endif  // ENABLE_LOGGING_AND_PROFILING
-
 #endif  // V8_PROFILE_GENERATOR_H_
diff --git a/src/property.h b/src/property.h
index 87f9ea3..ddecc92 100644
--- a/src/property.h
+++ b/src/property.h
@@ -206,6 +206,7 @@
     lookup_type_ = HANDLER_TYPE;
     holder_ = NULL;
     details_ = PropertyDetails(NONE, HANDLER);
+    cacheable_ = false;
   }
 
   void InterceptorResult(JSObject* holder) {
diff --git a/src/proxy.js b/src/proxy.js
index cb9c020..27524bd 100644
--- a/src/proxy.js
+++ b/src/proxy.js
@@ -135,3 +135,15 @@
 function DerivedHasTrap(name) {
   return !!this.getPropertyDescriptor(name)
 }
+
+function DerivedKeysTrap() {
+  var names = this.getOwnPropertyNames()
+  var enumerableNames = []
+  for (var i = 0, count = 0; i < names.length; ++i) {
+    var name = names[i]
+    if (this.getOwnPropertyDescriptor(TO_STRING_INLINE(name)).enumerable) {
+      enumerableNames[count++] = names[i]
+    }
+  }
+  return enumerableNames
+}
diff --git a/src/runtime-profiler.cc b/src/runtime-profiler.cc
index 7a0dd91..917f6d0 100644
--- a/src/runtime-profiler.cc
+++ b/src/runtime-profiler.cc
@@ -61,9 +61,7 @@
 Atomic32 RuntimeProfiler::state_ = 0;
 // TODO(isolates): Create the semaphore lazily and clean it up when no
 // longer required.
-#ifdef ENABLE_LOGGING_AND_PROFILING
 Semaphore* RuntimeProfiler::semaphore_ = OS::CreateSemaphore(0);
-#endif
 
 #ifdef DEBUG
 bool RuntimeProfiler::has_been_globally_setup_ = false;
@@ -245,9 +243,7 @@
 
 
 void RuntimeProfiler::NotifyTick() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   isolate_->stack_guard()->RequestRuntimeProfilerTick();
-#endif
 }
 
 
@@ -295,7 +291,6 @@
 
 
 void RuntimeProfiler::HandleWakeUp(Isolate* isolate) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   // The profiler thread must still be waiting.
   ASSERT(NoBarrier_Load(&state_) >= 0);
   // In IsolateEnteredJS we have already incremented the counter and
@@ -303,7 +298,6 @@
   // to get the right count of active isolates.
   NoBarrier_AtomicIncrement(&state_, 1);
   semaphore_->Signal();
-#endif
 }
 
 
@@ -313,18 +307,15 @@
 
 
 bool RuntimeProfiler::WaitForSomeIsolateToEnterJS() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   Atomic32 old_state = NoBarrier_CompareAndSwap(&state_, 0, -1);
   ASSERT(old_state >= -1);
   if (old_state != 0) return false;
   semaphore_->Wait();
-#endif
   return true;
 }
 
 
 void RuntimeProfiler::StopRuntimeProfilerThreadBeforeShutdown(Thread* thread) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   // Do a fake increment. If the profiler is waiting on the semaphore,
   // the returned state is 0, which can be left as an initial state in
   // case profiling is restarted later. If the profiler is not
@@ -343,7 +334,6 @@
   if (new_state != 0) {
     NoBarrier_AtomicIncrement(&state_, -1);
   }
-#endif
 }
 
 
@@ -365,11 +355,9 @@
 
 
 bool RuntimeProfilerRateLimiter::SuspendIfNecessary() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (!RuntimeProfiler::IsSomeIsolateInJS()) {
     return RuntimeProfiler::WaitForSomeIsolateToEnterJS();
   }
-#endif
   return false;
 }
 
diff --git a/src/runtime.cc b/src/runtime.cc
index 117e5ab..56507ae 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -12145,7 +12145,6 @@
 #endif  // ENABLE_DEBUGGER_SUPPORT
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
 RUNTIME_FUNCTION(MaybeObject*, Runtime_ProfilerResume) {
   NoHandleAllocation ha;
   v8::V8::ResumeProfiler();
@@ -12159,7 +12158,6 @@
   return isolate->heap()->undefined_value();
 }
 
-#endif  // ENABLE_LOGGING_AND_PROFILING
 
 // Finds the script object from the script data. NOTE: This operation uses
 // heap traversal to find the function generated for the source position
diff --git a/src/runtime.h b/src/runtime.h
index 0900fd3..e59c82c 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -349,7 +349,10 @@
   F(HasExternalIntElements, 1, 1) \
   F(HasExternalUnsignedIntElements, 1, 1) \
   F(HasExternalFloatElements, 1, 1) \
-  F(HasExternalDoubleElements, 1, 1)
+  F(HasExternalDoubleElements, 1, 1) \
+  /* profiler */ \
+  F(ProfilerResume, 0, 1) \
+  F(ProfilerPause, 0, 1)
 
 
 #ifdef ENABLE_DEBUGGER_SUPPORT
@@ -427,14 +430,6 @@
 #define RUNTIME_FUNCTION_LIST_DEBUGGER_SUPPORT(F)
 #endif
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-#define RUNTIME_FUNCTION_LIST_PROFILER_SUPPORT(F) \
-  F(ProfilerResume, 0, 1) \
-  F(ProfilerPause, 0, 1)
-#else
-#define RUNTIME_FUNCTION_LIST_PROFILER_SUPPORT(F)
-#endif
-
 #ifdef DEBUG
 #define RUNTIME_FUNCTION_LIST_DEBUG(F) \
   /* Testing */ \
@@ -452,8 +447,7 @@
   RUNTIME_FUNCTION_LIST_ALWAYS_1(F) \
   RUNTIME_FUNCTION_LIST_ALWAYS_2(F) \
   RUNTIME_FUNCTION_LIST_DEBUG(F) \
-  RUNTIME_FUNCTION_LIST_DEBUGGER_SUPPORT(F) \
-  RUNTIME_FUNCTION_LIST_PROFILER_SUPPORT(F)
+  RUNTIME_FUNCTION_LIST_DEBUGGER_SUPPORT(F)
 
 // ----------------------------------------------------------------------------
 // INLINE_FUNCTION_LIST defines all inlined functions accessed
diff --git a/src/scopeinfo.cc b/src/scopeinfo.cc
index ccc2cc8..3e18368 100644
--- a/src/scopeinfo.cc
+++ b/src/scopeinfo.cc
@@ -32,6 +32,8 @@
 #include "scopeinfo.h"
 #include "scopes.h"
 
+#include "allocation-inl.h"
+
 namespace v8 {
 namespace internal {
 
diff --git a/src/scopes.cc b/src/scopes.cc
index 5546875..c6e2a46 100644
--- a/src/scopes.cc
+++ b/src/scopes.cc
@@ -34,6 +34,8 @@
 #include "prettyprinter.h"
 #include "scopeinfo.h"
 
+#include "allocation-inl.h"
+
 namespace v8 {
 namespace internal {
 
diff --git a/src/serialize.cc b/src/serialize.cc
index d960afd..8cde580 100644
--- a/src/serialize.cc
+++ b/src/serialize.cc
@@ -284,7 +284,6 @@
   const char* AddressNames[] = {
 #define C(name) "Isolate::" #name,
     ISOLATE_ADDRESS_LIST(C)
-    ISOLATE_ADDRESS_LIST_PROF(C)
     NULL
 #undef C
   };
diff --git a/src/spaces-inl.h b/src/spaces-inl.h
index 070f970..ca1177f 100644
--- a/src/spaces-inl.h
+++ b/src/spaces-inl.h
@@ -378,35 +378,6 @@
 }
 
 
-#ifdef ENABLE_HEAP_PROTECTION
-
-void MemoryAllocator::Protect(Address start, size_t size) {
-  OS::Protect(start, size);
-}
-
-
-void MemoryAllocator::Unprotect(Address start,
-                                size_t size,
-                                Executability executable) {
-  OS::Unprotect(start, size, executable);
-}
-
-
-void MemoryAllocator::ProtectChunkFromPage(Page* page) {
-  int id = GetChunkId(page);
-  OS::Protect(chunks_[id].address(), chunks_[id].size());
-}
-
-
-void MemoryAllocator::UnprotectChunkFromPage(Page* page) {
-  int id = GetChunkId(page);
-  OS::Unprotect(chunks_[id].address(), chunks_[id].size(),
-                chunks_[id].owner()->executable() == EXECUTABLE);
-}
-
-#endif
-
-
 // --------------------------------------------------------------------------
 // PagedSpace
 
diff --git a/src/spaces.cc b/src/spaces.cc
index 23c87cd..d41ce55 100644
--- a/src/spaces.cc
+++ b/src/spaces.cc
@@ -868,30 +868,6 @@
 }
 
 
-#ifdef ENABLE_HEAP_PROTECTION
-
-void PagedSpace::Protect() {
-  Page* page = first_page_;
-  while (page->is_valid()) {
-    Isolate::Current()->memory_allocator()->ProtectChunkFromPage(page);
-    page = Isolate::Current()->memory_allocator()->
-        FindLastPageInSameChunk(page)->next_page();
-  }
-}
-
-
-void PagedSpace::Unprotect() {
-  Page* page = first_page_;
-  while (page->is_valid()) {
-    Isolate::Current()->memory_allocator()->UnprotectChunkFromPage(page);
-    page = Isolate::Current()->memory_allocator()->
-        FindLastPageInSameChunk(page)->next_page();
-  }
-}
-
-#endif
-
-
 void PagedSpace::MarkAllPagesClean() {
   PageIterator it(this, PageIterator::ALL_PAGES);
   while (it.has_next()) {
@@ -1196,7 +1172,6 @@
   ASSERT(IsPowerOf2(maximum_semispace_capacity));
 
   // Allocate and setup the histogram arrays if necessary.
-#if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
   allocated_histogram_ = NewArray<HistogramInfo>(LAST_TYPE + 1);
   promoted_histogram_ = NewArray<HistogramInfo>(LAST_TYPE + 1);
 
@@ -1204,7 +1179,6 @@
                        promoted_histogram_[name].set_name(#name);
   INSTANCE_TYPE_LIST(SET_NAME)
 #undef SET_NAME
-#endif
 
   ASSERT(size == 2 * heap()->ReservedSemiSpaceSize());
   ASSERT(IsAddressAligned(start, size, 0));
@@ -1236,7 +1210,6 @@
 
 
 void NewSpace::TearDown() {
-#if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
   if (allocated_histogram_) {
     DeleteArray(allocated_histogram_);
     allocated_histogram_ = NULL;
@@ -1245,7 +1218,6 @@
     DeleteArray(promoted_histogram_);
     promoted_histogram_ = NULL;
   }
-#endif
 
   start_ = NULL;
   allocation_info_.top = NULL;
@@ -1258,24 +1230,6 @@
 }
 
 
-#ifdef ENABLE_HEAP_PROTECTION
-
-void NewSpace::Protect() {
-  heap()->isolate()->memory_allocator()->Protect(ToSpaceLow(), Capacity());
-  heap()->isolate()->memory_allocator()->Protect(FromSpaceLow(), Capacity());
-}
-
-
-void NewSpace::Unprotect() {
-  heap()->isolate()->memory_allocator()->Unprotect(ToSpaceLow(), Capacity(),
-                                                   to_space_.executable());
-  heap()->isolate()->memory_allocator()->Unprotect(FromSpaceLow(), Capacity(),
-                                                   from_space_.executable());
-}
-
-#endif
-
-
 void NewSpace::Flip() {
   SemiSpace tmp = from_space_;
   from_space_ = to_space_;
@@ -1638,7 +1592,6 @@
 
 
 // Support for statistics gathering for --heap-stats and --log-gc.
-#if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
 void NewSpace::ClearHistograms() {
   for (int i = 0; i <= LAST_TYPE; i++) {
     allocated_histogram_[i].clear();
@@ -1648,9 +1601,7 @@
 
 // Because the copying collector does not touch garbage objects, we iterate
 // the new space before a collection to get a histogram of allocated objects.
-// This only happens (1) when compiled with DEBUG and the --heap-stats flag is
-// set, or when compiled with ENABLE_LOGGING_AND_PROFILING and the --log-gc
-// flag is set.
+// This only happens when --log-gc flag is set.
 void NewSpace::CollectStatistics() {
   ClearHistograms();
   SemiSpaceIterator it(this);
@@ -1659,7 +1610,6 @@
 }
 
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
 static void DoReportStatistics(Isolate* isolate,
                                HistogramInfo* info, const char* description) {
   LOG(isolate, HeapSampleBeginEvent("NewSpace", description));
@@ -1686,7 +1636,6 @@
   }
   LOG(isolate, HeapSampleEndEvent("NewSpace", description));
 }
-#endif  // ENABLE_LOGGING_AND_PROFILING
 
 
 void NewSpace::ReportStatistics() {
@@ -1709,13 +1658,11 @@
   }
 #endif  // DEBUG
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (FLAG_log_gc) {
     Isolate* isolate = ISOLATE;
     DoReportStatistics(isolate, allocated_histogram_, "allocated");
     DoReportStatistics(isolate, promoted_histogram_, "promoted");
   }
-#endif  // ENABLE_LOGGING_AND_PROFILING
 }
 
 
@@ -1733,7 +1680,6 @@
   promoted_histogram_[type].increment_number(1);
   promoted_histogram_[type].increment_bytes(obj->Size());
 }
-#endif  // defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
 
 
 // -----------------------------------------------------------------------------
@@ -2809,31 +2755,6 @@
 }
 
 
-#ifdef ENABLE_HEAP_PROTECTION
-
-void LargeObjectSpace::Protect() {
-  LargeObjectChunk* chunk = first_chunk_;
-  while (chunk != NULL) {
-    heap()->isolate()->memory_allocator()->Protect(chunk->address(),
-                                                   chunk->size());
-    chunk = chunk->next();
-  }
-}
-
-
-void LargeObjectSpace::Unprotect() {
-  LargeObjectChunk* chunk = first_chunk_;
-  while (chunk != NULL) {
-    bool is_code = chunk->GetObject()->IsCode();
-    heap()->isolate()->memory_allocator()->Unprotect(chunk->address(),
-        chunk->size(), is_code ? EXECUTABLE : NOT_EXECUTABLE);
-    chunk = chunk->next();
-  }
-}
-
-#endif
-
-
 MaybeObject* LargeObjectSpace::AllocateRawInternal(int requested_size,
                                                    int object_size,
                                                    Executability executable) {
diff --git a/src/spaces.h b/src/spaces.h
index 4024387..c554a37 100644
--- a/src/spaces.h
+++ b/src/spaces.h
@@ -380,12 +380,6 @@
   // (e.g. see LargeObjectSpace).
   virtual intptr_t SizeOfObjects() { return Size(); }
 
-#ifdef ENABLE_HEAP_PROTECTION
-  // Protect/unprotect the space by marking it read-only/writable.
-  virtual void Protect() = 0;
-  virtual void Unprotect() = 0;
-#endif
-
 #ifdef DEBUG
   virtual void Print() = 0;
 #endif
@@ -641,17 +635,6 @@
                                   Page** last_page,
                                   Page** last_page_in_use);
 
-#ifdef ENABLE_HEAP_PROTECTION
-  // Protect/unprotect a block of memory by marking it read-only/writable.
-  inline void Protect(Address start, size_t size);
-  inline void Unprotect(Address start, size_t size,
-                        Executability executable);
-
-  // Protect/unprotect a chunk given a page in the chunk.
-  inline void ProtectChunkFromPage(Page* page);
-  inline void UnprotectChunkFromPage(Page* page);
-#endif
-
 #ifdef DEBUG
   // Reports statistic info of the space.
   void ReportStatistics();
@@ -1157,12 +1140,6 @@
   // Ensures that the capacity is at least 'capacity'. Returns false on failure.
   bool EnsureCapacity(int capacity);
 
-#ifdef ENABLE_HEAP_PROTECTION
-  // Protect/unprotect the space by marking it read-only/writable.
-  void Protect();
-  void Unprotect();
-#endif
-
 #ifdef DEBUG
   // Print meta info and objects in this space.
   virtual void Print();
@@ -1270,7 +1247,6 @@
 };
 
 
-#if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
 class NumberAndSizeInfo BASE_EMBEDDED {
  public:
   NumberAndSizeInfo() : number_(0), bytes_(0) {}
@@ -1293,9 +1269,7 @@
 
 
 // HistogramInfo class for recording a single "bar" of a histogram.  This
-// class is used for collecting statistics to print to stdout (when compiled
-// with DEBUG) or to the log file (when compiled with
-// ENABLE_LOGGING_AND_PROFILING).
+// class is used for collecting statistics to print to the log file.
 class HistogramInfo: public NumberAndSizeInfo {
  public:
   HistogramInfo() : NumberAndSizeInfo() {}
@@ -1306,7 +1280,6 @@
  private:
   const char* name_;
 };
-#endif
 
 
 // -----------------------------------------------------------------------------
@@ -1392,12 +1365,6 @@
   bool Commit();
   bool Uncommit();
 
-#ifdef ENABLE_HEAP_PROTECTION
-  // Protect/unprotect the space by marking it read-only/writable.
-  virtual void Protect() {}
-  virtual void Unprotect() {}
-#endif
-
 #ifdef DEBUG
   virtual void Print();
   virtual void Verify();
@@ -1628,12 +1595,6 @@
   template <typename StringType>
   inline void ShrinkStringAtAllocationBoundary(String* string, int len);
 
-#ifdef ENABLE_HEAP_PROTECTION
-  // Protect/unprotect the space by marking it read-only/writable.
-  virtual void Protect();
-  virtual void Unprotect();
-#endif
-
 #ifdef DEBUG
   // Verify the active semispace.
   virtual void Verify();
@@ -1641,7 +1602,6 @@
   virtual void Print() { to_space_.Print(); }
 #endif
 
-#if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
   // Iterates the active semispace to collect statistics.
   void CollectStatistics();
   // Reports previously collected statistics of the active semispace.
@@ -1654,7 +1614,6 @@
   // to space during a scavenge GC.
   void RecordAllocation(HeapObject* obj);
   void RecordPromotion(HeapObject* obj);
-#endif
 
   // Return whether the operation succeded.
   bool CommitFromSpaceIfNeeded() {
@@ -1683,10 +1642,8 @@
   AllocationInfo allocation_info_;
   AllocationInfo mc_forwarding_info_;
 
-#if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
   HistogramInfo* allocated_histogram_;
   HistogramInfo* promoted_histogram_;
-#endif
 
   // Implementation of AllocateRaw and MCAllocateRaw.
   MUST_USE_RESULT inline MaybeObject* AllocateRawInternal(
@@ -2296,12 +2253,6 @@
   // may use some memory, leaving less for large objects.
   virtual bool ReserveSpace(int bytes);
 
-#ifdef ENABLE_HEAP_PROTECTION
-  // Protect/unprotect the space by marking it read-only/writable.
-  void Protect();
-  void Unprotect();
-#endif
-
 #ifdef DEBUG
   virtual void Verify();
   virtual void Print();
diff --git a/src/string-stream.cc b/src/string-stream.cc
index aea1420..9002593 100644
--- a/src/string-stream.cc
+++ b/src/string-stream.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -30,6 +30,8 @@
 #include "factory.h"
 #include "string-stream.h"
 
+#include "allocation-inl.h"
+
 namespace v8 {
 namespace internal {
 
diff --git a/src/type-info.h b/src/type-info.h
index 75aabe8..0a8c935 100644
--- a/src/type-info.h
+++ b/src/type-info.h
@@ -30,7 +30,6 @@
 
 #include "allocation.h"
 #include "globals.h"
-#include "zone.h"
 #include "zone-inl.h"
 
 namespace v8 {
diff --git a/src/v8globals.h b/src/v8globals.h
index a23ca19..d86f299 100644
--- a/src/v8globals.h
+++ b/src/v8globals.h
@@ -395,12 +395,11 @@
 };
 
 
-// Logging and profiling.
-// A StateTag represents a possible state of the VM.  When compiled with
-// ENABLE_VMSTATE_TRACKING, the logger maintains a stack of these.
-// Creating a VMState object enters a state by pushing on the stack, and
-// destroying a VMState object leaves a state by popping the current state
-// from the stack.
+// Logging and profiling.  A StateTag represents a possible state of
+// the VM. The logger maintains a stack of these. Creating a VMState
+// object enters a state by pushing on the stack, and destroying a
+// VMState object leaves a state by popping the current state from the
+// stack.
 
 #define STATE_TAG_LIST(V) \
   V(JS)                   \
diff --git a/src/v8natives.js b/src/v8natives.js
index 831dd14..53a0317 100644
--- a/src/v8natives.js
+++ b/src/v8natives.js
@@ -308,6 +308,13 @@
 function ObjectKeys(obj) {
   if (!IS_SPEC_OBJECT(obj))
     throw MakeTypeError("obj_ctor_property_non_object", ["keys"]);
+  if (%IsJSProxy(obj)) {
+    var handler = %GetHandler(obj);
+    var keys = handler.keys;
+    if (IS_UNDEFINED(keys)) keys = DerivedKeysTrap;
+    var names = %_CallFunction(handler, keys);
+    return ToStringArray(names);
+  }
   return %LocalKeys(obj);
 }
 
@@ -585,10 +592,10 @@
       throw MakeTypeError("handler_trap_missing",
                           [handler, "getPropertyDescriptor"]);
     }
-    var descriptor = getProperty.call(handler, p);
+    var descriptor = %_CallFunction(handler, p, getProperty);
     if (IS_UNDEFINED(descriptor)) return descriptor;
     var desc = ToCompletePropertyDescriptor(descriptor);
-    if (!desc.configurable) {
+    if (!desc.isConfigurable()) {
       throw MakeTypeError("proxy_prop_not_configurable",
                           [handler, "getPropertyDescriptor", p, descriptor]);
     }
@@ -608,7 +615,7 @@
     var handler = %GetHandler(obj);
     var has = handler.has;
     if (IS_UNDEFINED(has)) has = DerivedHasTrap;
-    return ToBoolean(has.call(handler, obj, p));
+    return ToBoolean(%_CallFunction(handler, obj, p, has));
   }
   var desc = GetProperty(obj, p);
   return IS_UNDEFINED(desc) ? false : true;
@@ -617,6 +624,23 @@
 
 // ES5 section 8.12.1.
 function GetOwnProperty(obj, p) {
+  if (%IsJSProxy(obj)) {
+    var handler = %GetHandler(obj);
+    var getOwnProperty = handler.getOwnPropertyDescriptor;
+    if (IS_UNDEFINED(getOwnProperty)) {
+      throw MakeTypeError("handler_trap_missing",
+                          [handler, "getOwnPropertyDescriptor"]);
+    }
+    var descriptor = %_CallFunction(handler, p, getOwnProperty);
+    if (IS_UNDEFINED(descriptor)) return descriptor;
+    var desc = ToCompletePropertyDescriptor(descriptor);
+    if (!desc.isConfigurable()) {
+      throw MakeTypeError("proxy_prop_not_configurable",
+                          [handler, "getOwnPropertyDescriptor", p, descriptor]);
+    }
+    return desc;
+  }
+
   // GetOwnProperty returns an array indexed by the constants
   // defined in macros.py.
   // If p is not a property on obj undefined is returned.
@@ -636,7 +660,7 @@
   if (IS_UNDEFINED(defineProperty)) {
     throw MakeTypeError("handler_trap_missing", [handler, "defineProperty"]);
   }
-  var result = defineProperty.call(handler, p, attributes);
+  var result = %_CallFunction(handler, p, attributes, defineProperty);
   if (!ToBoolean(result)) {
     if (should_throw) {
       throw MakeTypeError("handler_failed", [handler, "defineProperty"]);
@@ -829,7 +853,8 @@
 // ES5 section 15.2.3.3
 function ObjectGetOwnPropertyDescriptor(obj, p) {
   if (!IS_SPEC_OBJECT(obj))
-    throw MakeTypeError("obj_ctor_property_non_object", ["getOwnPropertyDescriptor"]);
+    throw MakeTypeError("obj_ctor_property_non_object",
+                        ["getOwnPropertyDescriptor"]);
   var desc = GetOwnProperty(obj, p);
   return FromPropertyDescriptor(desc);
 }
@@ -868,7 +893,7 @@
       throw MakeTypeError("handler_trap_missing",
                           [handler, "getOwnPropertyNames"]);
     }
-    var names = getOwnPropertyNames.call(handler);
+    var names = %_CallFunction(handler, getOwnPropertyNames);
     return ToStringArray(names, "getOwnPropertyNames");
   }
 
diff --git a/src/v8utils.cc b/src/v8utils.cc
index 89f9d95..bf0e05d 100644
--- a/src/v8utils.cc
+++ b/src/v8utils.cc
@@ -110,11 +110,11 @@
 }
 
 
-char* ReadCharsFromFile(const char* filename,
+char* ReadCharsFromFile(FILE* file,
                         int* size,
                         int extra_space,
-                        bool verbose) {
-  FILE* file = OS::FOpen(filename, "rb");
+                        bool verbose,
+                        const char* filename) {
   if (file == NULL || fseek(file, 0, SEEK_END) != 0) {
     if (verbose) {
       OS::PrintError("Cannot read from file %s.\n", filename);
@@ -127,16 +127,26 @@
   rewind(file);
 
   char* result = NewArray<char>(*size + extra_space);
-  for (int i = 0; i < *size;) {
+  for (int i = 0; i < *size && feof(file) == 0;) {
     int read = static_cast<int>(fread(&result[i], 1, *size - i, file));
-    if (read <= 0) {
+    if (read != (*size - i) && ferror(file) != 0) {
       fclose(file);
       DeleteArray(result);
       return NULL;
     }
     i += read;
   }
-  fclose(file);
+  return result;
+}
+
+
+char* ReadCharsFromFile(const char* filename,
+                        int* size,
+                        int extra_space,
+                        bool verbose) {
+  FILE* file = OS::FOpen(filename, "rb");
+  char* result = ReadCharsFromFile(file, size, extra_space, verbose, filename);
+  if (file != NULL) fclose(file);
   return result;
 }
 
@@ -147,18 +157,34 @@
 }
 
 
+static Vector<const char> SetVectorContents(char* chars,
+                                            int size,
+                                            bool* exists) {
+  if (!chars) {
+    *exists = false;
+    return Vector<const char>::empty();
+  }
+  chars[size] = '\0';
+  *exists = true;
+  return Vector<const char>(chars, size);
+}
+
+
 Vector<const char> ReadFile(const char* filename,
                             bool* exists,
                             bool verbose) {
   int size;
   char* result = ReadCharsFromFile(filename, &size, 1, verbose);
-  if (!result) {
-    *exists = false;
-    return Vector<const char>::empty();
-  }
-  result[size] = '\0';
-  *exists = true;
-  return Vector<const char>(result, size);
+  return SetVectorContents(result, size, exists);
+}
+
+
+Vector<const char> ReadFile(FILE* file,
+                            bool* exists,
+                            bool verbose) {
+  int size;
+  char* result = ReadCharsFromFile(file, &size, 1, verbose, "");
+  return SetVectorContents(result, size, exists);
 }
 
 
diff --git a/src/v8utils.h b/src/v8utils.h
index 498e23d..aada521 100644
--- a/src/v8utils.h
+++ b/src/v8utils.h
@@ -188,6 +188,9 @@
 Vector<const char> ReadFile(const char* filename,
                             bool* exists,
                             bool verbose = true);
+Vector<const char> ReadFile(FILE* file,
+                            bool* exists,
+                            bool verbose = true);
 
 
 
diff --git a/src/version.cc b/src/version.cc
index 5070178..6b4bfbd 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     4
-#define BUILD_NUMBER      11
+#define BUILD_NUMBER      12
 #define PATCH_LEVEL       0
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
diff --git a/src/vm-state-inl.h b/src/vm-state-inl.h
index 1f363de..c647e56 100644
--- a/src/vm-state-inl.h
+++ b/src/vm-state-inl.h
@@ -39,7 +39,6 @@
 // logger and partially threaded through the call stack.  States are pushed by
 // VMState construction and popped by destruction.
 //
-#ifdef ENABLE_VMSTATE_TRACKING
 inline const char* StateToString(StateTag state) {
   switch (state) {
     case JS:
@@ -61,32 +60,16 @@
 
 VMState::VMState(Isolate* isolate, StateTag tag)
     : isolate_(isolate), previous_tag_(isolate->current_vm_state()) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (FLAG_log_state_changes) {
     LOG(isolate, UncheckedStringEvent("Entering", StateToString(tag)));
     LOG(isolate, UncheckedStringEvent("From", StateToString(previous_tag_)));
   }
-#endif
 
   isolate_->SetCurrentVMState(tag);
-
-#ifdef ENABLE_HEAP_PROTECTION
-  if (FLAG_protect_heap) {
-    if (tag == EXTERNAL) {
-      // We are leaving V8.
-      ASSERT(previous_tag_ != EXTERNAL);
-      isolate_->heap()->Protect();
-    } else if (previous_tag_ = EXTERNAL) {
-      // We are entering V8.
-      isolate_->heap()->Unprotect();
-    }
-  }
-#endif
 }
 
 
 VMState::~VMState() {
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (FLAG_log_state_changes) {
     LOG(isolate_,
         UncheckedStringEvent("Leaving",
@@ -94,32 +77,10 @@
     LOG(isolate_,
         UncheckedStringEvent("To", StateToString(previous_tag_)));
   }
-#endif  // ENABLE_LOGGING_AND_PROFILING
-
-#ifdef ENABLE_HEAP_PROTECTION
-  StateTag tag = isolate_->current_vm_state();
-#endif
 
   isolate_->SetCurrentVMState(previous_tag_);
-
-#ifdef ENABLE_HEAP_PROTECTION
-  if (FLAG_protect_heap) {
-    if (tag == EXTERNAL) {
-      // We are reentering V8.
-      ASSERT(previous_tag_ != EXTERNAL);
-      isolate_->heap()->Unprotect();
-    } else if (previous_tag_ == EXTERNAL) {
-      // We are leaving V8.
-      isolate_->heap()->Protect();
-    }
-  }
-#endif  // ENABLE_HEAP_PROTECTION
 }
 
-#endif  // ENABLE_VMSTATE_TRACKING
-
-
-#ifdef ENABLE_LOGGING_AND_PROFILING
 
 ExternalCallbackScope::ExternalCallbackScope(Isolate* isolate, Address callback)
     : isolate_(isolate), previous_callback_(isolate->external_callback()) {
@@ -130,8 +91,6 @@
   isolate_->set_external_callback(previous_callback_);
 }
 
-#endif  // ENABLE_LOGGING_AND_PROFILING
-
 
 } }  // namespace v8::internal
 
diff --git a/src/vm-state.h b/src/vm-state.h
index 2062340..831e2d3 100644
--- a/src/vm-state.h
+++ b/src/vm-state.h
@@ -35,7 +35,6 @@
 namespace internal {
 
 class VMState BASE_EMBEDDED {
-#ifdef ENABLE_VMSTATE_TRACKING
  public:
   inline VMState(Isolate* isolate, StateTag tag);
   inline ~VMState();
@@ -43,26 +42,16 @@
  private:
   Isolate* isolate_;
   StateTag previous_tag_;
-
-#else
- public:
-  VMState(Isolate* isolate, StateTag state) {}
-#endif
 };
 
 
 class ExternalCallbackScope BASE_EMBEDDED {
-#ifdef ENABLE_LOGGING_AND_PROFILING
  public:
   inline ExternalCallbackScope(Isolate* isolate, Address callback);
   inline ~ExternalCallbackScope();
  private:
   Isolate* isolate_;
   Address previous_callback_;
-#else
- public:
-  ExternalCallbackScope(Isolate* isolate, Address callback) {}
-#endif
 };
 
 } }  // namespace v8::internal
diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc
index 2f40251..3cf7840 100644
--- a/src/x64/code-stubs-x64.cc
+++ b/src/x64/code-stubs-x64.cc
@@ -642,25 +642,17 @@
 }
 
 
-const char* UnaryOpStub::GetName() {
-  if (name_ != NULL) return name_;
-  const int kMaxNameLength = 100;
-  name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
-      kMaxNameLength);
-  if (name_ == NULL) return "OOM";
+void UnaryOpStub::PrintName(StringStream* stream) {
   const char* op_name = Token::Name(op_);
   const char* overwrite_name = NULL;  // Make g++ happy.
   switch (mode_) {
     case UNARY_NO_OVERWRITE: overwrite_name = "Alloc"; break;
     case UNARY_OVERWRITE: overwrite_name = "Overwrite"; break;
   }
-
-  OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
-               "UnaryOpStub_%s_%s_%s",
-               op_name,
-               overwrite_name,
-               UnaryOpIC::GetName(operand_type_));
-  return name_;
+  stream->Add("UnaryOpStub_%s_%s_%s",
+              op_name,
+              overwrite_name,
+              UnaryOpIC::GetName(operand_type_));
 }
 
 
@@ -721,12 +713,7 @@
 }
 
 
-const char* BinaryOpStub::GetName() {
-  if (name_ != NULL) return name_;
-  const int kMaxNameLength = 100;
-  name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
-      kMaxNameLength);
-  if (name_ == NULL) return "OOM";
+void BinaryOpStub::PrintName(StringStream* stream) {
   const char* op_name = Token::Name(op_);
   const char* overwrite_name;
   switch (mode_) {
@@ -735,13 +722,10 @@
     case OVERWRITE_LEFT: overwrite_name = "OverwriteLeft"; break;
     default: overwrite_name = "UnknownOverwrite"; break;
   }
-
-  OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
-               "BinaryOpStub_%s_%s_%s",
-               op_name,
-               overwrite_name,
-               BinaryOpIC::GetName(operands_type_));
-  return name_;
+  stream->Add("BinaryOpStub_%s_%s_%s",
+              op_name,
+              overwrite_name,
+              BinaryOpIC::GetName(operands_type_));
 }
 
 
@@ -3450,9 +3434,7 @@
 
 void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
   Label invoke, exit;
-#ifdef ENABLE_LOGGING_AND_PROFILING
   Label not_outermost_js, not_outermost_js_2;
-#endif
   {  // NOLINT. Scope block confuses linter.
     MacroAssembler::NoRootArrayScope uninitialized_root_register(masm);
     // Setup frame.
@@ -3497,7 +3479,6 @@
     __ push(c_entry_fp_operand);
   }
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
   // If this is the outermost JS call, set js_entry_sp value.
   ExternalReference js_entry_sp(Isolate::k_js_entry_sp_address, isolate);
   __ Load(rax, js_entry_sp);
@@ -3511,7 +3492,6 @@
   __ bind(&not_outermost_js);
   __ Push(Smi::FromInt(StackFrame::INNER_JSENTRY_FRAME));
   __ bind(&cont);
-#endif
 
   // Call a faked try-block that does the invoke.
   __ call(&invoke);
@@ -3555,7 +3535,6 @@
   __ PopTryHandler();
 
   __ bind(&exit);
-#ifdef ENABLE_LOGGING_AND_PROFILING
   // Check if the current stack frame is marked as the outermost JS frame.
   __ pop(rbx);
   __ Cmp(rbx, Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME));
@@ -3563,7 +3542,6 @@
   __ movq(kScratchRegister, js_entry_sp);
   __ movq(Operand(kScratchRegister, 0), Immediate(0));
   __ bind(&not_outermost_js_2);
-#endif
 
   // Restore the top frame descriptor from the stack.
   { Operand c_entry_fp_operand = masm->ExternalOperand(c_entry_fp);
@@ -3772,15 +3750,8 @@
 
 // Unfortunately you have to run without snapshots to see most of these
 // names in the profile since most compare stubs end up in the snapshot.
-const char* CompareStub::GetName() {
+void CompareStub::PrintName(StringStream* stream) {
   ASSERT(lhs_.is(no_reg) && rhs_.is(no_reg));
-
-  if (name_ != NULL) return name_;
-  const int kMaxNameLength = 100;
-  name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
-      kMaxNameLength);
-  if (name_ == NULL) return "OOM";
-
   const char* cc_name;
   switch (cc_) {
     case less: cc_name = "LT"; break;
@@ -3791,35 +3762,12 @@
     case not_equal: cc_name = "NE"; break;
     default: cc_name = "UnknownCondition"; break;
   }
-
-  const char* strict_name = "";
-  if (strict_ && (cc_ == equal || cc_ == not_equal)) {
-    strict_name = "_STRICT";
-  }
-
-  const char* never_nan_nan_name = "";
-  if (never_nan_nan_ && (cc_ == equal || cc_ == not_equal)) {
-    never_nan_nan_name = "_NO_NAN";
-  }
-
-  const char* include_number_compare_name = "";
-  if (!include_number_compare_) {
-    include_number_compare_name = "_NO_NUMBER";
-  }
-
-  const char* include_smi_compare_name = "";
-  if (!include_smi_compare_) {
-    include_smi_compare_name = "_NO_SMI";
-  }
-
-  OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
-               "CompareStub_%s%s%s%s",
-               cc_name,
-               strict_name,
-               never_nan_nan_name,
-               include_number_compare_name,
-               include_smi_compare_name);
-  return name_;
+  bool is_equality = cc_ == equal || cc_ == not_equal;
+  stream->Add("CompareStub_%s", cc_name);
+  if (strict_ && is_equality) stream->Add("_STRICT");
+  if (never_nan_nan_ && is_equality) stream->Add("_NO_NAN");
+  if (!include_number_compare_) stream->Add("_NO_NUMBER");
+  if (!include_smi_compare_) stream->Add("_NO_SMI");
 }
 
 
diff --git a/src/x64/code-stubs-x64.h b/src/x64/code-stubs-x64.h
index ed92167..4058118 100644
--- a/src/x64/code-stubs-x64.h
+++ b/src/x64/code-stubs-x64.h
@@ -66,8 +66,7 @@
               UnaryOpIC::TypeInfo operand_type = UnaryOpIC::UNINITIALIZED)
       : op_(op),
         mode_(mode),
-        operand_type_(operand_type),
-        name_(NULL) {
+        operand_type_(operand_type) {
   }
 
  private:
@@ -77,19 +76,7 @@
   // Operand type information determined at runtime.
   UnaryOpIC::TypeInfo operand_type_;
 
-  char* name_;
-
-  virtual const char* GetName();
-
-#ifdef DEBUG
-  void Print() {
-    PrintF("UnaryOpStub %d (op %s), (mode %d, runtime_type_info %s)\n",
-           MinorKey(),
-           Token::String(op_),
-           static_cast<int>(mode_),
-           UnaryOpIC::GetName(operand_type_));
-  }
-#endif
+  virtual void PrintName(StringStream* stream);
 
   class ModeBits: public BitField<UnaryOverwriteMode, 0, 1> {};
   class OpBits: public BitField<Token::Value, 1, 7> {};
@@ -149,8 +136,7 @@
       : op_(op),
         mode_(mode),
         operands_type_(BinaryOpIC::UNINITIALIZED),
-        result_type_(BinaryOpIC::UNINITIALIZED),
-        name_(NULL) {
+        result_type_(BinaryOpIC::UNINITIALIZED) {
     ASSERT(OpBits::is_valid(Token::NUM_TOKENS));
   }
 
@@ -161,8 +147,7 @@
       : op_(OpBits::decode(key)),
         mode_(ModeBits::decode(key)),
         operands_type_(operands_type),
-        result_type_(result_type),
-        name_(NULL) { }
+        result_type_(result_type) { }
 
  private:
   enum SmiCodeGenerateHeapNumberResults {
@@ -177,20 +162,7 @@
   BinaryOpIC::TypeInfo operands_type_;
   BinaryOpIC::TypeInfo result_type_;
 
-  char* name_;
-
-  virtual const char* GetName();
-
-#ifdef DEBUG
-  void Print() {
-    PrintF("BinaryOpStub %d (op %s), "
-           "(mode %d, runtime_type_info %s)\n",
-           MinorKey(),
-           Token::String(op_),
-           static_cast<int>(mode_),
-           BinaryOpIC::GetName(operands_type_));
-  }
-#endif
+  virtual void PrintName(StringStream* stream);
 
   // Minor key encoding in 15 bits RRRTTTOOOOOOOMM.
   class ModeBits: public BitField<OverwriteMode, 0, 2> {};
diff --git a/src/x64/codegen-x64.h b/src/x64/codegen-x64.h
index 94c7850..a0648ce 100644
--- a/src/x64/codegen-x64.h
+++ b/src/x64/codegen-x64.h
@@ -58,9 +58,7 @@
   // Print the code after compiling it.
   static void PrintCode(Handle<Code> code, CompilationInfo* info);
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
   static bool ShouldGenerateLog(Expression* type);
-#endif
 
   static bool RecordPositions(MacroAssembler* masm,
                               int pos,
diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc
index 6629927..a54bff5 100644
--- a/src/x64/full-codegen-x64.cc
+++ b/src/x64/full-codegen-x64.cc
@@ -741,7 +741,7 @@
       // IDs for bailouts from optimized code.
       ASSERT(prop->obj()->AsVariableProxy() != NULL);
       { AccumulatorValueContext for_object(this);
-        EmitVariableLoad(prop->obj()->AsVariableProxy()->var());
+        EmitVariableLoad(prop->obj()->AsVariableProxy());
       }
       __ push(rax);
       VisitForAccumulatorValue(function);
@@ -1071,7 +1071,7 @@
 
 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
   Comment cmnt(masm_, "[ VariableProxy");
-  EmitVariableLoad(expr->var());
+  EmitVariableLoad(expr);
 }
 
 
@@ -1222,7 +1222,11 @@
 }
 
 
-void FullCodeGenerator::EmitVariableLoad(Variable* var) {
+void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
+  // Record position before possible IC call.
+  SetSourcePosition(proxy->position());
+  Variable* var = proxy->var();
+
   // Three cases: non-this global variables, lookup slots, and all other
   // types of slots.
   Slot* slot = var->AsSlot();
@@ -1548,7 +1552,7 @@
     { AccumulatorValueContext context(this);
       switch (assign_type) {
         case VARIABLE:
-          EmitVariableLoad(expr->target()->AsVariableProxy()->var());
+          EmitVariableLoad(expr->target()->AsVariableProxy());
           PrepareForBailout(expr->target(), TOS_REG);
           break;
         case NAMED_PROPERTY:
@@ -2664,13 +2668,11 @@
   //     with '%2s' (see Logger::LogRuntime for all the formats).
   //   2 (array): Arguments to the format string.
   ASSERT_EQ(args->length(), 3);
-#ifdef ENABLE_LOGGING_AND_PROFILING
   if (CodeGenerator::ShouldGenerateLog(args->at(0))) {
     VisitForStackValue(args->at(1));
     VisitForStackValue(args->at(2));
     __ CallRuntime(Runtime::kLog, 2);
   }
-#endif
   // Finally, we're expected to leave a value on the top of the stack.
   __ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
   context()->Plug(rax);
@@ -3746,7 +3748,7 @@
   if (assign_type == VARIABLE) {
     ASSERT(expr->expression()->AsVariableProxy()->var() != NULL);
     AccumulatorValueContext context(this);
-    EmitVariableLoad(expr->expression()->AsVariableProxy()->var());
+    EmitVariableLoad(expr->expression()->AsVariableProxy());
   } else {
     // Reserve space for result of postfix operation.
     if (expr->is_postfix() && !context()->IsEffect()) {
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
index 3ebdc7c..98667ce 100644
--- a/src/x64/lithium-codegen-x64.cc
+++ b/src/x64/lithium-codegen-x64.cc
@@ -1341,6 +1341,7 @@
 
   BinaryOpStub stub(instr->op(), NO_OVERWRITE);
   CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
+  __ nop();  // Signals no inlined code.
 }
 
 
diff --git a/src/zone.h b/src/zone.h
index a5e437f..af9c916 100644
--- a/src/zone.h
+++ b/src/zone.h
@@ -164,7 +164,7 @@
 class ZoneListAllocationPolicy {
  public:
   // Allocate 'size' bytes of memory in the zone.
-  INLINE(static void* New(int size));
+  static void* New(int size);
 
   // De-allocation attempts are silently ignored.
   static void Delete(void* p) { }
diff --git a/test/cctest/SConscript b/test/cctest/SConscript
index c3614b6..0ef5667 100644
--- a/test/cctest/SConscript
+++ b/test/cctest/SConscript
@@ -65,7 +65,6 @@
     'test-liveedit.cc',
     'test-lock.cc',
     'test-lockers.cc',
-    'test-log-utils.cc',
     'test-log.cc',
     'test-mark-compact.cc',
     'test-parsing.cc',
diff --git a/test/cctest/cctest.gyp b/test/cctest/cctest.gyp
index 1d54e8c..0a74ce3 100644
--- a/test/cctest/cctest.gyp
+++ b/test/cctest/cctest.gyp
@@ -71,7 +71,6 @@
         'test-lock.cc',
         'test-lockers.cc',
         'test-log.cc',
-        'test-log-utils.cc',
         'test-mark-compact.cc',
         'test-parsing.cc',
         'test-profile-generator.cc',
diff --git a/test/cctest/log-eq-of-logging-and-traversal.js b/test/cctest/log-eq-of-logging-and-traversal.js
new file mode 100644
index 0000000..e661efe
--- /dev/null
+++ b/test/cctest/log-eq-of-logging-and-traversal.js
@@ -0,0 +1,191 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// This is a supplementary file for test-log/EquivalenceOfLoggingAndTraversal.
+
+function parseState(s) {
+  switch (s) {
+  case "": return Profile.CodeState.COMPILED;
+  case "~": return Profile.CodeState.OPTIMIZABLE;
+  case "*": return Profile.CodeState.OPTIMIZED;
+  }
+  throw new Error("unknown code state: " + s);
+}
+
+function LogProcessor() {
+  LogReader.call(this, {
+      'code-creation': {
+          parsers: [null, parseInt, parseInt, null, 'var-args'],
+          processor: this.processCodeCreation },
+      'code-move': { parsers: [parseInt, parseInt],
+          processor: this.processCodeMove },
+      'code-delete': { parsers: [parseInt],
+          processor: this.processCodeDelete },
+      'sfi-move': { parsers: [parseInt, parseInt],
+          processor: this.processFunctionMove },
+      'shared-library': null,
+      'profiler': null,
+      'tick': null });
+  this.profile = new Profile();
+
+}
+LogProcessor.prototype.__proto__ = LogReader.prototype;
+
+LogProcessor.prototype.processCodeCreation = function(
+    type, start, size, name, maybe_func) {
+  if (type != "LazyCompile" && type != "Script" && type != "Function") return;
+  // Discard types to avoid discrepancies in "LazyCompile" vs. "Function".
+  type = "";
+  if (maybe_func.length) {
+    var funcAddr = parseInt(maybe_func[0]);
+    var state = parseState(maybe_func[1]);
+    this.profile.addFuncCode(type, name, start, size, funcAddr, state);
+  } else {
+    this.profile.addCode(type, name, start, size);
+  }
+};
+
+LogProcessor.prototype.processCodeMove = function(from, to) {
+  this.profile.moveCode(from, to);
+};
+
+LogProcessor.prototype.processCodeDelete = function(start) {
+  this.profile.deleteCode(start);
+};
+
+LogProcessor.prototype.processFunctionMove = function(from, to) {
+  this.profile.moveFunc(from, to);
+};
+
+function RunTest() {
+  // _log must be provided externally.
+  var log_lines = _log.split("\n");
+  var line, pos = 0, log_lines_length = log_lines.length;
+  if (log_lines_length < 2)
+    return "log_lines_length < 2";
+  var logging_processor = new LogProcessor();
+  for ( ; pos < log_lines_length; ++pos) {
+    line = log_lines[pos];
+    if (line === "test-logging-done,\"\"") {
+      ++pos;
+      break;
+    }
+    logging_processor.processLogLine(line);
+  }
+  logging_processor.profile.cleanUpFuncEntries();
+  var logging_entries =
+    logging_processor.profile.codeMap_.getAllDynamicEntriesWithAddresses();
+  if (logging_entries.length === 0)
+    return "logging_entries.length === 0";
+  var traversal_processor = new LogProcessor();
+  for ( ; pos < log_lines_length; ++pos) {
+    line = log_lines[pos];
+    if (line === "test-traversal-done,\"\"") break;
+    traversal_processor.processLogLine(line);
+  }
+  var traversal_entries =
+    traversal_processor.profile.codeMap_.getAllDynamicEntriesWithAddresses();
+  if (traversal_entries.length === 0)
+    return "traversal_entries.length === 0";
+
+  function addressComparator(entryA, entryB) {
+    return entryA[0] < entryB[0] ? -1 : (entryA[0] > entryB[0] ? 1 : 0);
+  }
+
+  logging_entries.sort(addressComparator);
+  traversal_entries.sort(addressComparator);
+
+  function entityNamesEqual(entityA, entityB) {
+    if ("getRawName" in entityB &&
+        entityNamesEqual.builtins.indexOf(entityB.getRawName()) !== -1) {
+      return true;
+    }
+    if (entityNamesEqual.builtins.indexOf(entityB.getName()) !== -1) return true;
+    return entityA.getName() === entityB.getName();
+  }
+  entityNamesEqual.builtins =
+    ["Boolean", "Function", "Number", "Object",
+     "Script", "String", "RegExp", "Date", "Error"];
+
+  function entitiesEqual(entityA, entityB) {
+    if (entityA === null && entityB !== null) return true;
+    if (entityA !== null && entityB === null) return false;
+    return entityA.size === entityB.size && entityNamesEqual(entityA, entityB);
+  }
+
+  var i = 0, j = 0, k = logging_entries.length, l = traversal_entries.length;
+  var comparison = [];
+  var equal = true;
+  // Do a merge-like comparison of entries. At the same address we expect to
+  // find the same entries. We skip builtins during log parsing, but compiled
+  // functions traversal may erroneously recognize them as functions, so we are
+  // expecting more functions in traversal vs. logging.
+  while (i < k && j < l) {
+    var entryA = logging_entries[i], entryB = traversal_entries[j];
+    var cmp = addressComparator(entryA, entryB);
+    var entityA = entryA[1], entityB = entryB[1];
+    var address = entryA[0];
+    if (cmp < 0) {
+      ++i;
+      entityB = null;
+    } else if (cmp > 0) {
+      ++j;
+      entityA = null;
+      address = entryB[0];
+    } else {
+      ++i;
+      ++j;
+    }
+    var entities_equal = entitiesEqual(entityA, entityB);
+    if (!entities_equal) equal = false;
+    comparison.push([entities_equal, address, entityA, entityB]);
+  }
+  if (i < k) equal = false;
+  while (i < k) {
+    var entryA = logging_entries[i++];
+    comparison.push([false, entryA[0], entryA[1], null]);
+  }
+  return [equal, comparison];
+}
+
+var result = RunTest();
+if (typeof result !== "string") {
+  var out = [];
+  if (!result[0]) {
+    var comparison = result[1];
+    for (var i = 0, l = comparison.length; i < l; ++i) {
+      var c = comparison[i];
+      out.push((c[0] ? "  " : "* ") +
+               c[1].toString(16) + " " +
+               (c[2] ? c[2] : "---") + " " +
+               (c[3] ? c[3] : "---"));
+    }
+  }
+  result[0] ? true : out.join("\n");
+} else {
+  result;
+}
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index 1531f90..8d8770f 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -12633,9 +12633,10 @@
                     stackTrace->GetFrame(0));
     checkStackFrame(origin, "foo", 6, 3, false, false,
                     stackTrace->GetFrame(1));
-    checkStackFrame(NULL, "", 1, 1, false, false,
+    // This is the source string inside the eval which has the call to foo.
+    checkStackFrame(NULL, "", 1, 5, false, false,
                     stackTrace->GetFrame(2));
-    // The last frame is an anonymous function that has the initial call.
+    // The last frame is an anonymous function which has the initial eval call.
     checkStackFrame(origin, "", 8, 7, false, false,
                     stackTrace->GetFrame(3));
 
@@ -12654,9 +12655,10 @@
     bool is_eval = false;
 #endif  // ENABLE_DEBUGGER_SUPPORT
 
-    checkStackFrame(NULL, "", 1, 1, is_eval, false,
+    // This is the source string inside the eval which has the call to baz.
+    checkStackFrame(NULL, "", 1, 5, is_eval, false,
                     stackTrace->GetFrame(2));
-    // The last frame is an anonymous function that has the initial call to foo.
+    // The last frame is an anonymous function which has the initial eval call.
     checkStackFrame(origin, "", 10, 1, false, false,
                     stackTrace->GetFrame(3));
 
diff --git a/test/cctest/test-cpu-profiler.cc b/test/cctest/test-cpu-profiler.cc
index 7d898ce..9ff2a17 100644
--- a/test/cctest/test-cpu-profiler.cc
+++ b/test/cctest/test-cpu-profiler.cc
@@ -2,8 +2,6 @@
 //
 // Tests of profiles generator and utilities.
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
 #include "v8.h"
 #include "cpu-profiler-inl.h"
 #include "cctest.h"
@@ -401,5 +399,3 @@
   CHECK_EQ(0, CpuProfiler::GetProfilesCount());
   CHECK_EQ(NULL, v8::CpuProfiler::FindProfile(uid3));
 }
-
-#endif  // ENABLE_LOGGING_AND_PROFILING
diff --git a/test/cctest/test-heap-profiler.cc b/test/cctest/test-heap-profiler.cc
index a2426cc..8675a01 100644
--- a/test/cctest/test-heap-profiler.cc
+++ b/test/cctest/test-heap-profiler.cc
@@ -2,8 +2,6 @@
 //
 // Tests for heap profiler
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
 #include "v8.h"
 
 #include "cctest.h"
@@ -893,5 +891,3 @@
   }
   CHECK_EQ(1, count);
 }
-
-#endif  // ENABLE_LOGGING_AND_PROFILING
diff --git a/test/cctest/test-lockers.cc b/test/cctest/test-lockers.cc
index 4579361..2b184e9 100644
--- a/test/cctest/test-lockers.cc
+++ b/test/cctest/test-lockers.cc
@@ -314,7 +314,11 @@
 
 // Run parallel threads that lock and access different isolates in parallel
 TEST(SeparateIsolatesLocksNonexclusive) {
+#ifdef V8_TARGET_ARCH_ARM
+  const int kNThreads = 50;
+#else
   const int kNThreads = 100;
+#endif
   v8::Isolate* isolate1 = v8::Isolate::New();
   v8::Isolate* isolate2 = v8::Isolate::New();
   i::List<JoinableThread*> threads(kNThreads);
@@ -383,7 +387,11 @@
 
 // Use unlocker inside of a Locker, multiple threads.
 TEST(LockerUnlocker) {
+#ifdef V8_TARGET_ARCH_ARM
+  const int kNThreads = 50;
+#else
   const int kNThreads = 100;
+#endif
   i::List<JoinableThread*> threads(kNThreads);
   v8::Isolate* isolate = v8::Isolate::New();
   for (int i = 0; i < kNThreads; i++) {
@@ -431,7 +439,11 @@
 
 // Use Unlocker inside two Lockers.
 TEST(LockTwiceAndUnlock) {
+#ifdef V8_TARGET_ARCH_ARM
+  const int kNThreads = 50;
+#else
   const int kNThreads = 100;
+#endif
   i::List<JoinableThread*> threads(kNThreads);
   v8::Isolate* isolate = v8::Isolate::New();
   for (int i = 0; i < kNThreads; i++) {
diff --git a/test/cctest/test-log-stack-tracer.cc b/test/cctest/test-log-stack-tracer.cc
index b967c73..2bcb3fe 100644
--- a/test/cctest/test-log-stack-tracer.cc
+++ b/test/cctest/test-log-stack-tracer.cc
@@ -27,8 +27,6 @@
 //
 // Tests of profiler-related functions from log.h
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
 #include <stdlib.h>
 
 #include "v8.h"
@@ -413,5 +411,3 @@
   CompileRun("js_entry_sp_level2();");
   CHECK_EQ(0, GetJsEntrySp());
 }
-
-#endif  // ENABLE_LOGGING_AND_PROFILING
diff --git a/test/cctest/test-log-utils.cc b/test/cctest/test-log-utils.cc
deleted file mode 100644
index 861be12..0000000
--- a/test/cctest/test-log-utils.cc
+++ /dev/null
@@ -1,140 +0,0 @@
-// Copyright 2006-2009 the V8 project authors. All rights reserved.
-//
-// Tests of logging utilities from log-utils.h
-
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
-#include "v8.h"
-
-#include "log-utils.h"
-#include "cctest.h"
-
-using v8::internal::CStrVector;
-using v8::internal::EmbeddedVector;
-using v8::internal::LogDynamicBuffer;
-using v8::internal::MutableCStrVector;
-using v8::internal::ScopedVector;
-using v8::internal::Vector;
-using v8::internal::StrLength;
-
-// Fills 'ref_buffer' with test data: a sequence of two-digit
-// hex numbers: '0001020304...'. Then writes 'ref_buffer' contents to 'dynabuf'.
-static void WriteData(LogDynamicBuffer* dynabuf, Vector<char>* ref_buffer) {
-  static const char kHex[] = "0123456789ABCDEF";
-  CHECK_GT(ref_buffer->length(), 0);
-  CHECK_GT(513, ref_buffer->length());
-  for (int i = 0, half_len = ref_buffer->length() >> 1; i < half_len; ++i) {
-    (*ref_buffer)[i << 1] = kHex[i >> 4];
-    (*ref_buffer)[(i << 1) + 1] = kHex[i & 15];
-  }
-  if (ref_buffer->length() & 1) {
-    ref_buffer->last() = kHex[ref_buffer->length() >> 5];
-  }
-  CHECK_EQ(ref_buffer->length(),
-           dynabuf->Write(ref_buffer->start(), ref_buffer->length()));
-}
-
-
-static int ReadData(
-    LogDynamicBuffer* dynabuf, int start_pos, i::Vector<char>* buffer) {
-  return dynabuf->Read(start_pos, buffer->start(), buffer->length());
-}
-
-
-// Helper function used by CHECK_EQ to compare Vectors. Templatized to
-// accept both "char" and "const char" vector contents.
-template <typename E, typename V>
-static inline void CheckEqualsHelper(const char* file, int line,
-                                     const char* expected_source,
-                                     const Vector<E>& expected,
-                                     const char* value_source,
-                                     const Vector<V>& value) {
-  if (expected.length() != value.length()) {
-    V8_Fatal(file, line, "CHECK_EQ(%s, %s) failed\n"
-             "#   Vectors lengths differ: %d expected, %d found\n"
-             "#   Expected: %.*s\n"
-             "#   Found: %.*s",
-             expected_source, value_source,
-             expected.length(), value.length(),
-             expected.length(), expected.start(),
-             value.length(), value.start());
-  }
-  if (strncmp(expected.start(), value.start(), expected.length()) != 0) {
-    V8_Fatal(file, line, "CHECK_EQ(%s, %s) failed\n"
-             "#   Vectors contents differ:\n"
-             "#   Expected: %.*s\n"
-             "#   Found: %.*s",
-             expected_source, value_source,
-             expected.length(), expected.start(),
-             value.length(), value.start());
-  }
-}
-
-
-TEST(DynaBufSingleBlock) {
-  LogDynamicBuffer dynabuf(32, 32, "", 0);
-  EmbeddedVector<char, 32> ref_buf;
-  WriteData(&dynabuf, &ref_buf);
-  EmbeddedVector<char, 32> buf;
-  CHECK_EQ(32, dynabuf.Read(0, buf.start(), buf.length()));
-  CHECK_EQ(32, ReadData(&dynabuf, 0, &buf));
-  CHECK_EQ(ref_buf, buf);
-
-  // Verify that we can't read and write past the end.
-  CHECK_EQ(0, dynabuf.Read(32, buf.start(), buf.length()));
-  CHECK_EQ(0, dynabuf.Write(buf.start(), buf.length()));
-}
-
-
-TEST(DynaBufCrossBlocks) {
-  LogDynamicBuffer dynabuf(32, 128, "", 0);
-  EmbeddedVector<char, 48> ref_buf;
-  WriteData(&dynabuf, &ref_buf);
-  CHECK_EQ(48, dynabuf.Write(ref_buf.start(), ref_buf.length()));
-  // Verify that we can't write data when remaining buffer space isn't enough.
-  CHECK_EQ(0, dynabuf.Write(ref_buf.start(), ref_buf.length()));
-  EmbeddedVector<char, 48> buf;
-  CHECK_EQ(48, ReadData(&dynabuf, 0, &buf));
-  CHECK_EQ(ref_buf, buf);
-  CHECK_EQ(48, ReadData(&dynabuf, 48, &buf));
-  CHECK_EQ(ref_buf, buf);
-  CHECK_EQ(0, ReadData(&dynabuf, 48 * 2, &buf));
-}
-
-
-TEST(DynaBufReadTruncation) {
-  LogDynamicBuffer dynabuf(32, 128, "", 0);
-  EmbeddedVector<char, 128> ref_buf;
-  WriteData(&dynabuf, &ref_buf);
-  EmbeddedVector<char, 128> buf;
-  CHECK_EQ(128, ReadData(&dynabuf, 0, &buf));
-  CHECK_EQ(ref_buf, buf);
-  // Try to read near the end with a buffer larger than remaining data size.
-  EmbeddedVector<char, 48> tail_buf;
-  CHECK_EQ(32, ReadData(&dynabuf, 128 - 32, &tail_buf));
-  CHECK_EQ(ref_buf.SubVector(128 - 32, 128), tail_buf.SubVector(0, 32));
-}
-
-
-TEST(DynaBufSealing) {
-  const char* seal = "Sealed";
-  const int seal_size = StrLength(seal);
-  LogDynamicBuffer dynabuf(32, 128, seal, seal_size);
-  EmbeddedVector<char, 100> ref_buf;
-  WriteData(&dynabuf, &ref_buf);
-  // Try to write data that will not fit in the buffer.
-  CHECK_EQ(0, dynabuf.Write(ref_buf.start(), 128 - 100 - seal_size + 1));
-  // Now the buffer is sealed, writing of any amount of data is forbidden.
-  CHECK_EQ(0, dynabuf.Write(ref_buf.start(), 1));
-  EmbeddedVector<char, 100> buf;
-  CHECK_EQ(100, ReadData(&dynabuf, 0, &buf));
-  CHECK_EQ(ref_buf, buf);
-  // Check the seal.
-  EmbeddedVector<char, 50> seal_buf;
-  CHECK_EQ(seal_size, ReadData(&dynabuf, 100, &seal_buf));
-  CHECK_EQ(CStrVector(seal), seal_buf.SubVector(0, seal_size));
-  // Verify that there's no data beyond the seal.
-  CHECK_EQ(0, ReadData(&dynabuf, 100 + seal_size, &buf));
-}
-
-#endif  // ENABLE_LOGGING_AND_PROFILING
diff --git a/test/cctest/test-log.cc b/test/cctest/test-log.cc
index 10a90bc..5704b07 100644
--- a/test/cctest/test-log.cc
+++ b/test/cctest/test-log.cc
@@ -2,8 +2,6 @@
 //
 // Tests of logging functions from log.h
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
 #ifdef __linux__
 #include <math.h>
 #include <pthread.h>
@@ -15,6 +13,7 @@
 #include "log.h"
 #include "cpu-profiler.h"
 #include "v8threads.h"
+#include "v8utils.h"
 #include "cctest.h"
 #include "vm-state-inl.h"
 
@@ -25,269 +24,75 @@
 
 namespace i = v8::internal;
 
-static void SetUp() {
-  // Log to memory buffer.
-  i::FLAG_logfile = "*";
-  i::FLAG_log = true;
-  LOGGER->Setup();
-}
-
-static void TearDown() {
-  LOGGER->TearDown();
-}
-
-
-TEST(EmptyLog) {
-  SetUp();
-  CHECK_EQ(0, LOGGER->GetLogLines(0, NULL, 0));
-  CHECK_EQ(0, LOGGER->GetLogLines(100, NULL, 0));
-  CHECK_EQ(0, LOGGER->GetLogLines(0, NULL, 100));
-  CHECK_EQ(0, LOGGER->GetLogLines(100, NULL, 100));
-  TearDown();
-}
-
-
-TEST(GetMessages) {
-  SetUp();
-  LOGGER->StringEvent("aaa", "bbb");
-  LOGGER->StringEvent("cccc", "dddd");
-  CHECK_EQ(0, LOGGER->GetLogLines(0, NULL, 0));
-  char log_lines[100];
-  memset(log_lines, 0, sizeof(log_lines));
-  // See Logger::StringEvent.
-  const char* line_1 = "aaa,\"bbb\"\n";
-  const int line_1_len = StrLength(line_1);
-  // The exact size.
-  CHECK_EQ(line_1_len, LOGGER->GetLogLines(0, log_lines, line_1_len));
-  CHECK_EQ(line_1, log_lines);
-  memset(log_lines, 0, sizeof(log_lines));
-  // A bit more than the first line length.
-  CHECK_EQ(line_1_len, LOGGER->GetLogLines(0, log_lines, line_1_len + 3));
-  log_lines[line_1_len] = '\0';
-  CHECK_EQ(line_1, log_lines);
-  memset(log_lines, 0, sizeof(log_lines));
-  const char* line_2 = "cccc,\"dddd\"\n";
-  const int line_2_len = StrLength(line_2);
-  // Now start with line_2 beginning.
-  CHECK_EQ(0, LOGGER->GetLogLines(line_1_len, log_lines, 0));
-  CHECK_EQ(line_2_len, LOGGER->GetLogLines(line_1_len, log_lines, line_2_len));
-  CHECK_EQ(line_2, log_lines);
-  memset(log_lines, 0, sizeof(log_lines));
-  CHECK_EQ(line_2_len,
-           LOGGER->GetLogLines(line_1_len, log_lines, line_2_len + 3));
-  CHECK_EQ(line_2, log_lines);
-  memset(log_lines, 0, sizeof(log_lines));
-  // Now get entire buffer contents.
-  const char* all_lines = "aaa,\"bbb\"\ncccc,\"dddd\"\n";
-  const int all_lines_len = StrLength(all_lines);
-  CHECK_EQ(all_lines_len, LOGGER->GetLogLines(0, log_lines, all_lines_len));
-  CHECK_EQ(all_lines, log_lines);
-  memset(log_lines, 0, sizeof(log_lines));
-  CHECK_EQ(all_lines_len, LOGGER->GetLogLines(0, log_lines, all_lines_len + 3));
-  CHECK_EQ(all_lines, log_lines);
-  memset(log_lines, 0, sizeof(log_lines));
-  TearDown();
-}
-
-
-static int GetLogLines(int start_pos, i::Vector<char>* buffer) {
-  return LOGGER->GetLogLines(start_pos, buffer->start(), buffer->length());
-}
-
-
-TEST(BeyondWritePosition) {
-  SetUp();
-  LOGGER->StringEvent("aaa", "bbb");
-  LOGGER->StringEvent("cccc", "dddd");
-  // See Logger::StringEvent.
-  const char* all_lines = "aaa,\"bbb\"\ncccc,\"dddd\"\n";
-  const int all_lines_len = StrLength(all_lines);
-  EmbeddedVector<char, 100> buffer;
-  const int beyond_write_pos = all_lines_len;
-  CHECK_EQ(0, LOGGER->GetLogLines(beyond_write_pos, buffer.start(), 1));
-  CHECK_EQ(0, GetLogLines(beyond_write_pos, &buffer));
-  CHECK_EQ(0, LOGGER->GetLogLines(beyond_write_pos + 1, buffer.start(), 1));
-  CHECK_EQ(0, GetLogLines(beyond_write_pos + 1, &buffer));
-  CHECK_EQ(0, LOGGER->GetLogLines(beyond_write_pos + 100, buffer.start(), 1));
-  CHECK_EQ(0, GetLogLines(beyond_write_pos + 100, &buffer));
-  CHECK_EQ(0, LOGGER->GetLogLines(10 * 1024 * 1024, buffer.start(), 1));
-  CHECK_EQ(0, GetLogLines(10 * 1024 * 1024, &buffer));
-  TearDown();
-}
-
-
-TEST(MemoryLoggingTurnedOff) {
-  // Log to stdout
-  i::FLAG_logfile = "-";
-  i::FLAG_log = true;
-  LOGGER->Setup();
-  CHECK_EQ(0, LOGGER->GetLogLines(0, NULL, 0));
-  CHECK_EQ(0, LOGGER->GetLogLines(100, NULL, 0));
-  CHECK_EQ(0, LOGGER->GetLogLines(0, NULL, 100));
-  CHECK_EQ(0, LOGGER->GetLogLines(100, NULL, 100));
-  LOGGER->TearDown();
-}
-
-
-static void CompileAndRunScript(const char *src) {
-  v8::Script::Compile(v8::String::New(src))->Run();
-}
-
-
-namespace v8 {
-namespace internal {
-
-class LoggerTestHelper : public AllStatic {
- public:
-  static bool IsSamplerActive() { return LOGGER->IsProfilerSamplerActive(); }
-  static void ResetSamplesTaken() {
-    reinterpret_cast<Sampler*>(LOGGER->ticker_)->ResetSamplesTaken();
-  }
-  static bool has_samples_taken() {
-    return reinterpret_cast<Sampler*>(LOGGER->ticker_)->samples_taken() > 0;
-  }
-};
-
-}  // namespace v8::internal
-}  // namespace v8
-
-using v8::internal::LoggerTestHelper;
-
-
 namespace {
 
 class ScopedLoggerInitializer {
  public:
   explicit ScopedLoggerInitializer(bool prof_lazy)
-      : saved_prof_lazy_(i::FLAG_prof_lazy),
+      : saved_log_(i::FLAG_log),
+        saved_prof_lazy_(i::FLAG_prof_lazy),
         saved_prof_(i::FLAG_prof),
         saved_prof_auto_(i::FLAG_prof_auto),
+        temp_file_(NULL),
+        // Need to run this prior to creating the scope.
         trick_to_run_init_flags_(init_flags_(prof_lazy)),
-        need_to_set_up_logger_(i::V8::IsRunning()),
         scope_(),
         env_(v8::Context::New()) {
-    if (need_to_set_up_logger_) LOGGER->Setup();
     env_->Enter();
   }
 
   ~ScopedLoggerInitializer() {
     env_->Exit();
     LOGGER->TearDown();
+    if (temp_file_ != NULL) fclose(temp_file_);
     i::FLAG_prof_lazy = saved_prof_lazy_;
     i::FLAG_prof = saved_prof_;
     i::FLAG_prof_auto = saved_prof_auto_;
+    i::FLAG_log = saved_log_;
   }
 
   v8::Handle<v8::Context>& env() { return env_; }
 
+  FILE* StopLoggingGetTempFile() {
+    temp_file_ = LOGGER->TearDown();
+    CHECK_NE(NULL, temp_file_);
+    fflush(temp_file_);
+    rewind(temp_file_);
+    return temp_file_;
+  }
+
  private:
   static bool init_flags_(bool prof_lazy) {
+    i::FLAG_log = true;
     i::FLAG_prof = true;
     i::FLAG_prof_lazy = prof_lazy;
     i::FLAG_prof_auto = false;
-    i::FLAG_logfile = "*";
+    i::FLAG_logfile = i::Log::kLogToTemporaryFile;
     return prof_lazy;
   }
 
+  const bool saved_log_;
   const bool saved_prof_lazy_;
   const bool saved_prof_;
   const bool saved_prof_auto_;
+  FILE* temp_file_;
   const bool trick_to_run_init_flags_;
-  const bool need_to_set_up_logger_;
   v8::HandleScope scope_;
   v8::Handle<v8::Context> env_;
 
   DISALLOW_COPY_AND_ASSIGN(ScopedLoggerInitializer);
 };
 
-
-class LogBufferMatcher {
- public:
-  LogBufferMatcher() {
-    // Skip all initially logged stuff.
-    log_pos_ = GetLogLines(0, &buffer_);
-  }
-
-  int log_pos() { return log_pos_; }
-
-  int GetNextChunk() {
-    int chunk_size = GetLogLines(log_pos_, &buffer_);
-    CHECK_GT(buffer_.length(), chunk_size);
-    buffer_[chunk_size] = '\0';
-    log_pos_ += chunk_size;
-    return chunk_size;
-  }
-
-  const char* Find(const char* substr) {
-    return strstr(buffer_.start(), substr);
-  }
-
-  const char* Find(const i::Vector<char>& substr) {
-    return Find(substr.start());
-  }
-
-  bool IsInSequence(const char* s1, const char* s2) {
-    const char* s1_pos = Find(s1);
-    const char* s2_pos = Find(s2);
-    CHECK_NE(NULL, s1_pos);
-    CHECK_NE(NULL, s2_pos);
-    return s1_pos < s2_pos;
-  }
-
-  void PrintBuffer() {
-    puts(buffer_.start());
-  }
-
- private:
-  EmbeddedVector<char, 102400> buffer_;
-  int log_pos_;
-};
-
 }  // namespace
 
 
-static void CheckThatProfilerWorks(LogBufferMatcher* matcher) {
-  CHECK(i::RuntimeProfiler::IsEnabled() ||
-        !LoggerTestHelper::IsSamplerActive());
-  LoggerTestHelper::ResetSamplesTaken();
-
-  LOGGER->ResumeProfiler();
-  CHECK(LoggerTestHelper::IsSamplerActive());
-
-  // Verify that the current map of compiled functions has been logged.
-  CHECK_GT(matcher->GetNextChunk(), 0);
-  const char* code_creation = "\ncode-creation,";  // eq. to /^code-creation,/
-  CHECK_NE(NULL, matcher->Find(code_creation));
-
-  // Force compiler to generate new code by parametrizing source.
-  EmbeddedVector<char, 100> script_src;
-  i::OS::SNPrintF(script_src,
-                  "function f%d(x) { return %d * x; }"
-                  "for (var i = 0; i < 10000; ++i) { f%d(i); }",
-                  matcher->log_pos(), matcher->log_pos(), matcher->log_pos());
-  // Run code for 200 msecs to get some ticks.
-  const double end_time = i::OS::TimeCurrentMillis() + 200;
-  while (i::OS::TimeCurrentMillis() < end_time) {
-    CompileAndRunScript(script_src.start());
-    // Yield CPU to give Profiler thread a chance to process ticks.
-    i::OS::Sleep(1);
-  }
-
-  LOGGER->PauseProfiler();
-  CHECK(i::RuntimeProfiler::IsEnabled() ||
-        !LoggerTestHelper::IsSamplerActive());
-
-  // Wait 50 msecs to allow Profiler thread to process the last
-  // tick sample it has got.
-  i::OS::Sleep(50);
-
-  // Now we must have compiler and tick records.
-  CHECK_GT(matcher->GetNextChunk(), 0);
-  matcher->PrintBuffer();
-  CHECK_NE(NULL, matcher->Find(code_creation));
-  const char* tick = "\ntick,";
-  const bool ticks_found = matcher->Find(tick) != NULL;
-  CHECK_EQ(LoggerTestHelper::has_samples_taken(), ticks_found);
+static const char* StrNStr(const char* s1, const char* s2, int n) {
+  if (s1[n] == '\0') return strstr(s1, s2);
+  i::ScopedVector<char> str(n + 1);
+  i::OS::StrNCpy(str, s1, static_cast<size_t>(n));
+  str[n] = '\0';
+  char* found = strstr(str.start(), s2);
+  return found != NULL ? s1 + (found - str.start()) : NULL;
 }
 
 
@@ -296,29 +101,61 @@
 
   if (!i::V8::UseCrankshaft()) return;
 
-  // No sampling should happen prior to resuming profiler unless we
-  // are runtime profiling.
-  CHECK(i::RuntimeProfiler::IsEnabled() ||
-        !LoggerTestHelper::IsSamplerActive());
-
-  LogBufferMatcher matcher;
-  // Nothing must be logged until profiling is resumed.
-  CHECK_EQ(0, matcher.log_pos());
-
-  CompileAndRunScript("var a = (function(x) { return x + 1; })(10);");
-
-  // Nothing must be logged while profiling is suspended.
-  CHECK_EQ(0, matcher.GetNextChunk());
-
-  CheckThatProfilerWorks(&matcher);
-
-  CompileAndRunScript("var a = (function(x) { return x + 1; })(10);");
-
-  // No new data beyond last retrieved position.
-  CHECK_EQ(0, matcher.GetNextChunk());
-
+  LOGGER->StringEvent("test-start", "");
+  CompileRun("var a = (function(x) { return x + 1; })(10);");
+  LOGGER->StringEvent("test-profiler-start", "");
+  v8::V8::ResumeProfiler();
+  CompileRun(
+      "var b = (function(x) { return x + 2; })(10);\n"
+      "var c = (function(x) { return x + 3; })(10);\n"
+      "var d = (function(x) { return x + 4; })(10);\n"
+      "var e = (function(x) { return x + 5; })(10);");
+  v8::V8::PauseProfiler();
+  LOGGER->StringEvent("test-profiler-stop", "");
+  CompileRun("var f = (function(x) { return x + 6; })(10);");
   // Check that profiling can be resumed again.
-  CheckThatProfilerWorks(&matcher);
+  LOGGER->StringEvent("test-profiler-start-2", "");
+  v8::V8::ResumeProfiler();
+  CompileRun(
+      "var g = (function(x) { return x + 7; })(10);\n"
+      "var h = (function(x) { return x + 8; })(10);\n"
+      "var i = (function(x) { return x + 9; })(10);\n"
+      "var j = (function(x) { return x + 10; })(10);");
+  v8::V8::PauseProfiler();
+  LOGGER->StringEvent("test-profiler-stop-2", "");
+  LOGGER->StringEvent("test-stop", "");
+
+  bool exists = false;
+  i::Vector<const char> log(
+      i::ReadFile(initialize_logger.StopLoggingGetTempFile(), &exists, true));
+  CHECK(exists);
+
+  const char* test_start_position =
+      StrNStr(log.start(), "test-start,", log.length());
+  CHECK_NE(NULL, test_start_position);
+  const char* test_profiler_start_position =
+      StrNStr(log.start(), "test-profiler-start,", log.length());
+  CHECK_NE(NULL, test_profiler_start_position);
+  CHECK_GT(test_profiler_start_position, test_start_position);
+  const char* test_profiler_stop_position =
+      StrNStr(log.start(), "test-profiler-stop,", log.length());
+  CHECK_NE(NULL, test_profiler_stop_position);
+  CHECK_GT(test_profiler_stop_position, test_profiler_start_position);
+  const char* test_profiler_start_2_position =
+      StrNStr(log.start(), "test-profiler-start-2,", log.length());
+  CHECK_NE(NULL, test_profiler_start_2_position);
+  CHECK_GT(test_profiler_start_2_position, test_profiler_stop_position);
+
+  // Nothing must be logged until profiling is resumed.
+  CHECK_EQ(NULL, StrNStr(test_start_position,
+                         "code-creation,",
+                         static_cast<int>(test_profiler_start_position -
+                                          test_start_position)));
+  // Nothing must be logged while profiling is suspended.
+  CHECK_EQ(NULL, StrNStr(test_profiler_stop_position,
+                         "code-creation,",
+                         static_cast<int>(test_profiler_start_2_position -
+                                          test_profiler_stop_position)));
 }
 
 
@@ -383,7 +220,7 @@
       {
         v8::Context::Scope context_scope(context);
         SignalRunning();
-        CompileAndRunScript(
+        CompileRun(
             "var j; for (var i=0; i<10000; ++i) { j = Math.sin(i); }");
       }
       context.Dispose();
@@ -531,34 +368,34 @@
 
 TEST(LogCallbacks) {
   ScopedLoggerInitializer initialize_logger(false);
-  LogBufferMatcher matcher;
 
   v8::Persistent<v8::FunctionTemplate> obj =
       v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New());
-  obj->SetClassName(v8::String::New("Obj"));
+  obj->SetClassName(v8_str("Obj"));
   v8::Handle<v8::ObjectTemplate> proto = obj->PrototypeTemplate();
   v8::Local<v8::Signature> signature = v8::Signature::New(obj);
-  proto->Set(v8::String::New("method1"),
+  proto->Set(v8_str("method1"),
              v8::FunctionTemplate::New(ObjMethod1,
                                        v8::Handle<v8::Value>(),
                                        signature),
              static_cast<v8::PropertyAttribute>(v8::DontDelete));
 
   initialize_logger.env()->Global()->Set(v8_str("Obj"), obj->GetFunction());
-  CompileAndRunScript("Obj.prototype.method1.toString();");
+  CompileRun("Obj.prototype.method1.toString();");
 
   LOGGER->LogCompiledFunctions();
-  CHECK_GT(matcher.GetNextChunk(), 0);
 
-  const char* callback_rec = "code-creation,Callback,";
-  char* pos = const_cast<char*>(matcher.Find(callback_rec));
-  CHECK_NE(NULL, pos);
-  pos += strlen(callback_rec);
-  EmbeddedVector<char, 100> ref_data;
+  bool exists = false;
+  i::Vector<const char> log(
+      i::ReadFile(initialize_logger.StopLoggingGetTempFile(), &exists, true));
+  CHECK(exists);
+
+  i::EmbeddedVector<char, 100> ref_data;
   i::OS::SNPrintF(ref_data,
-                  "0x%" V8PRIxPTR ",1,\"method1\"", ObjMethod1);
-  *(pos + strlen(ref_data.start())) = '\0';
-  CHECK_EQ(ref_data.start(), pos);
+                  "code-creation,Callback,0x%" V8PRIxPTR ",1,\"method1\"\0",
+                  ObjMethod1);
+
+  CHECK_NE(NULL, StrNStr(log.start(), ref_data.start(), log.length()));
 
   obj.Dispose();
 }
@@ -581,34 +418,41 @@
 
 TEST(LogAccessorCallbacks) {
   ScopedLoggerInitializer initialize_logger(false);
-  LogBufferMatcher matcher;
 
   v8::Persistent<v8::FunctionTemplate> obj =
       v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New());
-  obj->SetClassName(v8::String::New("Obj"));
+  obj->SetClassName(v8_str("Obj"));
   v8::Handle<v8::ObjectTemplate> inst = obj->InstanceTemplate();
-  inst->SetAccessor(v8::String::New("prop1"), Prop1Getter, Prop1Setter);
-  inst->SetAccessor(v8::String::New("prop2"), Prop2Getter);
+  inst->SetAccessor(v8_str("prop1"), Prop1Getter, Prop1Setter);
+  inst->SetAccessor(v8_str("prop2"), Prop2Getter);
 
   LOGGER->LogAccessorCallbacks();
-  CHECK_GT(matcher.GetNextChunk(), 0);
-  matcher.PrintBuffer();
+
+  bool exists = false;
+  i::Vector<const char> log(
+      i::ReadFile(initialize_logger.StopLoggingGetTempFile(), &exists, true));
+  CHECK(exists);
 
   EmbeddedVector<char, 100> prop1_getter_record;
   i::OS::SNPrintF(prop1_getter_record,
                   "code-creation,Callback,0x%" V8PRIxPTR ",1,\"get prop1\"",
                   Prop1Getter);
-  CHECK_NE(NULL, matcher.Find(prop1_getter_record));
+  CHECK_NE(NULL,
+           StrNStr(log.start(), prop1_getter_record.start(), log.length()));
+
   EmbeddedVector<char, 100> prop1_setter_record;
   i::OS::SNPrintF(prop1_setter_record,
                   "code-creation,Callback,0x%" V8PRIxPTR ",1,\"set prop1\"",
                   Prop1Setter);
-  CHECK_NE(NULL, matcher.Find(prop1_setter_record));
+  CHECK_NE(NULL,
+           StrNStr(log.start(), prop1_setter_record.start(), log.length()));
+
   EmbeddedVector<char, 100> prop2_getter_record;
   i::OS::SNPrintF(prop2_getter_record,
                   "code-creation,Callback,0x%" V8PRIxPTR ",1,\"get prop2\"",
                   Prop2Getter);
-  CHECK_NE(NULL, matcher.Find(prop2_getter_record));
+  CHECK_NE(NULL,
+           StrNStr(log.start(), prop2_getter_record.start(), log.length()));
 
   obj.Dispose();
 }
@@ -625,377 +469,6 @@
 }
 
 
-static inline bool IsStringEqualTo(const char* r, const char* s) {
-  return strncmp(r, s, strlen(r)) == 0;
-}
-
-
-static bool Consume(const char* str, char** buf) {
-  if (IsStringEqualTo(str, *buf)) {
-    *buf += strlen(str);
-    return true;
-  }
-  return false;
-}
-
-
-namespace {
-
-// A code entity is a pointer to a position of code-creation event in buffer log
-// offset to a point where entity size begins, i.e.: '255,"func"\n'. This makes
-// comparing code entities pretty easy.
-typedef char* CodeEntityInfo;
-
-class Interval {
- public:
-  Interval()
-      : min_addr_(reinterpret_cast<Address>(-1)),
-        max_addr_(reinterpret_cast<Address>(0)), next_(NULL) {}
-
-  ~Interval() { delete next_; }
-
-  size_t Length() {
-    size_t result = max_addr_ - min_addr_ + 1;
-    if (next_ != NULL) result += next_->Length();
-    return result;
-  }
-
-  void CloneFrom(Interval* src) {
-    while (src != NULL) {
-      RegisterAddress(src->min_addr_);
-      RegisterAddress(src->max_addr_);
-      src = src->next_;
-    }
-  }
-
-  bool Contains(Address addr) {
-    if (min_addr_ <= addr && addr <= max_addr_) {
-      return true;
-    }
-    if (next_ != NULL) {
-      return next_->Contains(addr);
-    } else {
-      return false;
-    }
-  }
-
-  size_t GetIndex(Address addr) {
-    if (min_addr_ <= addr && addr <= max_addr_) {
-      return addr - min_addr_;
-    }
-    CHECK_NE(NULL, next_);
-    return (max_addr_ - min_addr_ + 1) + next_->GetIndex(addr);
-  }
-
-  Address GetMinAddr() {
-    return next_ == NULL ? min_addr_ : i::Min(min_addr_, next_->GetMinAddr());
-  }
-
-  Address GetMaxAddr() {
-    return next_ == NULL ? max_addr_ : i::Max(max_addr_, next_->GetMaxAddr());
-  }
-
-  void RegisterAddress(Address addr) {
-    if (min_addr_ == reinterpret_cast<Address>(-1)
-        || (size_t)(addr > min_addr_ ?
-           addr - min_addr_ : min_addr_ - addr) < MAX_DELTA) {
-      if (addr < min_addr_) min_addr_ = addr;
-      if (addr > max_addr_) max_addr_ = addr;
-    } else {
-      if (next_ == NULL) next_ = new Interval();
-      next_->RegisterAddress(addr);
-    }
-  }
-
-  Address raw_min_addr() { return min_addr_; }
-
-  Address raw_max_addr() { return max_addr_; }
-
-  Interval* get_next() { return next_; }
-
- private:
-  static const size_t MAX_DELTA = 0x100000;
-  Address min_addr_;
-  Address max_addr_;
-  Interval* next_;
-};
-
-
-// A structure used to return log parsing results.
-class ParseLogResult {
- public:
-  ParseLogResult()
-      : entities_map(NULL), entities(NULL),
-        max_entities(0) {}
-
-  ~ParseLogResult() {
-    i::DeleteArray(entities_map);
-    i::DeleteArray(entities);
-  }
-
-  void AllocateEntities() {
-    // Make sure that the test doesn't operate on a bogus log.
-    CHECK_GT(max_entities, 0);
-    CHECK_GT(bounds.GetMinAddr(), 0);
-    CHECK_GT(bounds.GetMaxAddr(), bounds.GetMinAddr());
-
-    entities = i::NewArray<CodeEntityInfo>(max_entities);
-    for (int i = 0; i < max_entities; ++i) {
-      entities[i] = NULL;
-    }
-    const size_t map_length = bounds.Length();
-    entities_map = i::NewArray<int>(static_cast<int>(map_length));
-    for (size_t i = 0; i < map_length; ++i) {
-      entities_map[i] = -1;
-    }
-  }
-
-  bool HasIndexForAddress(Address addr) {
-    return bounds.Contains(addr);
-  }
-
-  size_t GetIndexForAddress(Address addr) {
-    CHECK(HasIndexForAddress(addr));
-    return bounds.GetIndex(addr);
-  }
-
-  CodeEntityInfo GetEntity(Address addr) {
-    if (HasIndexForAddress(addr)) {
-      size_t idx = GetIndexForAddress(addr);
-      int item = entities_map[idx];
-      return item != -1 ? entities[item] : NULL;
-    }
-    return NULL;
-  }
-
-  void ParseAddress(char* start) {
-    Address addr =
-        reinterpret_cast<Address>(strtoul(start, NULL, 16));  // NOLINT
-    bounds.RegisterAddress(addr);
-  }
-
-  Address ConsumeAddress(char** start) {
-    char* end_ptr;
-    Address addr =
-        reinterpret_cast<Address>(strtoul(*start, &end_ptr, 16));  // NOLINT
-    CHECK(HasIndexForAddress(addr));
-    *start = end_ptr;
-    return addr;
-  }
-
-  Interval bounds;
-  // Memory map of entities start addresses.
-  int* entities_map;
-  // An array of code entities.
-  CodeEntityInfo* entities;
-  // Maximal entities count. Actual entities count can be lower,
-  // empty entity slots are pointing to NULL.
-  int max_entities;
-};
-
-}  // namespace
-
-
-typedef void (*ParserBlock)(char* start, char* end, ParseLogResult* result);
-
-static void ParserCycle(
-    char* start, char* end, ParseLogResult* result,
-    ParserBlock block_creation, ParserBlock block_delete,
-    ParserBlock block_move) {
-
-  const char* code_creation = "code-creation,";
-  const char* code_delete = "code-delete,";
-  const char* code_move = "code-move,";
-
-  const char* lazy_compile = "LazyCompile,";
-  const char* script = "Script,";
-  const char* function = "Function,";
-
-  while (start < end) {
-    if (Consume(code_creation, &start)) {
-      if (Consume(lazy_compile, &start)
-          || Consume(script, &start)
-          || Consume(function, &start)) {
-        block_creation(start, end, result);
-      }
-    } else if (Consume(code_delete, &start)) {
-      block_delete(start, end, result);
-    } else if (Consume(code_move, &start)) {
-      block_move(start, end, result);
-    }
-    while (start < end && *start != '\n') ++start;
-    ++start;
-  }
-}
-
-
-static void Pass1CodeCreation(char* start, char* end, ParseLogResult* result) {
-  result->ParseAddress(start);
-  ++result->max_entities;
-}
-
-
-static void Pass1CodeDelete(char* start, char* end, ParseLogResult* result) {
-  result->ParseAddress(start);
-}
-
-
-static void Pass1CodeMove(char* start, char* end, ParseLogResult* result) {
-  result->ParseAddress(start);
-  // Skip old address.
-  while (start < end && *start != ',') ++start;
-  CHECK_GT(end, start);
-  ++start;  // Skip ','.
-  result->ParseAddress(start);
-}
-
-
-static void Pass2CodeCreation(char* start, char* end, ParseLogResult* result) {
-  Address addr = result->ConsumeAddress(&start);
-  CHECK_GT(end, start);
-  ++start;  // Skip ','.
-
-  size_t idx = result->GetIndexForAddress(addr);
-  result->entities_map[idx] = -1;
-  for (int i = 0; i < result->max_entities; ++i) {
-    // Find an empty slot and fill it.
-    if (result->entities[i] == NULL) {
-      result->entities[i] = start;
-      result->entities_map[idx] = i;
-      break;
-    }
-  }
-  // Make sure that a slot was found.
-  CHECK_GE(result->entities_map[idx], 0);
-}
-
-
-static void Pass2CodeDelete(char* start, char* end, ParseLogResult* result) {
-  Address addr = result->ConsumeAddress(&start);
-  size_t idx = result->GetIndexForAddress(addr);
-  // There can be code deletes that are not related to JS code.
-  if (result->entities_map[idx] >= 0) {
-    result->entities[result->entities_map[idx]] = NULL;
-    result->entities_map[idx] = -1;
-  }
-}
-
-
-static void Pass2CodeMove(char* start, char* end, ParseLogResult* result) {
-  Address from_addr = result->ConsumeAddress(&start);
-  CHECK_GT(end, start);
-  ++start;  // Skip ','.
-  Address to_addr = result->ConsumeAddress(&start);
-  CHECK_GT(end, start);
-
-  size_t from_idx = result->GetIndexForAddress(from_addr);
-  size_t to_idx = result->GetIndexForAddress(to_addr);
-  // There can be code moves that are not related to JS code.
-  if (from_idx != to_idx && result->entities_map[from_idx] >= 0) {
-    CHECK_EQ(-1, result->entities_map[to_idx]);
-    result->entities_map[to_idx] = result->entities_map[from_idx];
-    result->entities_map[from_idx] = -1;
-  };
-}
-
-
-static void ParseLog(char* start, char* end, ParseLogResult* result) {
-  // Pass 1: Calculate boundaries of addresses and entities count.
-  ParserCycle(start, end, result,
-              Pass1CodeCreation, Pass1CodeDelete, Pass1CodeMove);
-
-  printf("min_addr: %p, max_addr: %p, entities: %d\n",
-         result->bounds.GetMinAddr(), result->bounds.GetMaxAddr(),
-         result->max_entities);
-
-  result->AllocateEntities();
-
-  // Pass 2: Fill in code entries data.
-  ParserCycle(start, end, result,
-              Pass2CodeCreation, Pass2CodeDelete, Pass2CodeMove);
-}
-
-
-static inline void PrintCodeEntityInfo(CodeEntityInfo entity) {
-  const int max_len = 50;
-  if (entity != NULL) {
-    char* eol = strchr(entity, '\n');
-    int len = static_cast<int>(eol - entity);
-    len = len <= max_len ? len : max_len;
-    printf("%-*.*s ", max_len, len, entity);
-  } else {
-    printf("%*s", max_len + 1, "");
-  }
-}
-
-
-static void PrintCodeEntitiesInfo(
-    bool is_equal, Address addr,
-    CodeEntityInfo l_entity, CodeEntityInfo r_entity) {
-  printf("%c %p ", is_equal ? ' ' : '*', addr);
-  PrintCodeEntityInfo(l_entity);
-  PrintCodeEntityInfo(r_entity);
-  printf("\n");
-}
-
-
-static inline int StrChrLen(const char* s, char c) {
-  return static_cast<int>(strchr(s, c) - s);
-}
-
-
-static bool AreFuncSizesEqual(CodeEntityInfo ref_s, CodeEntityInfo new_s) {
-  int ref_len = StrChrLen(ref_s, ',');
-  int new_len = StrChrLen(new_s, ',');
-  return ref_len == new_len && strncmp(ref_s, new_s, ref_len) == 0;
-}
-
-
-static bool AreFuncNamesEqual(CodeEntityInfo ref_s, CodeEntityInfo new_s) {
-  // Skip size.
-  ref_s = strchr(ref_s, ',') + 1;
-  new_s = strchr(new_s, ',') + 1;
-  CHECK_EQ('"', ref_s[0]);
-  CHECK_EQ('"', new_s[0]);
-  int ref_len = StrChrLen(ref_s + 1, '\"');
-  int new_len = StrChrLen(new_s + 1, '\"');
-  // A special case for ErrorPrototype. Haven't yet figured out why they
-  // are different.
-  const char* error_prototype = "\"ErrorPrototype";
-  if (IsStringEqualTo(error_prototype, ref_s)
-      && IsStringEqualTo(error_prototype, new_s)) {
-    return true;
-  }
-  // Built-in objects have problems too.
-  const char* built_ins[] = {
-      "\"Boolean\"", "\"Function\"", "\"Number\"",
-      "\"Object\"", "\"Script\"", "\"String\""
-  };
-  for (size_t i = 0; i < sizeof(built_ins) / sizeof(*built_ins); ++i) {
-    if (IsStringEqualTo(built_ins[i], new_s)) {
-      return true;
-    }
-  }
-  return ref_len == new_len && strncmp(ref_s, new_s, ref_len) == 0;
-}
-
-
-static bool AreEntitiesEqual(CodeEntityInfo ref_e, CodeEntityInfo new_e) {
-  if (ref_e == NULL && new_e != NULL) return true;
-  if (ref_e != NULL && new_e != NULL) {
-    return AreFuncSizesEqual(ref_e, new_e) && AreFuncNamesEqual(ref_e, new_e);
-  }
-  if (ref_e != NULL && new_e == NULL) {
-    // args_count entities (argument adapters) are not found by heap traversal,
-    // but they are not needed because they doesn't contain any code.
-    ref_e = strchr(ref_e, ',') + 1;
-    const char* args_count = "\"args_count:";
-    return IsStringEqualTo(args_count, ref_e);
-  }
-  return false;
-}
-
-
 // Test that logging of code create / move / delete events
 // is equivalent to traversal of a resulting heap.
 TEST(EquivalenceOfLoggingAndTraversal) {
@@ -1008,86 +481,68 @@
   // P.S. No, V8 can't be re-initialized after disposal, see include/v8.h.
   CHECK(!i::V8::IsRunning());
 
-  i::FLAG_logfile = "*";
-  i::FLAG_log = true;
-  i::FLAG_log_code = true;
-
-  // Make sure objects move.
-  bool saved_always_compact = i::FLAG_always_compact;
-  if (!i::FLAG_never_compact) {
-    i::FLAG_always_compact = true;
-  }
-
-  v8::HandleScope scope;
-  v8::Handle<v8::Value> global_object = v8::Handle<v8::Value>();
-  v8::Handle<v8::Context> env = v8::Context::New(
-      0, v8::Handle<v8::ObjectTemplate>(), global_object);
-  env->Enter();
+  // Start with profiling to capture all code events from the beginning.
+  ScopedLoggerInitializer initialize_logger(false);
 
   // Compile and run a function that creates other functions.
-  CompileAndRunScript(
+  CompileRun(
       "(function f(obj) {\n"
       "  obj.test =\n"
       "    (function a(j) { return function b() { return j; } })(100);\n"
       "})(this);");
-  HEAP->CollectAllGarbage(false);
-
-  EmbeddedVector<char, 204800> buffer;
-  int log_size;
-  ParseLogResult ref_result;
-
-  // Retrieve the log.
-  {
-    // Make sure that no GCs occur prior to LogCompiledFunctions call.
-    i::AssertNoAllocation no_alloc;
-
-    log_size = GetLogLines(0, &buffer);
-    CHECK_GT(log_size, 0);
-    CHECK_GT(buffer.length(), log_size);
-
-    // Fill a map of compiled code objects.
-    ParseLog(buffer.start(), buffer.start() + log_size, &ref_result);
-  }
+  v8::V8::PauseProfiler();
+  HEAP->CollectAllGarbage(true);
+  LOGGER->StringEvent("test-logging-done", "");
 
   // Iterate heap to find compiled functions, will write to log.
   LOGGER->LogCompiledFunctions();
-  char* new_log_start = buffer.start() + log_size;
-  const int new_log_size = LOGGER->GetLogLines(
-      log_size, new_log_start, buffer.length() - log_size);
-  CHECK_GT(new_log_size, 0);
-  CHECK_GT(buffer.length(), log_size + new_log_size);
+  LOGGER->StringEvent("test-traversal-done", "");
 
-  // Fill an equivalent map of compiled code objects.
-  ParseLogResult new_result;
-  ParseLog(new_log_start, new_log_start + new_log_size, &new_result);
+  bool exists = false;
+  i::Vector<const char> log(
+      i::ReadFile(initialize_logger.StopLoggingGetTempFile(), &exists, true));
+  CHECK(exists);
+  v8::Handle<v8::String> log_str = v8::String::New(log.start(), log.length());
+  initialize_logger.env()->Global()->Set(v8_str("_log"), log_str);
 
-  // Test their actual equivalence.
-  Interval combined;
-  combined.CloneFrom(&ref_result.bounds);
-  combined.CloneFrom(&new_result.bounds);
-  Interval* iter = &combined;
-  bool results_equal = true;
-
-  while (iter != NULL) {
-    for (Address addr = iter->raw_min_addr();
-         addr <= iter->raw_max_addr(); ++addr) {
-      CodeEntityInfo ref_entity = ref_result.GetEntity(addr);
-      CodeEntityInfo new_entity = new_result.GetEntity(addr);
-      if (ref_entity != NULL || new_entity != NULL) {
-        const bool equal = AreEntitiesEqual(ref_entity, new_entity);
-        if (!equal) results_equal = false;
-        PrintCodeEntitiesInfo(equal, addr, ref_entity, new_entity);
-      }
+  const char* scripts[] = {
+    "tools/splaytree.js", "tools/codemap.js", "tools/csvparser.js",
+    "tools/consarray.js", "tools/profile.js", "tools/profile_view.js",
+    "tools/logreader.js", "test/cctest/log-eq-of-logging-and-traversal.js"
+  };
+  int scripts_count = sizeof(scripts) / sizeof(scripts[0]);
+  v8::Handle<v8::Value> last_result;
+  for (int i = 0; i < scripts_count; ++i) {
+    bool exists = true;
+    i::Vector<const char> source(i::ReadFile(scripts[i], &exists, true));
+    CHECK(exists);
+    CHECK_GT(source.length(), 0);
+    v8::Handle<v8::String> source_str =
+        v8::String::New(source.start(), source.length());
+    v8::TryCatch try_catch;
+    v8::Handle<v8::Script> script =
+        v8::Script::Compile(source_str, v8_str(scripts[i]));
+    if (script.IsEmpty()) {
+      v8::String::Utf8Value exception(try_catch.Exception());
+      printf("compile %s: %s\n", scripts[i], *exception);
+      CHECK(false);
     }
-    iter = iter->get_next();
+    last_result = script->Run();
+    if (last_result.IsEmpty()) {
+      v8::String::Utf8Value exception(try_catch.Exception());
+      printf("run %s: %s\n", scripts[i], *exception);
+      CHECK(false);
+    }
   }
-  // Make sure that all log data is written prior crash due to CHECK failure.
-  fflush(stdout);
-  CHECK(results_equal);
-
-  env->Exit();
-  LOGGER->TearDown();
-  i::FLAG_always_compact = saved_always_compact;
+  // The result either be a "true" literal or problem description.
+  if (!last_result->IsTrue()) {
+    v8::Local<v8::String> s = last_result->ToString();
+    i::ScopedVector<char> data(s->Length() + 1);
+    CHECK_NE(NULL, data.start());
+    s->WriteAscii(data.start());
+    printf("%s\n", data.start());
+    // Make sure that our output is written prior crash due to CHECK failure.
+    fflush(stdout);
+    CHECK(false);
+  }
 }
-
-#endif  // ENABLE_LOGGING_AND_PROFILING
diff --git a/test/cctest/test-profile-generator.cc b/test/cctest/test-profile-generator.cc
index fbe5834..6d30443 100644
--- a/test/cctest/test-profile-generator.cc
+++ b/test/cctest/test-profile-generator.cc
@@ -2,8 +2,6 @@
 //
 // Tests of profiles generator and utilities.
 
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
 #include "v8.h"
 #include "profile-generator-inl.h"
 #include "cctest.h"
@@ -824,5 +822,3 @@
   for (int i = 0; i < CpuProfilesCollection::kMaxSimultaneousProfiles; ++i)
     i::DeleteArray(titles[i]);
 }
-
-#endif  // ENABLE_LOGGING_AND_PROFILING
diff --git a/test/message/regress/regress-1527.js b/test/message/regress/regress-1527.js
new file mode 100644
index 0000000..682e386
--- /dev/null
+++ b/test/message/regress/regress-1527.js
@@ -0,0 +1,33 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+var o1 = {foo: 'bar'};
+var o2 = {
+  1: 'blah',
+  2: o1.foo,
+  3: foo
+}
diff --git a/test/message/regress/regress-1527.out b/test/message/regress/regress-1527.out
new file mode 100644
index 0000000..dc17fb3
--- /dev/null
+++ b/test/message/regress/regress-1527.out
@@ -0,0 +1,32 @@
+# Copyright 2011 the V8 project authors. All rights reserved.
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+#       copyright notice, this list of conditions and the following
+#       disclaimer in the documentation and/or other materials provided
+#       with the distribution.
+#     * Neither the name of Google Inc. nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*%(basename)s:32: ReferenceError: foo is not defined
+  3: foo
+     ^
+ReferenceError: foo is not defined
+    at *%(basename)s:32:6
diff --git a/test/mjsunit/debug-backtrace.js b/test/mjsunit/debug-backtrace.js
index d15b2d2..3647913 100644
--- a/test/mjsunit/debug-backtrace.js
+++ b/test/mjsunit/debug-backtrace.js
@@ -195,7 +195,7 @@
       assertEquals("m", response.lookup(frame.func.ref).inferredName);
       assertFalse(frame.constructCall);
       assertEquals(35, frame.line);
-      assertEquals(2, frame.column);
+      assertEquals(6, frame.column);
       assertEquals(0, frame.arguments.length);
 
       json = '{"seq":0,"type":"request","command":"frame","arguments":{"number":3}}'
@@ -269,4 +269,3 @@
 // Make sure that the debug event listener vas invoked.
 assertFalse(exception, "exception in listener");
 assertTrue(listenerCalled);
-
diff --git a/test/mjsunit/harmony/proxies.js b/test/mjsunit/harmony/proxies.js
index 490877c..37f3513 100644
--- a/test/mjsunit/harmony/proxies.js
+++ b/test/mjsunit/harmony/proxies.js
@@ -35,7 +35,6 @@
   var o = Proxy.create(handler)
   assertEquals(42, o.a)
   assertEquals(42, o["b"])
-//  assertEquals(Object.getOwnPropertyDescriptor(o, "b").value, 42)
 }
 
 TestGet({
@@ -69,6 +68,64 @@
 }))
 
 
+function TestGetCall(handler) {
+  var p = Proxy.create(handler)
+  assertEquals(55, p.f())
+  assertEquals(55, p.f("unused", "arguments"))
+  assertEquals(55, p.f.call(p))
+  assertEquals(55, p.withargs(45, 5))
+  assertEquals(55, p.withargs.call(p, 11, 22))
+  assertEquals("6655", "66" + p)  // calls p.toString
+}
+
+TestGetCall({
+  get: function(r, k) { return function() { return 55 } }
+})
+TestGetCall({
+  get: function(r, k) { return this.get2(r, k) },
+  get2: function(r, k) { return function() { return 55 } }
+})
+TestGetCall({
+  getPropertyDescriptor: function(k) {
+    return {value: function() { return 55 }}
+  }
+})
+TestGetCall({
+  getPropertyDescriptor: function(k) { return this.getPropertyDescriptor2(k) },
+  getPropertyDescriptor2: function(k) {
+    return {value: function() { return 55 }}
+  }
+})
+TestGetCall({
+  getPropertyDescriptor: function(k) {
+    return {get value() { return function() { return 55 } }}
+  }
+})
+TestGetCall({
+  get: undefined,
+  getPropertyDescriptor: function(k) {
+    return {value: function() { return 55 }}
+  }
+})
+TestGetCall({
+  get: function(r, k) {
+    if (k == "gg") {
+      return function() { return 55 }
+    } else if (k == "withargs") {
+      return function(n, m) { return n + m * 2 }
+    } else {
+      return function() { return this.gg() }
+    }
+  }
+})
+
+TestGetCall(Proxy.create({
+  get: function(pr, pk) {
+    return function(r, k) { return function() { return 55 } }
+  }
+}))
+
+
 
 // Setters.
 
@@ -82,9 +139,6 @@
   assertEquals(43, o["b"] = 43)
   assertEquals("b", key)
   assertEquals(43, val)
-//  assertTrue(Object.defineProperty(o, "c", {value: 44}))
-//  assertEquals("c", key)
-//  assertEquals(44, val)
 }
 
 TestSet({
@@ -149,7 +203,7 @@
 
 
 
-// Property definition (Object.defineProperty).
+// Property definition (Object.defineProperty and Object.defineProperties).
 
 var key
 var desc
@@ -193,7 +247,7 @@
   assertEquals("zzz", key)
   assertEquals(0, Object.getOwnPropertyNames(desc).length)
 
-// This test requires [s in proxy] to be implemented first.
+// TODO(rossberg): This test requires [s in proxy] to be implemented first.
 //  var d = Proxy.create({
 //    get: function(r, k) { return (k === "value") ? 77 : void 0 },
 //    getOwnPropertyNames: function() { return ["value"] }
@@ -204,6 +258,20 @@
 //  assertEquals("p", key)
 //  assertEquals(1, Object.getOwnPropertyNames(desc).length)
 //  assertEquals(77, desc.value)
+
+  var props = {
+    'bla': {},
+    blub: {get: function() { return true }},
+    '': {get value() { return 20 }},
+    last: {value: 21, configurable: true, mine: "eyes"}
+  }
+  Object.defineProperty(props, "hidden", {value: "hidden", enumerable: false})
+  assertEquals(o, Object.defineProperties(o, props))
+  assertEquals("last", key)
+  assertEquals(2, Object.getOwnPropertyNames(desc).length)
+  assertEquals(21, desc.value)
+  assertEquals(true, desc.configurable)
+  assertEquals(undefined, desc.mine)  // Arguably a bug in the spec...
 }
 
 TestDefine({
@@ -221,6 +289,44 @@
 
 
 
+// Property descriptors (Object.getOwnPropertyDescriptor).
+
+function TestDescriptor(handler) {
+  var o = Proxy.create(handler)
+  var descs = [
+    {configurable: true},
+    {value: 34, enumerable: true, configurable: true},
+    {value: 3, writable: false, mine: "eyes", configurable: true},
+    {get value() { return 20 }, get configurable() { return true }},
+    {get: function() { "get" }, set: function() { "set" }, configurable: true}
+  ]
+  for (var i = 0; i < descs.length; ++i) {
+    assertEquals(o, Object.defineProperty(o, i, descs[i]))
+    var desc = Object.getOwnPropertyDescriptor(o, i)
+    for (p in descs[i]) {
+      // TODO(rossberg): Ignore user attributes as long as the spec isn't
+      // fixed suitably.
+      if (p != "mine") assertEquals(descs[i][p], desc[p])
+    }
+    assertEquals(undefined, Object.getOwnPropertyDescriptor(o, "absent"))
+  }
+}
+
+
+TestDescriptor({
+  defineProperty: function(k, d) { this["__" + k] = d; return true },
+  getOwnPropertyDescriptor: function(k) { return this["__" + k] }
+})
+TestDescriptor({
+  defineProperty: function(k, d) { this["__" + k] = d; return true },
+  getOwnPropertyDescriptor: function(k) {
+    return this.getOwnPropertyDescriptor2(k)
+  },
+  getOwnPropertyDescriptor2: function(k) { return this["__" + k] }
+})
+
+
+
 // Comparison.
 
 function TestComparison(eq) {
@@ -309,7 +415,7 @@
 
 
 
-// Property names (Object.getOwnPropertyNames).
+// Property names (Object.getOwnPropertyNames, Object.keys).
 
 function TestPropertyNames(names, handler) {
   var p = Proxy.create(handler)
@@ -331,3 +437,51 @@
     return function() { return [{}] }
   }
 })
+
+
+function TestKeys(names, handler) {
+  var p = Proxy.create(handler)
+  assertArrayEquals(names, Object.keys(p))
+}
+
+TestKeys([], {
+  keys: function() { return [] }
+})
+TestKeys(["a", "zz", " ", "0"], {
+  keys: function() { return ["a", "zz", " ", 0] }
+})
+TestKeys(["throw", "function "], {
+  keys: function() { return this.keys2() },
+  keys2: function() { return ["throw", "function "] }
+})
+TestKeys(["[object Object]"], {
+  get keys() {
+    return function() { return [{}] }
+  }
+})
+TestKeys(["a", "0"], {
+  getOwnPropertyNames: function() { return ["a", 23, "zz", "", 0] },
+  getOwnPropertyDescriptor: function(k) { return {enumerable: k.length == 1} }
+})
+TestKeys(["23", "zz", ""], {
+  getOwnPropertyNames: function() { return this.getOwnPropertyNames2() },
+  getOwnPropertyNames2: function() { return ["a", 23, "zz", "", 0] },
+  getOwnPropertyDescriptor: function(k) {
+    return this.getOwnPropertyDescriptor2(k)
+  },
+  getOwnPropertyDescriptor2: function(k) { return {enumerable: k.length != 1} }
+})
+TestKeys(["a", "b", "c", "5"], {
+  get getOwnPropertyNames() {
+    return function() { return ["0", 4, "a", "b", "c", 5] }
+  },
+  get getOwnPropertyDescriptor() {
+    return function(k) { return {enumerable: k >= "44"} }
+  }
+})
+TestKeys([], {
+  get getOwnPropertyNames() {
+    return function() { return ["a", "b", "c"] }
+  },
+  getOwnPropertyDescriptor: function(k) { return {} }
+})
diff --git a/test/mjsunit/regress/regress-88591.js b/test/mjsunit/regress/regress-88591.js
new file mode 100644
index 0000000..e42570a
--- /dev/null
+++ b/test/mjsunit/regress/regress-88591.js
@@ -0,0 +1,42 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Regression test for a crash.  A data property in the global object's
+// prototype shadowed by a setter in the global object's prototype's
+// prototype would crash or assert when seen by Runtime_DeclareContextSlot.
+var called = false;
+Object.prototype.__defineSetter__('x', function(x) { called = true; });
+Object.prototype.__defineGetter__('x', function () { return 0; });
+
+this.__proto__ = { x: 1 };
+
+try { fail; } catch (e) { eval('const x = 2'); }
+
+var o = Object.getOwnPropertyDescriptor(this, 'x');
+assertFalse(called);
+assertEquals(2, o.value);
+assertEquals(false, o.writable);
diff --git a/test/mjsunit/tools/profile_view.js b/test/mjsunit/tools/profile_view.js
index 7f60119..d62205b 100644
--- a/test/mjsunit/tools/profile_view.js
+++ b/test/mjsunit/tools/profile_view.js
@@ -26,7 +26,8 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 // Load source code files from <project root>/tools.
-// Files: tools/consarray.js tools/profile.js tools/profile_view.js
+// Files: tools/codemap.js tools/consarray.js tools/profile.js
+// Files: tools/profile_view.js
 
 
 function createNode(name, time, opt_parent) {
diff --git a/test/test262/test262.status b/test/test262/test262.status
index bcaa304..f68b85d 100644
--- a/test/test262/test262.status
+++ b/test/test262/test262.status
@@ -453,12 +453,6 @@
 #      (15.4.5.1 step 4.e.ii)
 15.2.3.6-4-276: FAIL
 # Bug? Object.defineProperty - 'O' is an Arguments object of a function that has
-#      formal parameters, 'name' is own property which is defined in both
-#      [[ParameterMap]] of 'O' and 'O', is deleted afterwards, and 'desc' is
-#      accessor descriptor, test 'name' is redefined in 'O' with all correct
-#      attribute values (10.6 [[DefineOwnProperty]] step 3)
-15.2.3.6-4-290-1: FAIL
-# Bug? Object.defineProperty - 'O' is an Arguments object of a function that has
 #      formal parameters, 'name' is own accessor property of 'O' which is also
 #      defined in [[ParameterMap]] of 'O', and 'desc' is accessor descriptor,
 #      test updating multiple attribute values of 'name' (10.6
@@ -864,12 +858,6 @@
 #      ToUint32('P') is greater than value of the length property in 'O'
 #      (15.4.5.1 step 4.e.ii)
 15.2.3.7-6-a-265: FAIL
-# Bug? Object.defineProperties - 'O' is an Arguments object, 'P' is own property
-#      which is ever defined in both [[ParameterMap]] of 'O' and 'O', and is
-#      deleted afterwards, and 'desc' is accessor descriptor, test 'P' is
-#      redefined in 'O' with all correct attribute values (10.6
-#      [[DefineOwnProperty]] step 3)
-15.2.3.7-6-a-279: FAIL
 # Bug? Object.defineProperties - 'O' is an Arguments object, 'P' is own accessor
 #      property of 'O' which is also defined in [[ParameterMap]] of 'O', and
 #      'desc' is accessor descriptor, test updating multiple attribute values of
diff --git a/tools/codemap.js b/tools/codemap.js
index 71a99cc..dec494a 100644
--- a/tools/codemap.js
+++ b/tools/codemap.js
@@ -211,6 +211,14 @@
 
 
 /**
+ * Returns an array of pairs of all dynamic code entries and their addresses.
+ */
+CodeMap.prototype.getAllDynamicEntriesWithAddresses = function() {
+  return this.dynamics_.exportKeysAndValues();
+};
+
+
+/**
  * Returns an array of all static code entries.
  */
 CodeMap.prototype.getAllStaticEntries = function() {
diff --git a/tools/gcmole/gcmole.lua b/tools/gcmole/gcmole.lua
index 4afc66d..f8d3b62 100644
--- a/tools/gcmole/gcmole.lua
+++ b/tools/gcmole/gcmole.lua
@@ -97,8 +97,6 @@
       .. (plugin_args or "")
       .. " -triple " .. triple
       .. " -D" .. arch_define
-      .. " -DENABLE_VMSTATE_TRACKING"
-      .. " -DENABLE_LOGGING_AND_PROFILING"
       .. " -DENABLE_DEBUGGER_SUPPORT"
       .. " -Isrc"
 end
diff --git a/tools/gyp/v8.gyp b/tools/gyp/v8.gyp
index 1d4cbfd..2650483 100644
--- a/tools/gyp/v8.gyp
+++ b/tools/gyp/v8.gyp
@@ -62,10 +62,7 @@
     ['use_system_v8==0', {
       'target_defaults': {
         'defines': [
-          'ENABLE_LOGGING_AND_PROFILING',
           'ENABLE_DEBUGGER_SUPPORT',
-          'ENABLE_VMSTATE_TRACKING',
-          'V8_FAST_TLS',
         ],
         'conditions': [
           ['OS!="mac"', {
diff --git a/tools/profile.js b/tools/profile.js
index c9c9437..10a07f8 100644
--- a/tools/profile.js
+++ b/tools/profile.js
@@ -162,8 +162,16 @@
     // Function object has been overwritten with a new one.
     func.name = name;
   }
-  var entry = new Profile.DynamicFuncCodeEntry(size, type, func, state);
-  this.codeMap_.addCode(start, entry);
+  var entry = this.codeMap_.findDynamicEntryByStartAddress(start);
+  if (entry) {
+    if (entry.size === size && entry.func === func) {
+      // Entry state has changed.
+      entry.state = state;
+    }
+  } else {
+    entry = new Profile.DynamicFuncCodeEntry(size, type, func, state);
+    this.codeMap_.addCode(start, entry);
+  }
   return entry;
 };
 
@@ -374,6 +382,31 @@
 
 
 /**
+ * Cleans up function entries that are not referenced by code entries.
+ */
+Profile.prototype.cleanUpFuncEntries = function() {
+  var referencedFuncEntries = [];
+  var entries = this.codeMap_.getAllDynamicEntriesWithAddresses();
+  for (var i = 0, l = entries.length; i < l; ++i) {
+    if (entries[i][1].constructor === Profile.FunctionEntry) {
+      entries[i][1].used = false;
+    }
+  }
+  for (var i = 0, l = entries.length; i < l; ++i) {
+    if ("func" in entries[i][1]) {
+      entries[i][1].func.used = true;
+    }
+  }
+  for (var i = 0, l = entries.length; i < l; ++i) {
+    if (entries[i][1].constructor === Profile.FunctionEntry &&
+        !entries[i][1].used) {
+      this.codeMap_.deleteCode(entries[i][0]);
+    }
+  }
+};
+
+
+/**
  * Creates a dynamic code entry.
  *
  * @param {number} size Code size.
@@ -408,6 +441,11 @@
 };
 
 
+Profile.DynamicCodeEntry.prototype.toString = function() {
+  return this.getName() + ': ' + this.size.toString(16);
+};
+
+
 /**
  * Creates a dynamic code entry.
  *
@@ -448,6 +486,11 @@
 };
 
 
+Profile.DynamicFuncCodeEntry.prototype.toString = function() {
+  return this.getName() + ': ' + this.size.toString(16);
+};
+
+
 /**
  * Creates a shared function object entry.
  *
@@ -473,6 +516,7 @@
   return name;
 };
 
+Profile.FunctionEntry.prototype.toString = CodeMap.CodeEntry.prototype.toString;
 
 /**
  * Constructs a call graph.
diff --git a/tools/splaytree.js b/tools/splaytree.js
index 1c9aab9..d272a9e 100644
--- a/tools/splaytree.js
+++ b/tools/splaytree.js
@@ -191,6 +191,17 @@
 
 
 /**
+ * @return {Array<*>} An array containing all the values of tree's nodes paired
+ *     with keys.
+ */
+SplayTree.prototype.exportKeysAndValues = function() {
+  var result = [];
+  this.traverse_(function(node) { result.push([node.key, node.value]); });
+  return result;
+};
+
+
+/**
  * @return {Array<*>} An array containing all the values of tree's nodes.
  */
 SplayTree.prototype.exportValues = function() {