| Index: src/log.cc
 | 
| diff --git a/src/log.cc b/src/log.cc
 | 
| index 3ce207229a515ea8bbafa6b99da9fcf184db4b5e..124b37b7242f0c6608b19441e04ffac75f519737 100644
 | 
| --- a/src/log.cc
 | 
| +++ b/src/log.cc
 | 
| @@ -334,10 +334,187 @@ void Profiler::Run() {
 | 
|  }
 | 
|  
 | 
|  
 | 
| +// Low-level profiling event structures.
 | 
| +
 | 
| +struct LowLevelCodeCreateStruct {
 | 
| +  static const char kTag = 'C';
 | 
| +
 | 
| +  int32_t name_size;
 | 
| +  Address code_address;
 | 
| +  int32_t code_size;
 | 
| +};
 | 
| +
 | 
| +
 | 
| +struct LowLevelCodeMoveStruct {
 | 
| +  static const char kTag = 'M';
 | 
| +
 | 
| +  Address from_address;
 | 
| +  Address to_address;
 | 
| +};
 | 
| +
 | 
| +
 | 
| +struct LowLevelCodeDeleteStruct {
 | 
| +  static const char kTag = 'D';
 | 
| +
 | 
| +  Address address;
 | 
| +};
 | 
| +
 | 
| +
 | 
| +struct LowLevelSnapshotPositionStruct {
 | 
| +  static const char kTag = 'P';
 | 
| +
 | 
| +  Address address;
 | 
| +  int32_t position;
 | 
| +};
 | 
| +
 | 
| +
 | 
| +static const char kCodeMovingGCTag = 'G';
 | 
| +
 | 
| +
 | 
|  //
 | 
|  // Logger class implementation.
 | 
|  //
 | 
|  
 | 
| +class Logger::NameMap {
 | 
| + public:
 | 
| +  NameMap() : impl_(&PointerEquals) {}
 | 
| +
 | 
| +  ~NameMap() {
 | 
| +    for (HashMap::Entry* p = impl_.Start(); p != NULL; p = impl_.Next(p)) {
 | 
| +      DeleteArray(static_cast<const char*>(p->value));
 | 
| +    }
 | 
| +  }
 | 
| +
 | 
| +  void Insert(Address code_address, const char* name, int name_size) {
 | 
| +    HashMap::Entry* entry = FindOrCreateEntry(code_address);
 | 
| +    if (entry->value == NULL) {
 | 
| +      entry->value = CopyName(name, name_size);
 | 
| +    }
 | 
| +  }
 | 
| +
 | 
| +  const char* Lookup(Address code_address) {
 | 
| +    HashMap::Entry* entry = FindEntry(code_address);
 | 
| +    return (entry != NULL) ? static_cast<const char*>(entry->value) : NULL;
 | 
| +  }
 | 
| +
 | 
| +  void Remove(Address code_address) {
 | 
| +    HashMap::Entry* entry = FindEntry(code_address);
 | 
| +    if (entry != NULL) DeleteArray(static_cast<const char*>(entry->value));
 | 
| +    RemoveEntry(entry);
 | 
| +  }
 | 
| +
 | 
| +  void Move(Address from, Address to) {
 | 
| +    if (from == to) return;
 | 
| +    HashMap::Entry* from_entry = FindEntry(from);
 | 
| +    ASSERT(from_entry != NULL);
 | 
| +    void* value = from_entry->value;
 | 
| +    RemoveEntry(from_entry);
 | 
| +    HashMap::Entry* to_entry = FindOrCreateEntry(to);
 | 
| +    ASSERT(to_entry->value == NULL);
 | 
| +    to_entry->value = value;
 | 
| +  }
 | 
| +
 | 
| + private:
 | 
| +  static bool PointerEquals(void* lhs, void* rhs) {
 | 
| +    return lhs == rhs;
 | 
| +  }
 | 
| +
 | 
| +  static char* CopyName(const char* name, int name_size) {
 | 
| +    char* result = NewArray<char>(name_size + 1);
 | 
| +    for (int i = 0; i < name_size; ++i) {
 | 
| +      char c = name[i];
 | 
| +      if (c == '\0') c = ' ';
 | 
| +      result[i] = c;
 | 
| +    }
 | 
| +    result[name_size] = '\0';
 | 
| +    return result;
 | 
| +  }
 | 
| +
 | 
| +  HashMap::Entry* FindOrCreateEntry(Address code_address) {
 | 
| +    return impl_.Lookup(code_address, ComputePointerHash(code_address), true);
 | 
| +  }
 | 
| +
 | 
| +  HashMap::Entry* FindEntry(Address code_address) {
 | 
| +    return impl_.Lookup(code_address, ComputePointerHash(code_address), false);
 | 
| +  }
 | 
| +
 | 
| +  void RemoveEntry(HashMap::Entry* entry) {
 | 
| +    impl_.Remove(entry->key, entry->hash);
 | 
| +  }
 | 
| +
 | 
| +  HashMap impl_;
 | 
| +
 | 
| +  DISALLOW_COPY_AND_ASSIGN(NameMap);
 | 
| +};
 | 
| +
 | 
| +
 | 
| +class Logger::NameBuffer {
 | 
| + public:
 | 
| +  NameBuffer() { Reset(); }
 | 
| +
 | 
| +  void Reset() {
 | 
| +    utf8_pos_ = 0;
 | 
| +  }
 | 
| +
 | 
| +  void AppendString(String* str) {
 | 
| +    if (str == NULL) return;
 | 
| +    if (str->HasOnlyAsciiChars()) {
 | 
| +      int utf8_length = Min(str->length(), kUtf8BufferSize - utf8_pos_);
 | 
| +      String::WriteToFlat(str, utf8_buffer_ + utf8_pos_, 0, utf8_length);
 | 
| +      utf8_pos_ += utf8_length;
 | 
| +      return;
 | 
| +    }
 | 
| +    int uc16_length = Min(str->length(), kUc16BufferSize);
 | 
| +    String::WriteToFlat(str, uc16_buffer_, 0, uc16_length);
 | 
| +    for (int i = 0; i < uc16_length && utf8_pos_ < kUtf8BufferSize; ++i) {
 | 
| +      uc16 c = uc16_buffer_[i];
 | 
| +      if (c <= String::kMaxAsciiCharCodeU) {
 | 
| +        utf8_buffer_[utf8_pos_++] = c;
 | 
| +      } else {
 | 
| +        int char_length = unibrow::Utf8::Length(c);
 | 
| +        if (utf8_pos_ + char_length > kUtf8BufferSize) break;
 | 
| +        unibrow::Utf8::Encode(utf8_buffer_ + utf8_pos_, c);
 | 
| +        utf8_pos_ += char_length;
 | 
| +      }
 | 
| +    }
 | 
| +  }
 | 
| +
 | 
| +  void AppendBytes(const char* bytes, int size) {
 | 
| +    size = Min(size, kUtf8BufferSize - utf8_pos_);
 | 
| +    memcpy(utf8_buffer_ + utf8_pos_, bytes, size);
 | 
| +    utf8_pos_ += size;
 | 
| +  }
 | 
| +
 | 
| +  void AppendBytes(const char* bytes) {
 | 
| +    AppendBytes(bytes, StrLength(bytes));
 | 
| +  }
 | 
| +
 | 
| +  void AppendByte(char c) {
 | 
| +    if (utf8_pos_ >= kUtf8BufferSize) return;
 | 
| +    utf8_buffer_[utf8_pos_++] = c;
 | 
| +  }
 | 
| +
 | 
| +  void AppendInt(int n) {
 | 
| +    Vector<char> buffer(utf8_buffer_ + utf8_pos_, kUtf8BufferSize - utf8_pos_);
 | 
| +    int size = OS::SNPrintF(buffer, "%d", n);
 | 
| +    if (size > 0 && utf8_pos_ + size <= kUtf8BufferSize) {
 | 
| +      utf8_pos_ += size;
 | 
| +    }
 | 
| +  }
 | 
| +
 | 
| +  const char* get() { return utf8_buffer_; }
 | 
| +  int size() const { return utf8_pos_; }
 | 
| +
 | 
| + private:
 | 
| +  static const int kUtf8BufferSize = 512;
 | 
| +  static const int kUc16BufferSize = 128;
 | 
| +
 | 
| +  int utf8_pos_;
 | 
| +  char utf8_buffer_[kUtf8BufferSize];
 | 
| +  uc16 uc16_buffer_[kUc16BufferSize];
 | 
| +};
 | 
| +
 | 
| +
 | 
|  Logger::Logger()
 | 
|    : ticker_(NULL),
 | 
|      profiler_(NULL),
 | 
| @@ -347,6 +524,8 @@ Logger::Logger()
 | 
|      cpu_profiler_nesting_(0),
 | 
|      heap_profiler_nesting_(0),
 | 
|      log_(new Log(this)),
 | 
| +    name_buffer_(new NameBuffer),
 | 
| +    address_to_name_map_(NULL),
 | 
|      is_initialized_(false),
 | 
|      last_address_(NULL),
 | 
|      prev_sp_(NULL),
 | 
| @@ -355,10 +534,14 @@ Logger::Logger()
 | 
|      prev_code_(NULL) {
 | 
|  }
 | 
|  
 | 
| +
 | 
|  Logger::~Logger() {
 | 
| +  delete address_to_name_map_;
 | 
| +  delete name_buffer_;
 | 
|    delete log_;
 | 
|  }
 | 
|  
 | 
| +
 | 
|  #define DECLARE_EVENT(ignore1, name) name,
 | 
|  static const char* const kLogEventsNames[Logger::NUMBER_OF_LOG_EVENTS] = {
 | 
|    LOG_EVENTS_AND_TAGS_LIST(DECLARE_EVENT)
 | 
| @@ -735,7 +918,20 @@ void Logger::CodeCreateEvent(LogEventsAndTags tag,
 | 
|                               Code* code,
 | 
|                               const char* comment) {
 | 
|  #ifdef ENABLE_LOGGING_AND_PROFILING
 | 
| -  if (!log_->IsEnabled() || !FLAG_log_code) return;
 | 
| +  if (!log_->IsEnabled()) return;
 | 
| +  if (FLAG_ll_prof || Serializer::enabled()) {
 | 
| +    name_buffer_->Reset();
 | 
| +    name_buffer_->AppendBytes(kLogEventsNames[tag]);
 | 
| +    name_buffer_->AppendByte(':');
 | 
| +    name_buffer_->AppendBytes(comment);
 | 
| +  }
 | 
| +  if (FLAG_ll_prof) {
 | 
| +    LowLevelCodeCreateEvent(code, name_buffer_->get(), name_buffer_->size());
 | 
| +  }
 | 
| +  if (Serializer::enabled()) {
 | 
| +    RegisterSnapshotCodeName(code, name_buffer_->get(), name_buffer_->size());
 | 
| +  }
 | 
| +  if (!FLAG_log_code) return;
 | 
|    LogMessageBuilder msg(this);
 | 
|    msg.Append("%s,%s,",
 | 
|               kLogEventsNames[CODE_CREATION_EVENT],
 | 
| @@ -749,7 +945,6 @@ void Logger::CodeCreateEvent(LogEventsAndTags tag,
 | 
|      msg.Append(*p);
 | 
|    }
 | 
|    msg.Append('"');
 | 
| -  LowLevelCodeCreateEvent(code, &msg);
 | 
|    msg.Append('\n');
 | 
|    msg.WriteToLogFile();
 | 
|  #endif
 | 
| @@ -760,13 +955,30 @@ void Logger::CodeCreateEvent(LogEventsAndTags tag,
 | 
|                               Code* code,
 | 
|                               String* name) {
 | 
|  #ifdef ENABLE_LOGGING_AND_PROFILING
 | 
| -  if (name != NULL) {
 | 
| -    SmartPointer<char> str =
 | 
| -        name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
 | 
| -    CodeCreateEvent(tag, code, *str);
 | 
| -  } else {
 | 
| -    CodeCreateEvent(tag, code, "");
 | 
| +  if (!log_->IsEnabled()) return;
 | 
| +  if (FLAG_ll_prof || Serializer::enabled()) {
 | 
| +    name_buffer_->Reset();
 | 
| +    name_buffer_->AppendBytes(kLogEventsNames[tag]);
 | 
| +    name_buffer_->AppendByte(':');
 | 
| +    name_buffer_->AppendString(name);
 | 
| +  }
 | 
| +  if (FLAG_ll_prof) {
 | 
| +    LowLevelCodeCreateEvent(code, name_buffer_->get(), name_buffer_->size());
 | 
|    }
 | 
| +  if (Serializer::enabled()) {
 | 
| +    RegisterSnapshotCodeName(code, name_buffer_->get(), name_buffer_->size());
 | 
| +  }
 | 
| +  if (!FLAG_log_code) return;
 | 
| +  LogMessageBuilder msg(this);
 | 
| +  msg.Append("%s,%s,",
 | 
| +             kLogEventsNames[CODE_CREATION_EVENT],
 | 
| +             kLogEventsNames[tag]);
 | 
| +  msg.AppendAddress(code->address());
 | 
| +  msg.Append(",%d,\"", code->ExecutableSize());
 | 
| +  msg.AppendDetailed(name, false);
 | 
| +  msg.Append('"');
 | 
| +  msg.Append('\n');
 | 
| +  msg.WriteToLogFile();
 | 
|  #endif
 | 
|  }
 | 
|  
 | 
| @@ -788,7 +1000,20 @@ void Logger::CodeCreateEvent(LogEventsAndTags tag,
 | 
|                               SharedFunctionInfo* shared,
 | 
|                               String* name) {
 | 
|  #ifdef ENABLE_LOGGING_AND_PROFILING
 | 
| -  if (!log_->IsEnabled() || !FLAG_log_code) return;
 | 
| +  if (!log_->IsEnabled()) return;
 | 
| +  if (FLAG_ll_prof || Serializer::enabled()) {
 | 
| +    name_buffer_->Reset();
 | 
| +    name_buffer_->AppendBytes(kLogEventsNames[tag]);
 | 
| +    name_buffer_->AppendByte(':');
 | 
| +    name_buffer_->AppendString(name);
 | 
| +  }
 | 
| +  if (FLAG_ll_prof) {
 | 
| +    LowLevelCodeCreateEvent(code, name_buffer_->get(), name_buffer_->size());
 | 
| +  }
 | 
| +  if (Serializer::enabled()) {
 | 
| +    RegisterSnapshotCodeName(code, name_buffer_->get(), name_buffer_->size());
 | 
| +  }
 | 
| +  if (!FLAG_log_code) return;
 | 
|    if (code == Isolate::Current()->builtins()->builtin(
 | 
|        Builtins::kLazyCompile))
 | 
|      return;
 | 
| @@ -803,7 +1028,6 @@ void Logger::CodeCreateEvent(LogEventsAndTags tag,
 | 
|    msg.Append(",%d,\"%s\",", code->ExecutableSize(), *str);
 | 
|    msg.AppendAddress(shared->address());
 | 
|    msg.Append(",%s", ComputeMarker(code));
 | 
| -  LowLevelCodeCreateEvent(code, &msg);
 | 
|    msg.Append('\n');
 | 
|    msg.WriteToLogFile();
 | 
|  #endif
 | 
| @@ -818,7 +1042,24 @@ void Logger::CodeCreateEvent(LogEventsAndTags tag,
 | 
|                               SharedFunctionInfo* shared,
 | 
|                               String* source, int line) {
 | 
|  #ifdef ENABLE_LOGGING_AND_PROFILING
 | 
| -  if (!log_->IsEnabled() || !FLAG_log_code) return;
 | 
| +  if (!log_->IsEnabled()) return;
 | 
| +  if (FLAG_ll_prof || Serializer::enabled()) {
 | 
| +    name_buffer_->Reset();
 | 
| +    name_buffer_->AppendBytes(kLogEventsNames[tag]);
 | 
| +    name_buffer_->AppendByte(':');
 | 
| +    name_buffer_->AppendString(shared->DebugName());
 | 
| +    name_buffer_->AppendByte(' ');
 | 
| +    name_buffer_->AppendString(source);
 | 
| +    name_buffer_->AppendByte(':');
 | 
| +    name_buffer_->AppendInt(line);
 | 
| +  }
 | 
| +  if (FLAG_ll_prof) {
 | 
| +    LowLevelCodeCreateEvent(code, name_buffer_->get(), name_buffer_->size());
 | 
| +  }
 | 
| +  if (Serializer::enabled()) {
 | 
| +    RegisterSnapshotCodeName(code, name_buffer_->get(), name_buffer_->size());
 | 
| +  }
 | 
| +  if (!FLAG_log_code) return;
 | 
|    LogMessageBuilder msg(this);
 | 
|    SmartPointer<char> name =
 | 
|        shared->DebugName()->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
 | 
| @@ -835,7 +1076,6 @@ void Logger::CodeCreateEvent(LogEventsAndTags tag,
 | 
|               line);
 | 
|    msg.AppendAddress(shared->address());
 | 
|    msg.Append(",%s", ComputeMarker(code));
 | 
| -  LowLevelCodeCreateEvent(code, &msg);
 | 
|    msg.Append('\n');
 | 
|    msg.WriteToLogFile();
 | 
|  #endif
 | 
| @@ -844,14 +1084,26 @@ void Logger::CodeCreateEvent(LogEventsAndTags tag,
 | 
|  
 | 
|  void Logger::CodeCreateEvent(LogEventsAndTags tag, Code* code, int args_count) {
 | 
|  #ifdef ENABLE_LOGGING_AND_PROFILING
 | 
| -  if (!log_->IsEnabled() || !FLAG_log_code) return;
 | 
| +  if (!log_->IsEnabled()) return;
 | 
| +  if (FLAG_ll_prof || Serializer::enabled()) {
 | 
| +    name_buffer_->Reset();
 | 
| +    name_buffer_->AppendBytes(kLogEventsNames[tag]);
 | 
| +    name_buffer_->AppendByte(':');
 | 
| +    name_buffer_->AppendInt(args_count);
 | 
| +  }
 | 
| +  if (FLAG_ll_prof) {
 | 
| +    LowLevelCodeCreateEvent(code, name_buffer_->get(), name_buffer_->size());
 | 
| +  }
 | 
| +  if (Serializer::enabled()) {
 | 
| +    RegisterSnapshotCodeName(code, name_buffer_->get(), name_buffer_->size());
 | 
| +  }
 | 
| +  if (!FLAG_log_code) return;
 | 
|    LogMessageBuilder msg(this);
 | 
|    msg.Append("%s,%s,",
 | 
|               kLogEventsNames[CODE_CREATION_EVENT],
 | 
|               kLogEventsNames[tag]);
 | 
|    msg.AppendAddress(code->address());
 | 
|    msg.Append(",%d,\"args_count: %d\"", code->ExecutableSize(), args_count);
 | 
| -  LowLevelCodeCreateEvent(code, &msg);
 | 
|    msg.Append('\n');
 | 
|    msg.WriteToLogFile();
 | 
|  #endif
 | 
| @@ -860,10 +1112,8 @@ void Logger::CodeCreateEvent(LogEventsAndTags tag, Code* code, int args_count) {
 | 
|  
 | 
|  void Logger::CodeMovingGCEvent() {
 | 
|  #ifdef ENABLE_LOGGING_AND_PROFILING
 | 
| -  if (!log_->IsEnabled() || !FLAG_log_code || !FLAG_ll_prof) return;
 | 
| -  LogMessageBuilder msg(this);
 | 
| -  msg.Append("%s\n", kLogEventsNames[CODE_MOVING_GC]);
 | 
| -  msg.WriteToLogFile();
 | 
| +  if (!log_->IsEnabled() || !FLAG_ll_prof) return;
 | 
| +  LowLevelLogWriteBytes(&kCodeMovingGCTag, sizeof(kCodeMovingGCTag));
 | 
|    OS::SignalCodeMovingGC();
 | 
|  #endif
 | 
|  }
 | 
| @@ -871,7 +1121,20 @@ void Logger::CodeMovingGCEvent() {
 | 
|  
 | 
|  void Logger::RegExpCodeCreateEvent(Code* code, String* source) {
 | 
|  #ifdef ENABLE_LOGGING_AND_PROFILING
 | 
| -  if (!log_->IsEnabled() || !FLAG_log_code) return;
 | 
| +  if (!log_->IsEnabled()) return;
 | 
| +  if (FLAG_ll_prof || Serializer::enabled()) {
 | 
| +    name_buffer_->Reset();
 | 
| +    name_buffer_->AppendBytes(kLogEventsNames[REG_EXP_TAG]);
 | 
| +    name_buffer_->AppendByte(':');
 | 
| +    name_buffer_->AppendString(source);
 | 
| +  }
 | 
| +  if (FLAG_ll_prof) {
 | 
| +    LowLevelCodeCreateEvent(code, name_buffer_->get(), name_buffer_->size());
 | 
| +  }
 | 
| +  if (Serializer::enabled()) {
 | 
| +    RegisterSnapshotCodeName(code, name_buffer_->get(), name_buffer_->size());
 | 
| +  }
 | 
| +  if (!FLAG_log_code) return;
 | 
|    LogMessageBuilder msg(this);
 | 
|    msg.Append("%s,%s,",
 | 
|               kLogEventsNames[CODE_CREATION_EVENT],
 | 
| @@ -880,7 +1143,6 @@ void Logger::RegExpCodeCreateEvent(Code* code, String* source) {
 | 
|    msg.Append(",%d,\"", code->ExecutableSize());
 | 
|    msg.AppendDetailed(source, false);
 | 
|    msg.Append('\"');
 | 
| -  LowLevelCodeCreateEvent(code, &msg);
 | 
|    msg.Append('\n');
 | 
|    msg.WriteToLogFile();
 | 
|  #endif
 | 
| @@ -889,6 +1151,11 @@ void Logger::RegExpCodeCreateEvent(Code* code, String* source) {
 | 
|  
 | 
|  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
 | 
|  }
 | 
| @@ -896,6 +1163,11 @@ void Logger::CodeMoveEvent(Address from, Address to) {
 | 
|  
 | 
|  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
 | 
|  }
 | 
| @@ -903,7 +1175,21 @@ void Logger::CodeDeleteEvent(Address from) {
 | 
|  
 | 
|  void Logger::SnapshotPositionEvent(Address addr, int pos) {
 | 
|  #ifdef ENABLE_LOGGING_AND_PROFILING
 | 
| -  if (!log_->IsEnabled() || !FLAG_log_snapshot_positions) return;
 | 
| +  if (!log_->IsEnabled()) return;
 | 
| +  if (FLAG_ll_prof) LowLevelSnapshotPositionEvent(addr, pos);
 | 
| +  if (Serializer::enabled() && address_to_name_map_ != NULL) {
 | 
| +    const char* code_name = address_to_name_map_->Lookup(addr);
 | 
| +    if (code_name == NULL) return;  // Not a code object.
 | 
| +    LogMessageBuilder msg(this);
 | 
| +    msg.Append("%s,%d,\"", kLogEventsNames[SNAPSHOT_CODE_NAME_EVENT], pos);
 | 
| +    for (const char* p = code_name; *p != '\0'; ++p) {
 | 
| +      if (*p == '"') msg.Append('\\');
 | 
| +      msg.Append(*p);
 | 
| +    }
 | 
| +    msg.Append("\"\n");
 | 
| +    msg.WriteToLogFile();
 | 
| +  }
 | 
| +  if (!FLAG_log_snapshot_positions) return;
 | 
|    LogMessageBuilder msg(this);
 | 
|    msg.Append("%s,", kLogEventsNames[SNAPSHOT_POSITION_EVENT]);
 | 
|    msg.AppendAddress(addr);
 | 
| @@ -1308,7 +1594,7 @@ static int EnumerateCompiledFunctions(Handle<SharedFunctionInfo>* sfis,
 | 
|  
 | 
|  
 | 
|  void Logger::LogCodeObject(Object* object) {
 | 
| -  if (FLAG_log_code) {
 | 
| +  if (FLAG_log_code || FLAG_ll_prof) {
 | 
|      Code* code_object = Code::cast(object);
 | 
|      LogEventsAndTags tag = Logger::STUB_TAG;
 | 
|      const char* description = "Unknown code from the snapshot";
 | 
| @@ -1369,7 +1655,7 @@ void Logger::LogCodeObject(Object* object) {
 | 
|  
 | 
|  void Logger::LogCodeInfo() {
 | 
|  #ifdef ENABLE_LOGGING_AND_PROFILING
 | 
| -  if (!log_->IsEnabled() || !FLAG_log_code || !FLAG_ll_prof) return;
 | 
| +  if (!log_->IsEnabled() || !FLAG_ll_prof) return;
 | 
|  #if V8_TARGET_ARCH_IA32
 | 
|    const char arch[] = "ia32";
 | 
|  #elif V8_TARGET_ARCH_X64
 | 
| @@ -1379,21 +1665,69 @@ void Logger::LogCodeInfo() {
 | 
|  #else
 | 
|    const char arch[] = "unknown";
 | 
|  #endif
 | 
| -  LogMessageBuilder msg(this);
 | 
| -  msg.Append("code-info,%s,%d\n", arch, Code::kHeaderSize);
 | 
| -  msg.WriteToLogFile();
 | 
| +  LowLevelLogWriteBytes(arch, sizeof(arch));
 | 
|  #endif  // ENABLE_LOGGING_AND_PROFILING
 | 
|  }
 | 
|  
 | 
|  
 | 
| -void Logger::LowLevelCodeCreateEvent(Code* code, LogMessageBuilder* msg) {
 | 
| -  if (!FLAG_ll_prof || log_->output_code_handle_ == NULL) return;
 | 
| -  int pos = static_cast<int>(ftell(log_->output_code_handle_));
 | 
| -  size_t rv = fwrite(code->instruction_start(), 1, code->instruction_size(),
 | 
| -                     log_->output_code_handle_);
 | 
| -  ASSERT(static_cast<size_t>(code->instruction_size()) == rv);
 | 
| +void Logger::RegisterSnapshotCodeName(Code* code,
 | 
| +                                      const char* name,
 | 
| +                                      int name_size) {
 | 
| +  ASSERT(Serializer::enabled());
 | 
| +  if (address_to_name_map_ == NULL) {
 | 
| +    address_to_name_map_ = new NameMap;
 | 
| +  }
 | 
| +  address_to_name_map_->Insert(code->address(), name, name_size);
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void Logger::LowLevelCodeCreateEvent(Code* code,
 | 
| +                                     const char* name,
 | 
| +                                     int name_size) {
 | 
| +  if (log_->ll_output_handle_ == NULL) return;
 | 
| +  LowLevelCodeCreateStruct event;
 | 
| +  event.name_size = name_size;
 | 
| +  event.code_address = code->instruction_start();
 | 
| +  ASSERT(event.code_address == code->address() + Code::kHeaderSize);
 | 
| +  event.code_size = code->instruction_size();
 | 
| +  LowLevelLogWriteStruct(event);
 | 
| +  LowLevelLogWriteBytes(name, name_size);
 | 
| +  LowLevelLogWriteBytes(
 | 
| +      reinterpret_cast<const char*>(code->instruction_start()),
 | 
| +      code->instruction_size());
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void Logger::LowLevelCodeMoveEvent(Address from, Address to) {
 | 
| +  if (log_->ll_output_handle_ == NULL) return;
 | 
| +  LowLevelCodeMoveStruct event;
 | 
| +  event.from_address = from + Code::kHeaderSize;
 | 
| +  event.to_address = to + Code::kHeaderSize;
 | 
| +  LowLevelLogWriteStruct(event);
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void Logger::LowLevelCodeDeleteEvent(Address from) {
 | 
| +  if (log_->ll_output_handle_ == NULL) return;
 | 
| +  LowLevelCodeDeleteStruct event;
 | 
| +  event.address = from + Code::kHeaderSize;
 | 
| +  LowLevelLogWriteStruct(event);
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void Logger::LowLevelSnapshotPositionEvent(Address addr, int pos) {
 | 
| +  if (log_->ll_output_handle_ == NULL) return;
 | 
| +  LowLevelSnapshotPositionStruct event;
 | 
| +  event.address = addr + Code::kHeaderSize;
 | 
| +  event.position = pos;
 | 
| +  LowLevelLogWriteStruct(event);
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void Logger::LowLevelLogWriteBytes(const char* bytes, int size) {
 | 
| +  size_t rv = fwrite(bytes, 1, size, log_->ll_output_handle_);
 | 
| +  ASSERT(static_cast<size_t>(size) == rv);
 | 
|    USE(rv);
 | 
| -  msg->Append(",%d", pos);
 | 
|  }
 | 
|  
 | 
|  
 | 
| @@ -1496,7 +1830,6 @@ bool Logger::Setup() {
 | 
|  
 | 
|    // --ll-prof implies --log-code and --log-snapshot-positions.
 | 
|    if (FLAG_ll_prof) {
 | 
| -    FLAG_log_code = true;
 | 
|      FLAG_log_snapshot_positions = true;
 | 
|    }
 | 
|  
 | 
| @@ -1523,7 +1856,7 @@ bool Logger::Setup() {
 | 
|  
 | 
|    bool start_logging = 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_log_regexp || FLAG_log_state_changes || FLAG_ll_prof;
 | 
|  
 | 
|    if (start_logging) {
 | 
|      logging_nesting_ = 1;
 | 
| 
 |