~evarlast/ubuntu/utopic/mongodb/upstart-workaround-debian-bug-718702

« back to all changes in this revision

Viewing changes to src/third_party/v8/src/log-utils.cc

  • Committer: Package Import Robot
  • Author(s): James Page, James Page, Robie Basak
  • Date: 2013-05-29 17:44:42 UTC
  • mfrom: (44.1.7 sid)
  • Revision ID: package-import@ubuntu.com-20130529174442-z0a4qmoww4y0t458
Tags: 1:2.4.3-1ubuntu1
[ James Page ]
* Merge from Debian unstable, remaining changes:
  - Enable SSL support:
    + d/control: Add libssl-dev to BD's.
    + d/rules: Enabled --ssl option.
    + d/mongodb.conf: Add example SSL configuration options.
  - d/mongodb-server.mongodb.upstart: Add upstart configuration.
  - d/rules: Don't strip binaries during scons build for Ubuntu.
  - d/control: Add armhf to target archs.
  - d/p/SConscript.client.patch: fixup install of client libraries.
  - d/p/0010-install-libs-to-usr-lib-not-usr-lib64-Closes-588557.patch:
    Install libraries to lib not lib64.
* Dropped changes:
  - d/p/arm-support.patch: Included in Debian.
  - d/p/double-alignment.patch: Included in Debian.
  - d/rules,control: Debian also builds with avaliable system libraries
    now.
* Fix FTBFS due to gcc and boost upgrades in saucy:
  - d/p/0008-ignore-unused-local-typedefs.patch: Add -Wno-unused-typedefs
    to unbreak building with g++-4.8.
  - d/p/0009-boost-1.53.patch: Fixup signed/unsigned casting issue.

[ Robie Basak ]
* d/p/0011-Use-a-signed-char-to-store-BSONType-enumerations.patch: Fixup
  build failure on ARM due to missing signed'ness of char cast.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2009 the V8 project authors. All rights reserved.
 
2
// Redistribution and use in source and binary forms, with or without
 
3
// modification, are permitted provided that the following conditions are
 
4
// met:
 
5
//
 
6
//     * Redistributions of source code must retain the above copyright
 
7
//       notice, this list of conditions and the following disclaimer.
 
8
//     * Redistributions in binary form must reproduce the above
 
9
//       copyright notice, this list of conditions and the following
 
10
//       disclaimer in the documentation and/or other materials provided
 
11
//       with the distribution.
 
12
//     * Neither the name of Google Inc. nor the names of its
 
13
//       contributors may be used to endorse or promote products derived
 
14
//       from this software without specific prior written permission.
 
15
//
 
16
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 
17
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 
18
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 
19
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 
20
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 
21
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 
22
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 
23
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 
24
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
25
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 
26
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
27
 
 
28
#include "v8.h"
 
29
 
 
30
#include "log-utils.h"
 
31
#include "string-stream.h"
 
32
 
 
33
namespace v8 {
 
34
namespace internal {
 
35
 
 
36
 
 
37
const char* const Log::kLogToTemporaryFile = "&";
 
38
 
 
39
 
 
40
Log::Log(Logger* logger)
 
41
  : is_stopped_(false),
 
42
    output_handle_(NULL),
 
43
    ll_output_handle_(NULL),
 
44
    mutex_(NULL),
 
45
    message_buffer_(NULL),
 
46
    logger_(logger) {
 
47
}
 
48
 
 
49
 
 
50
static void AddIsolateIdIfNeeded(StringStream* stream) {
 
51
  Isolate* isolate = Isolate::Current();
 
52
  if (isolate->IsDefaultIsolate()) return;
 
53
  stream->Add("isolate-%p-", isolate);
 
54
}
 
55
 
 
56
 
 
57
void Log::Initialize() {
 
58
  mutex_ = OS::CreateMutex();
 
59
  message_buffer_ = NewArray<char>(kMessageBufferSize);
 
60
 
 
61
  // --log-all enables all the log flags.
 
62
  if (FLAG_log_all) {
 
63
    FLAG_log_runtime = true;
 
64
    FLAG_log_api = true;
 
65
    FLAG_log_code = true;
 
66
    FLAG_log_gc = true;
 
67
    FLAG_log_suspect = true;
 
68
    FLAG_log_handles = true;
 
69
    FLAG_log_regexp = true;
 
70
  }
 
71
 
 
72
  // --prof implies --log-code.
 
73
  if (FLAG_prof) FLAG_log_code = true;
 
74
 
 
75
  // --prof_lazy controls --log-code, implies --noprof_auto.
 
76
  if (FLAG_prof_lazy) {
 
77
    FLAG_log_code = false;
 
78
    FLAG_prof_auto = false;
 
79
  }
 
80
 
 
81
  bool open_log_file = FLAG_log || FLAG_log_runtime || FLAG_log_api
 
82
      || FLAG_log_code || FLAG_log_gc || FLAG_log_handles || FLAG_log_suspect
 
83
      || FLAG_log_regexp || FLAG_log_state_changes || FLAG_ll_prof;
 
84
 
 
85
  // If we're logging anything, we need to open the log file.
 
86
  if (open_log_file) {
 
87
    if (strcmp(FLAG_logfile, "-") == 0) {
 
88
      OpenStdout();
 
89
    } else if (strcmp(FLAG_logfile, kLogToTemporaryFile) == 0) {
 
90
      OpenTemporaryFile();
 
91
    } else {
 
92
      if (strchr(FLAG_logfile, '%') != NULL ||
 
93
          !Isolate::Current()->IsDefaultIsolate()) {
 
94
        // If there's a '%' in the log file name we have to expand
 
95
        // placeholders.
 
96
        HeapStringAllocator allocator;
 
97
        StringStream stream(&allocator);
 
98
        AddIsolateIdIfNeeded(&stream);
 
99
        for (const char* p = FLAG_logfile; *p; p++) {
 
100
          if (*p == '%') {
 
101
            p++;
 
102
            switch (*p) {
 
103
              case '\0':
 
104
                // If there's a % at the end of the string we back up
 
105
                // one character so we can escape the loop properly.
 
106
                p--;
 
107
                break;
 
108
              case 't': {
 
109
                // %t expands to the current time in milliseconds.
 
110
                double time = OS::TimeCurrentMillis();
 
111
                stream.Add("%.0f", FmtElm(time));
 
112
                break;
 
113
              }
 
114
              case '%':
 
115
                // %% expands (contracts really) to %.
 
116
                stream.Put('%');
 
117
                break;
 
118
              default:
 
119
                // All other %'s expand to themselves.
 
120
                stream.Put('%');
 
121
                stream.Put(*p);
 
122
                break;
 
123
            }
 
124
          } else {
 
125
            stream.Put(*p);
 
126
          }
 
127
        }
 
128
        SmartArrayPointer<const char> expanded = stream.ToCString();
 
129
        OpenFile(*expanded);
 
130
      } else {
 
131
        OpenFile(FLAG_logfile);
 
132
      }
 
133
    }
 
134
  }
 
135
}
 
136
 
 
137
 
 
138
void Log::OpenStdout() {
 
139
  ASSERT(!IsEnabled());
 
140
  output_handle_ = stdout;
 
141
}
 
142
 
 
143
 
 
144
void Log::OpenTemporaryFile() {
 
145
  ASSERT(!IsEnabled());
 
146
  output_handle_ = i::OS::OpenTemporaryFile();
 
147
}
 
148
 
 
149
 
 
150
// Extension added to V8 log file name to get the low-level log name.
 
151
static const char kLowLevelLogExt[] = ".ll";
 
152
 
 
153
// File buffer size of the low-level log. We don't use the default to
 
154
// minimize the associated overhead.
 
155
static const int kLowLevelLogBufferSize = 2 * MB;
 
156
 
 
157
 
 
158
void Log::OpenFile(const char* name) {
 
159
  ASSERT(!IsEnabled());
 
160
  output_handle_ = OS::FOpen(name, OS::LogFileOpenMode);
 
161
  if (FLAG_ll_prof) {
 
162
    // Open the low-level log file.
 
163
    size_t len = strlen(name);
 
164
    ScopedVector<char> ll_name(static_cast<int>(len + sizeof(kLowLevelLogExt)));
 
165
    memcpy(ll_name.start(), name, len);
 
166
    memcpy(ll_name.start() + len, kLowLevelLogExt, sizeof(kLowLevelLogExt));
 
167
    ll_output_handle_ = OS::FOpen(ll_name.start(), OS::LogFileOpenMode);
 
168
    setvbuf(ll_output_handle_, NULL, _IOFBF, kLowLevelLogBufferSize);
 
169
  }
 
170
}
 
171
 
 
172
 
 
173
FILE* Log::Close() {
 
174
  FILE* result = NULL;
 
175
  if (output_handle_ != NULL) {
 
176
    if (strcmp(FLAG_logfile, kLogToTemporaryFile) != 0) {
 
177
      fclose(output_handle_);
 
178
    } else {
 
179
      result = output_handle_;
 
180
    }
 
181
  }
 
182
  output_handle_ = NULL;
 
183
  if (ll_output_handle_ != NULL) fclose(ll_output_handle_);
 
184
  ll_output_handle_ = NULL;
 
185
 
 
186
  DeleteArray(message_buffer_);
 
187
  message_buffer_ = NULL;
 
188
 
 
189
  delete mutex_;
 
190
  mutex_ = NULL;
 
191
 
 
192
  is_stopped_ = false;
 
193
  return result;
 
194
}
 
195
 
 
196
 
 
197
LogMessageBuilder::LogMessageBuilder(Logger* logger)
 
198
  : log_(logger->log_),
 
199
    sl(log_->mutex_),
 
200
    pos_(0) {
 
201
  ASSERT(log_->message_buffer_ != NULL);
 
202
}
 
203
 
 
204
 
 
205
void LogMessageBuilder::Append(const char* format, ...) {
 
206
  Vector<char> buf(log_->message_buffer_ + pos_,
 
207
                   Log::kMessageBufferSize - pos_);
 
208
  va_list args;
 
209
  va_start(args, format);
 
210
  AppendVA(format, args);
 
211
  va_end(args);
 
212
  ASSERT(pos_ <= Log::kMessageBufferSize);
 
213
}
 
214
 
 
215
 
 
216
void LogMessageBuilder::AppendVA(const char* format, va_list args) {
 
217
  Vector<char> buf(log_->message_buffer_ + pos_,
 
218
                   Log::kMessageBufferSize - pos_);
 
219
  int result = v8::internal::OS::VSNPrintF(buf, format, args);
 
220
 
 
221
  // Result is -1 if output was truncated.
 
222
  if (result >= 0) {
 
223
    pos_ += result;
 
224
  } else {
 
225
    pos_ = Log::kMessageBufferSize;
 
226
  }
 
227
  ASSERT(pos_ <= Log::kMessageBufferSize);
 
228
}
 
229
 
 
230
 
 
231
void LogMessageBuilder::Append(const char c) {
 
232
  if (pos_ < Log::kMessageBufferSize) {
 
233
    log_->message_buffer_[pos_++] = c;
 
234
  }
 
235
  ASSERT(pos_ <= Log::kMessageBufferSize);
 
236
}
 
237
 
 
238
 
 
239
void LogMessageBuilder::Append(String* str) {
 
240
  AssertNoAllocation no_heap_allocation;  // Ensure string stay valid.
 
241
  int length = str->length();
 
242
  for (int i = 0; i < length; i++) {
 
243
    Append(static_cast<char>(str->Get(i)));
 
244
  }
 
245
}
 
246
 
 
247
 
 
248
void LogMessageBuilder::AppendAddress(Address addr) {
 
249
  Append("0x%" V8PRIxPTR, addr);
 
250
}
 
251
 
 
252
 
 
253
void LogMessageBuilder::AppendDetailed(String* str, bool show_impl_info) {
 
254
  if (str == NULL) return;
 
255
  AssertNoAllocation no_heap_allocation;  // Ensure string stay valid.
 
256
  int len = str->length();
 
257
  if (len > 0x1000)
 
258
    len = 0x1000;
 
259
  if (show_impl_info) {
 
260
    Append(str->IsAsciiRepresentation() ? 'a' : '2');
 
261
    if (StringShape(str).IsExternal())
 
262
      Append('e');
 
263
    if (StringShape(str).IsSymbol())
 
264
      Append('#');
 
265
    Append(":%i:", str->length());
 
266
  }
 
267
  for (int i = 0; i < len; i++) {
 
268
    uc32 c = str->Get(i);
 
269
    if (c > 0xff) {
 
270
      Append("\\u%04x", c);
 
271
    } else if (c < 32 || c > 126) {
 
272
      Append("\\x%02x", c);
 
273
    } else if (c == ',') {
 
274
      Append("\\,");
 
275
    } else if (c == '\\') {
 
276
      Append("\\\\");
 
277
    } else if (c == '\"') {
 
278
      Append("\"\"");
 
279
    } else {
 
280
      Append("%lc", c);
 
281
    }
 
282
  }
 
283
}
 
284
 
 
285
 
 
286
void LogMessageBuilder::AppendStringPart(const char* str, int len) {
 
287
  if (pos_ + len > Log::kMessageBufferSize) {
 
288
    len = Log::kMessageBufferSize - pos_;
 
289
    ASSERT(len >= 0);
 
290
    if (len == 0) return;
 
291
  }
 
292
  Vector<char> buf(log_->message_buffer_ + pos_,
 
293
                   Log::kMessageBufferSize - pos_);
 
294
  OS::StrNCpy(buf, str, len);
 
295
  pos_ += len;
 
296
  ASSERT(pos_ <= Log::kMessageBufferSize);
 
297
}
 
298
 
 
299
 
 
300
void LogMessageBuilder::WriteToLogFile() {
 
301
  ASSERT(pos_ <= Log::kMessageBufferSize);
 
302
  const int written = log_->WriteToFile(log_->message_buffer_, pos_);
 
303
  if (written != pos_) {
 
304
    log_->stop();
 
305
    log_->logger_->LogFailure();
 
306
  }
 
307
}
 
308
 
 
309
 
 
310
} }  // namespace v8::internal