1a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Copyright 2009 the V8 project authors. All rights reserved. 2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without 3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are 4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met: 5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions of source code must retain the above copyright 7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// notice, this list of conditions and the following disclaimer. 8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions in binary form must reproduce the above 9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// copyright notice, this list of conditions and the following 10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// disclaimer in the documentation and/or other materials provided 11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// with the distribution. 12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Neither the name of Google Inc. nor the names of its 13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// contributors may be used to endorse or promote products derived 14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// from this software without specific prior written permission. 15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "v8.h" 29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "log-utils.h" 3144f0eee88ff00398ff7f715fab053374d808c90dSteve Block#include "string-stream.h" 32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochconst char* const Log::kLogToTemporaryFile = "&"; 38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4044f0eee88ff00398ff7f715fab053374d808c90dSteve BlockLog::Log(Logger* logger) 413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : is_stopped_(false), 4244f0eee88ff00398ff7f715fab053374d808c90dSteve Block output_handle_(NULL), 43257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ll_output_handle_(NULL), 4444f0eee88ff00398ff7f715fab053374d808c90dSteve Block mutex_(NULL), 4544f0eee88ff00398ff7f715fab053374d808c90dSteve Block message_buffer_(NULL), 4644f0eee88ff00398ff7f715fab053374d808c90dSteve Block logger_(logger) { 4744f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 4844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 4944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 5044f0eee88ff00398ff7f715fab053374d808c90dSteve Blockstatic void AddIsolateIdIfNeeded(StringStream* stream) { 5144f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate = Isolate::Current(); 5244f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (isolate->IsDefaultIsolate()) return; 5344f0eee88ff00398ff7f715fab053374d808c90dSteve Block stream->Add("isolate-%p-", isolate); 5444f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5744f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Log::Initialize() { 58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block mutex_ = OS::CreateMutex(); 59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block message_buffer_ = NewArray<char>(kMessageBufferSize); 6044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 6144f0eee88ff00398ff7f715fab053374d808c90dSteve Block // --log-all enables all the log flags. 6244f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (FLAG_log_all) { 6344f0eee88ff00398ff7f715fab053374d808c90dSteve Block FLAG_log_runtime = true; 6444f0eee88ff00398ff7f715fab053374d808c90dSteve Block FLAG_log_api = true; 6544f0eee88ff00398ff7f715fab053374d808c90dSteve Block FLAG_log_code = true; 6644f0eee88ff00398ff7f715fab053374d808c90dSteve Block FLAG_log_gc = true; 6744f0eee88ff00398ff7f715fab053374d808c90dSteve Block FLAG_log_suspect = true; 6844f0eee88ff00398ff7f715fab053374d808c90dSteve Block FLAG_log_handles = true; 6944f0eee88ff00398ff7f715fab053374d808c90dSteve Block FLAG_log_regexp = true; 7044f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 7144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 7244f0eee88ff00398ff7f715fab053374d808c90dSteve Block // --prof implies --log-code. 7344f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (FLAG_prof) FLAG_log_code = true; 7444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 7544f0eee88ff00398ff7f715fab053374d808c90dSteve Block // --prof_lazy controls --log-code, implies --noprof_auto. 7644f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (FLAG_prof_lazy) { 7744f0eee88ff00398ff7f715fab053374d808c90dSteve Block FLAG_log_code = false; 7844f0eee88ff00398ff7f715fab053374d808c90dSteve Block FLAG_prof_auto = false; 7944f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 8044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool open_log_file = FLAG_log || FLAG_log_runtime || FLAG_log_api 8244f0eee88ff00398ff7f715fab053374d808c90dSteve Block || FLAG_log_code || FLAG_log_gc || FLAG_log_handles || FLAG_log_suspect 83257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch || FLAG_log_regexp || FLAG_log_state_changes || FLAG_ll_prof; 8444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 8544f0eee88ff00398ff7f715fab053374d808c90dSteve Block // If we're logging anything, we need to open the log file. 8644f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (open_log_file) { 8744f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (strcmp(FLAG_logfile, "-") == 0) { 8844f0eee88ff00398ff7f715fab053374d808c90dSteve Block OpenStdout(); 893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else if (strcmp(FLAG_logfile, kLogToTemporaryFile) == 0) { 903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch OpenTemporaryFile(); 913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 9244f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (strchr(FLAG_logfile, '%') != NULL || 9344f0eee88ff00398ff7f715fab053374d808c90dSteve Block !Isolate::Current()->IsDefaultIsolate()) { 9444f0eee88ff00398ff7f715fab053374d808c90dSteve Block // If there's a '%' in the log file name we have to expand 9544f0eee88ff00398ff7f715fab053374d808c90dSteve Block // placeholders. 9644f0eee88ff00398ff7f715fab053374d808c90dSteve Block HeapStringAllocator allocator; 9744f0eee88ff00398ff7f715fab053374d808c90dSteve Block StringStream stream(&allocator); 9844f0eee88ff00398ff7f715fab053374d808c90dSteve Block AddIsolateIdIfNeeded(&stream); 9944f0eee88ff00398ff7f715fab053374d808c90dSteve Block for (const char* p = FLAG_logfile; *p; p++) { 10044f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (*p == '%') { 10144f0eee88ff00398ff7f715fab053374d808c90dSteve Block p++; 10244f0eee88ff00398ff7f715fab053374d808c90dSteve Block switch (*p) { 10344f0eee88ff00398ff7f715fab053374d808c90dSteve Block case '\0': 10444f0eee88ff00398ff7f715fab053374d808c90dSteve Block // If there's a % at the end of the string we back up 10544f0eee88ff00398ff7f715fab053374d808c90dSteve Block // one character so we can escape the loop properly. 10644f0eee88ff00398ff7f715fab053374d808c90dSteve Block p--; 10744f0eee88ff00398ff7f715fab053374d808c90dSteve Block break; 10844f0eee88ff00398ff7f715fab053374d808c90dSteve Block case 't': { 10944f0eee88ff00398ff7f715fab053374d808c90dSteve Block // %t expands to the current time in milliseconds. 11044f0eee88ff00398ff7f715fab053374d808c90dSteve Block double time = OS::TimeCurrentMillis(); 11144f0eee88ff00398ff7f715fab053374d808c90dSteve Block stream.Add("%.0f", FmtElm(time)); 11244f0eee88ff00398ff7f715fab053374d808c90dSteve Block break; 11344f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 11444f0eee88ff00398ff7f715fab053374d808c90dSteve Block case '%': 11544f0eee88ff00398ff7f715fab053374d808c90dSteve Block // %% expands (contracts really) to %. 11644f0eee88ff00398ff7f715fab053374d808c90dSteve Block stream.Put('%'); 11744f0eee88ff00398ff7f715fab053374d808c90dSteve Block break; 11844f0eee88ff00398ff7f715fab053374d808c90dSteve Block default: 11944f0eee88ff00398ff7f715fab053374d808c90dSteve Block // All other %'s expand to themselves. 12044f0eee88ff00398ff7f715fab053374d808c90dSteve Block stream.Put('%'); 12144f0eee88ff00398ff7f715fab053374d808c90dSteve Block stream.Put(*p); 12244f0eee88ff00398ff7f715fab053374d808c90dSteve Block break; 12344f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 12444f0eee88ff00398ff7f715fab053374d808c90dSteve Block } else { 12544f0eee88ff00398ff7f715fab053374d808c90dSteve Block stream.Put(*p); 12644f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 12744f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 128589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch SmartArrayPointer<const char> expanded = stream.ToCString(); 12944f0eee88ff00398ff7f715fab053374d808c90dSteve Block OpenFile(*expanded); 13044f0eee88ff00398ff7f715fab053374d808c90dSteve Block } else { 13144f0eee88ff00398ff7f715fab053374d808c90dSteve Block OpenFile(FLAG_logfile); 13244f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 13344f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 13444f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Log::OpenStdout() { 139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!IsEnabled()); 140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block output_handle_ = stdout; 1413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 1423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid Log::OpenTemporaryFile() { 1453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(!IsEnabled()); 1463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch output_handle_ = i::OS::OpenTemporaryFile(); 147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 150257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Extension added to V8 log file name to get the low-level log name. 151257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochstatic const char kLowLevelLogExt[] = ".ll"; 152257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 153257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// File buffer size of the low-level log. We don't use the default to 154257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// minimize the associated overhead. 155257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochstatic const int kLowLevelLogBufferSize = 2 * MB; 156f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 157f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Log::OpenFile(const char* name) { 159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!IsEnabled()); 160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block output_handle_ = OS::FOpen(name, OS::LogFileOpenMode); 161f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch if (FLAG_ll_prof) { 162257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Open the low-level log file. 163257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch size_t len = strlen(name); 164257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ScopedVector<char> ll_name(static_cast<int>(len + sizeof(kLowLevelLogExt))); 165257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch memcpy(ll_name.start(), name, len); 166257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch memcpy(ll_name.start() + len, kLowLevelLogExt, sizeof(kLowLevelLogExt)); 167257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ll_output_handle_ = OS::FOpen(ll_name.start(), OS::LogFileOpenMode); 168257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch setvbuf(ll_output_handle_, NULL, _IOFBF, kLowLevelLogBufferSize); 169f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1733fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochFILE* Log::Close() { 1743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch FILE* result = NULL; 1753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (output_handle_ != NULL) { 1763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (strcmp(FLAG_logfile, kLogToTemporaryFile) != 0) { 1773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch fclose(output_handle_); 1783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 1793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch result = output_handle_; 1803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch output_handle_ = NULL; 1833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (ll_output_handle_ != NULL) fclose(ll_output_handle_); 1843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ll_output_handle_ = NULL; 185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DeleteArray(message_buffer_); 187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block message_buffer_ = NULL; 188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block delete mutex_; 190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block mutex_ = NULL; 191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block is_stopped_ = false; 1933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return result; 194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 19744f0eee88ff00398ff7f715fab053374d808c90dSteve BlockLogMessageBuilder::LogMessageBuilder(Logger* logger) 19844f0eee88ff00398ff7f715fab053374d808c90dSteve Block : log_(logger->log_), 19944f0eee88ff00398ff7f715fab053374d808c90dSteve Block sl(log_->mutex_), 20044f0eee88ff00398ff7f715fab053374d808c90dSteve Block pos_(0) { 20144f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(log_->message_buffer_ != NULL); 202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid LogMessageBuilder::Append(const char* format, ...) { 20644f0eee88ff00398ff7f715fab053374d808c90dSteve Block Vector<char> buf(log_->message_buffer_ + pos_, 207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Log::kMessageBufferSize - pos_); 208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block va_list args; 209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block va_start(args, format); 210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block AppendVA(format, args); 211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block va_end(args); 212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(pos_ <= Log::kMessageBufferSize); 213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid LogMessageBuilder::AppendVA(const char* format, va_list args) { 21744f0eee88ff00398ff7f715fab053374d808c90dSteve Block Vector<char> buf(log_->message_buffer_ + pos_, 218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Log::kMessageBufferSize - pos_); 219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int result = v8::internal::OS::VSNPrintF(buf, format, args); 220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Result is -1 if output was truncated. 222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (result >= 0) { 223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pos_ += result; 224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pos_ = Log::kMessageBufferSize; 226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(pos_ <= Log::kMessageBufferSize); 228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid LogMessageBuilder::Append(const char c) { 232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (pos_ < Log::kMessageBufferSize) { 23344f0eee88ff00398ff7f715fab053374d808c90dSteve Block log_->message_buffer_[pos_++] = c; 234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(pos_ <= Log::kMessageBufferSize); 236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid LogMessageBuilder::Append(String* str) { 240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block AssertNoAllocation no_heap_allocation; // Ensure string stay valid. 241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int length = str->length(); 242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < length; i++) { 243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Append(static_cast<char>(str->Get(i))); 244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid LogMessageBuilder::AppendAddress(Address addr) { 249b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Append("0x%" V8PRIxPTR, addr); 250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid LogMessageBuilder::AppendDetailed(String* str, bool show_impl_info) { 254257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (str == NULL) return; 255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block AssertNoAllocation no_heap_allocation; // Ensure string stay valid. 256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int len = str->length(); 257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (len > 0x1000) 258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block len = 0x1000; 259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (show_impl_info) { 260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Append(str->IsAsciiRepresentation() ? 'a' : '2'); 261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (StringShape(str).IsExternal()) 262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Append('e'); 263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (StringShape(str).IsSymbol()) 264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Append('#'); 265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Append(":%i:", str->length()); 266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < len; i++) { 268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uc32 c = str->Get(i); 269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (c > 0xff) { 270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Append("\\u%04x", c); 271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (c < 32 || c > 126) { 272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Append("\\x%02x", c); 273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (c == ',') { 274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Append("\\,"); 275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (c == '\\') { 276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Append("\\\\"); 277e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } else if (c == '\"') { 278e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Append("\"\""); 279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Append("%lc", c); 281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid LogMessageBuilder::AppendStringPart(const char* str, int len) { 287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (pos_ + len > Log::kMessageBufferSize) { 288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block len = Log::kMessageBufferSize - pos_; 289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(len >= 0); 290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (len == 0) return; 291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 29244f0eee88ff00398ff7f715fab053374d808c90dSteve Block Vector<char> buf(log_->message_buffer_ + pos_, 293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Log::kMessageBufferSize - pos_); 294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block OS::StrNCpy(buf, str, len); 295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pos_ += len; 296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(pos_ <= Log::kMessageBufferSize); 297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid LogMessageBuilder::WriteToLogFile() { 301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(pos_ <= Log::kMessageBufferSize); 3023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const int written = log_->WriteToFile(log_->message_buffer_, pos_); 30344f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (written != pos_) { 30444f0eee88ff00398ff7f715fab053374d808c90dSteve Block log_->stop(); 30544f0eee88ff00398ff7f715fab053374d808c90dSteve Block log_->logger_->LogFailure(); 306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 30944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} } // namespace v8::internal 311