Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/log.cc

Issue 367033002: Reland "Linux perf tool support update + refactoring." (r22146, attempt #5) (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: git cl format Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/isolate.cc ('k') | src/perf-jit.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <stdarg.h> 5 #include <stdarg.h>
6 6
7 #include "src/v8.h" 7 #include "src/v8.h"
8 8
9 #include "src/base/platform/platform.h" 9 #include "src/base/platform/platform.h"
10 #include "src/bootstrapper.h" 10 #include "src/bootstrapper.h"
11 #include "src/code-stubs.h" 11 #include "src/code-stubs.h"
12 #include "src/cpu-profiler.h" 12 #include "src/cpu-profiler.h"
13 #include "src/deoptimizer.h" 13 #include "src/deoptimizer.h"
14 #include "src/global-handles.h" 14 #include "src/global-handles.h"
15 #include "src/log.h" 15 #include "src/log.h"
16 #include "src/log-utils.h" 16 #include "src/log-utils.h"
17 #include "src/macro-assembler.h" 17 #include "src/macro-assembler.h"
18 #include "src/perf-jit.h"
18 #include "src/runtime-profiler.h" 19 #include "src/runtime-profiler.h"
19 #include "src/serialize.h" 20 #include "src/serialize.h"
20 #include "src/string-stream.h" 21 #include "src/string-stream.h"
21 #include "src/vm-state-inl.h" 22 #include "src/vm-state-inl.h"
22 23
23 namespace v8 { 24 namespace v8 {
24 namespace internal { 25 namespace internal {
25 26
26 27
27 #define DECLARE_EVENT(ignore1, name) name, 28 #define DECLARE_EVENT(ignore1, name) name,
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 const char* name, 283 const char* name,
283 int length) { 284 int length) {
284 ASSERT(code->instruction_start() == code->address() + Code::kHeaderSize); 285 ASSERT(code->instruction_start() == code->address() + Code::kHeaderSize);
285 286
286 base::OS::FPrint(perf_output_handle_, "%llx %x %.*s\n", 287 base::OS::FPrint(perf_output_handle_, "%llx %x %.*s\n",
287 reinterpret_cast<uint64_t>(code->instruction_start()), 288 reinterpret_cast<uint64_t>(code->instruction_start()),
288 code->instruction_size(), length, name); 289 code->instruction_size(), length, name);
289 } 290 }
290 291
291 292
292 // Linux perf tool logging support
293 class PerfJitLogger : public CodeEventLogger {
294 public:
295 PerfJitLogger();
296 virtual ~PerfJitLogger();
297
298 virtual void CodeMoveEvent(Address from, Address to) { }
299 virtual void CodeDisableOptEvent(Code* code, SharedFunctionInfo* shared) { }
300 virtual void CodeDeleteEvent(Address from) { }
301
302 private:
303 virtual void LogRecordedBuffer(Code* code,
304 SharedFunctionInfo* shared,
305 const char* name,
306 int length);
307
308 // Extension added to V8 log file name to get the low-level log name.
309 static const char kFilenameFormatString[];
310 static const int kFilenameBufferPadding;
311
312 // File buffer size of the low-level log. We don't use the default to
313 // minimize the associated overhead.
314 static const int kLogBufferSize = 2 * MB;
315
316 void LogWriteBytes(const char* bytes, int size);
317 void LogWriteHeader();
318
319 static const uint32_t kJitHeaderMagic = 0x4F74496A;
320 static const uint32_t kJitHeaderVersion = 0x2;
321 static const uint32_t kElfMachIA32 = 3;
322 static const uint32_t kElfMachX64 = 62;
323 static const uint32_t kElfMachARM = 40;
324 static const uint32_t kElfMachMIPS = 10;
325 static const uint32_t kElfMachX87 = 3;
326
327 struct jitheader {
328 uint32_t magic;
329 uint32_t version;
330 uint32_t total_size;
331 uint32_t elf_mach;
332 uint32_t pad1;
333 uint32_t pid;
334 uint64_t timestamp;
335 };
336
337 enum jit_record_type {
338 JIT_CODE_LOAD = 0
339 // JIT_CODE_UNLOAD = 1,
340 // JIT_CODE_CLOSE = 2,
341 // JIT_CODE_DEBUG_INFO = 3,
342 // JIT_CODE_PAGE_MAP = 4,
343 // JIT_CODE_MAX = 5
344 };
345
346 struct jr_code_load {
347 uint32_t id;
348 uint32_t total_size;
349 uint64_t timestamp;
350 uint64_t vma;
351 uint64_t code_addr;
352 uint32_t code_size;
353 uint32_t align;
354 };
355
356 uint32_t GetElfMach() {
357 #if V8_TARGET_ARCH_IA32
358 return kElfMachIA32;
359 #elif V8_TARGET_ARCH_X64
360 return kElfMachX64;
361 #elif V8_TARGET_ARCH_ARM
362 return kElfMachARM;
363 #elif V8_TARGET_ARCH_MIPS
364 return kElfMachMIPS;
365 #elif V8_TARGET_ARCH_X87
366 return kElfMachX87;
367 #else
368 UNIMPLEMENTED();
369 return 0;
370 #endif
371 }
372
373 FILE* perf_output_handle_;
374 };
375
376 const char PerfJitLogger::kFilenameFormatString[] = "/tmp/jit-%d.dump";
377
378 // Extra padding for the PID in the filename
379 const int PerfJitLogger::kFilenameBufferPadding = 16;
380
381 PerfJitLogger::PerfJitLogger()
382 : perf_output_handle_(NULL) {
383 // Open the perf JIT dump file.
384 int bufferSize = sizeof(kFilenameFormatString) + kFilenameBufferPadding;
385 ScopedVector<char> perf_dump_name(bufferSize);
386 int size = SNPrintF(
387 perf_dump_name,
388 kFilenameFormatString,
389 base::OS::GetCurrentProcessId());
390 CHECK_NE(size, -1);
391 perf_output_handle_ =
392 base::OS::FOpen(perf_dump_name.start(), base::OS::LogFileOpenMode);
393 CHECK_NE(perf_output_handle_, NULL);
394 setvbuf(perf_output_handle_, NULL, _IOFBF, kLogBufferSize);
395
396 LogWriteHeader();
397 }
398
399
400 PerfJitLogger::~PerfJitLogger() {
401 fclose(perf_output_handle_);
402 perf_output_handle_ = NULL;
403 }
404
405
406 void PerfJitLogger::LogRecordedBuffer(Code* code,
407 SharedFunctionInfo*,
408 const char* name,
409 int length) {
410 ASSERT(code->instruction_start() == code->address() + Code::kHeaderSize);
411 ASSERT(perf_output_handle_ != NULL);
412
413 const char* code_name = name;
414 uint8_t* code_pointer = reinterpret_cast<uint8_t*>(code->instruction_start());
415 uint32_t code_size = code->instruction_size();
416
417 static const char string_terminator[] = "\0";
418
419 jr_code_load code_load;
420 code_load.id = JIT_CODE_LOAD;
421 code_load.total_size = sizeof(code_load) + length + 1 + code_size;
422 code_load.timestamp =
423 static_cast<uint64_t>(base::OS::TimeCurrentMillis() * 1000.0);
424 code_load.vma = 0x0; // Our addresses are absolute.
425 code_load.code_addr = reinterpret_cast<uint64_t>(code->instruction_start());
426 code_load.code_size = code_size;
427 code_load.align = 0;
428
429 LogWriteBytes(reinterpret_cast<const char*>(&code_load), sizeof(code_load));
430 LogWriteBytes(code_name, length);
431 LogWriteBytes(string_terminator, 1);
432 LogWriteBytes(reinterpret_cast<const char*>(code_pointer), code_size);
433 }
434
435
436 void PerfJitLogger::LogWriteBytes(const char* bytes, int size) {
437 size_t rv = fwrite(bytes, 1, size, perf_output_handle_);
438 ASSERT(static_cast<size_t>(size) == rv);
439 USE(rv);
440 }
441
442
443 void PerfJitLogger::LogWriteHeader() {
444 ASSERT(perf_output_handle_ != NULL);
445 jitheader header;
446 header.magic = kJitHeaderMagic;
447 header.version = kJitHeaderVersion;
448 header.total_size = sizeof(jitheader);
449 header.pad1 = 0xdeadbeef;
450 header.elf_mach = GetElfMach();
451 header.pid = base::OS::GetCurrentProcessId();
452 header.timestamp =
453 static_cast<uint64_t>(base::OS::TimeCurrentMillis() * 1000.0);
454 LogWriteBytes(reinterpret_cast<const char*>(&header), sizeof(header));
455 }
456
457
458 // Low-level logging support. 293 // Low-level logging support.
459 #define LL_LOG(Call) if (ll_logger_) ll_logger_->Call; 294 #define LL_LOG(Call) if (ll_logger_) ll_logger_->Call;
460 295
461 class LowLevelLogger : public CodeEventLogger { 296 class LowLevelLogger : public CodeEventLogger {
462 public: 297 public:
463 explicit LowLevelLogger(const char* file_name); 298 explicit LowLevelLogger(const char* file_name);
464 virtual ~LowLevelLogger(); 299 virtual ~LowLevelLogger();
465 300
466 virtual void CodeMoveEvent(Address from, Address to); 301 virtual void CodeMoveEvent(Address from, Address to);
467 virtual void CodeDisableOptEvent(Code* code, SharedFunctionInfo* shared) { } 302 virtual void CodeDisableOptEvent(Code* code, SharedFunctionInfo* shared) { }
(...skipping 1653 matching lines...) Expand 10 before | Expand all | Expand 10 after
2121 if (jit_logger_) { 1956 if (jit_logger_) {
2122 removeCodeEventListener(jit_logger_); 1957 removeCodeEventListener(jit_logger_);
2123 delete jit_logger_; 1958 delete jit_logger_;
2124 jit_logger_ = NULL; 1959 jit_logger_ = NULL;
2125 } 1960 }
2126 1961
2127 return log_->Close(); 1962 return log_->Close();
2128 } 1963 }
2129 1964
2130 } } // namespace v8::internal 1965 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/isolate.cc ('k') | src/perf-jit.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698