OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 503 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
514 }; | 514 }; |
515 | 515 |
516 | 516 |
517 Logger::Logger() | 517 Logger::Logger() |
518 : ticker_(NULL), | 518 : ticker_(NULL), |
519 profiler_(NULL), | 519 profiler_(NULL), |
520 sliding_state_window_(NULL), | 520 sliding_state_window_(NULL), |
521 log_events_(NULL), | 521 log_events_(NULL), |
522 logging_nesting_(0), | 522 logging_nesting_(0), |
523 cpu_profiler_nesting_(0), | 523 cpu_profiler_nesting_(0), |
524 heap_profiler_nesting_(0), | |
525 log_(new Log(this)), | 524 log_(new Log(this)), |
526 name_buffer_(new NameBuffer), | 525 name_buffer_(new NameBuffer), |
527 address_to_name_map_(NULL), | 526 address_to_name_map_(NULL), |
528 is_initialized_(false), | 527 is_initialized_(false), |
529 last_address_(NULL), | 528 last_address_(NULL), |
530 prev_sp_(NULL), | 529 prev_sp_(NULL), |
531 prev_function_(NULL), | 530 prev_function_(NULL), |
532 prev_to_(NULL), | 531 prev_to_(NULL), |
533 prev_code_(NULL) { | 532 prev_code_(NULL) { |
534 } | 533 } |
(...skipping 744 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1279 LogMessageBuilder msg(this); | 1278 LogMessageBuilder msg(this); |
1280 // Using non-relative system time in order to be able to synchronize with | 1279 // Using non-relative system time in order to be able to synchronize with |
1281 // external memory profiling events (e.g. DOM memory size). | 1280 // external memory profiling events (e.g. DOM memory size). |
1282 msg.Append("heap-sample-begin,\"%s\",\"%s\",%.0f\n", | 1281 msg.Append("heap-sample-begin,\"%s\",\"%s\",%.0f\n", |
1283 space, kind, OS::TimeCurrentMillis()); | 1282 space, kind, OS::TimeCurrentMillis()); |
1284 msg.WriteToLogFile(); | 1283 msg.WriteToLogFile(); |
1285 #endif | 1284 #endif |
1286 } | 1285 } |
1287 | 1286 |
1288 | 1287 |
1289 void Logger::HeapSampleStats(const char* space, const char* kind, | |
1290 intptr_t capacity, intptr_t used) { | |
1291 #ifdef ENABLE_LOGGING_AND_PROFILING | |
1292 if (!log_->IsEnabled() || !FLAG_log_gc) return; | |
1293 LogMessageBuilder msg(this); | |
1294 msg.Append("heap-sample-stats,\"%s\",\"%s\"," | |
1295 "%" V8_PTR_PREFIX "d,%" V8_PTR_PREFIX "d\n", | |
1296 space, kind, capacity, used); | |
1297 msg.WriteToLogFile(); | |
1298 #endif | |
1299 } | |
1300 | |
1301 | |
1302 void Logger::HeapSampleEndEvent(const char* space, const char* kind) { | 1288 void Logger::HeapSampleEndEvent(const char* space, const char* kind) { |
1303 #ifdef ENABLE_LOGGING_AND_PROFILING | 1289 #ifdef ENABLE_LOGGING_AND_PROFILING |
1304 if (!log_->IsEnabled() || !FLAG_log_gc) return; | 1290 if (!log_->IsEnabled() || !FLAG_log_gc) return; |
1305 LogMessageBuilder msg(this); | 1291 LogMessageBuilder msg(this); |
1306 msg.Append("heap-sample-end,\"%s\",\"%s\"\n", space, kind); | 1292 msg.Append("heap-sample-end,\"%s\",\"%s\"\n", space, kind); |
1307 msg.WriteToLogFile(); | 1293 msg.WriteToLogFile(); |
1308 #endif | 1294 #endif |
1309 } | 1295 } |
1310 | 1296 |
1311 | 1297 |
1312 void Logger::HeapSampleItemEvent(const char* type, int number, int bytes) { | 1298 void Logger::HeapSampleItemEvent(const char* type, int number, int bytes) { |
1313 #ifdef ENABLE_LOGGING_AND_PROFILING | 1299 #ifdef ENABLE_LOGGING_AND_PROFILING |
1314 if (!log_->IsEnabled() || !FLAG_log_gc) return; | 1300 if (!log_->IsEnabled() || !FLAG_log_gc) return; |
1315 LogMessageBuilder msg(this); | 1301 LogMessageBuilder msg(this); |
1316 msg.Append("heap-sample-item,%s,%d,%d\n", type, number, bytes); | 1302 msg.Append("heap-sample-item,%s,%d,%d\n", type, number, bytes); |
1317 msg.WriteToLogFile(); | 1303 msg.WriteToLogFile(); |
1318 #endif | 1304 #endif |
1319 } | 1305 } |
1320 | 1306 |
1321 | 1307 |
1322 void Logger::HeapSampleJSConstructorEvent(const char* constructor, | |
1323 int number, int bytes) { | |
1324 #ifdef ENABLE_LOGGING_AND_PROFILING | |
1325 if (!log_->IsEnabled() || !FLAG_log_gc) return; | |
1326 LogMessageBuilder msg(this); | |
1327 msg.Append("heap-js-cons-item,%s,%d,%d\n", constructor, number, bytes); | |
1328 msg.WriteToLogFile(); | |
1329 #endif | |
1330 } | |
1331 | |
1332 // Event starts with comma, so we don't have it in the format string. | |
1333 static const char kEventText[] = "heap-js-ret-item,%s"; | |
1334 // We take placeholder strings into account, but it's OK to be conservative. | |
1335 static const int kEventTextLen = sizeof(kEventText)/sizeof(kEventText[0]); | |
1336 | |
1337 void Logger::HeapSampleJSRetainersEvent( | |
1338 const char* constructor, const char* event) { | |
1339 #ifdef ENABLE_LOGGING_AND_PROFILING | |
1340 if (!log_->IsEnabled() || !FLAG_log_gc) return; | |
1341 const int cons_len = StrLength(constructor); | |
1342 const int event_len = StrLength(event); | |
1343 int pos = 0; | |
1344 // Retainer lists can be long. We may need to split them into multiple events. | |
1345 do { | |
1346 LogMessageBuilder msg(this); | |
1347 msg.Append(kEventText, constructor); | |
1348 int to_write = event_len - pos; | |
1349 if (to_write > Log::kMessageBufferSize - (cons_len + kEventTextLen)) { | |
1350 int cut_pos = pos + Log::kMessageBufferSize - (cons_len + kEventTextLen); | |
1351 ASSERT(cut_pos < event_len); | |
1352 while (cut_pos > pos && event[cut_pos] != ',') --cut_pos; | |
1353 if (event[cut_pos] != ',') { | |
1354 // Crash in debug mode, skip in release mode. | |
1355 ASSERT(false); | |
1356 return; | |
1357 } | |
1358 // Append a piece of event that fits, without trailing comma. | |
1359 msg.AppendStringPart(event + pos, cut_pos - pos); | |
1360 // Start next piece with comma. | |
1361 pos = cut_pos; | |
1362 } else { | |
1363 msg.Append("%s", event + pos); | |
1364 pos += event_len; | |
1365 } | |
1366 msg.Append('\n'); | |
1367 msg.WriteToLogFile(); | |
1368 } while (pos < event_len); | |
1369 #endif | |
1370 } | |
1371 | |
1372 | |
1373 void Logger::HeapSampleJSProducerEvent(const char* constructor, | |
1374 Address* stack) { | |
1375 #ifdef ENABLE_LOGGING_AND_PROFILING | |
1376 if (!log_->IsEnabled() || !FLAG_log_gc) return; | |
1377 LogMessageBuilder msg(this); | |
1378 msg.Append("heap-js-prod-item,%s", constructor); | |
1379 while (*stack != NULL) { | |
1380 msg.Append(",0x%" V8PRIxPTR, *stack++); | |
1381 } | |
1382 msg.Append("\n"); | |
1383 msg.WriteToLogFile(); | |
1384 #endif | |
1385 } | |
1386 | |
1387 | |
1388 void Logger::DebugTag(const char* call_site_tag) { | 1308 void Logger::DebugTag(const char* call_site_tag) { |
1389 #ifdef ENABLE_LOGGING_AND_PROFILING | 1309 #ifdef ENABLE_LOGGING_AND_PROFILING |
1390 if (!log_->IsEnabled() || !FLAG_log) return; | 1310 if (!log_->IsEnabled() || !FLAG_log) return; |
1391 LogMessageBuilder msg(this); | 1311 LogMessageBuilder msg(this); |
1392 msg.Append("debug-tag,%s\n", call_site_tag); | 1312 msg.Append("debug-tag,%s\n", call_site_tag); |
1393 msg.WriteToLogFile(); | 1313 msg.WriteToLogFile(); |
1394 #endif | 1314 #endif |
1395 } | 1315 } |
1396 | 1316 |
1397 | 1317 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1440 msg.Append('\n'); | 1360 msg.Append('\n'); |
1441 msg.WriteToLogFile(); | 1361 msg.WriteToLogFile(); |
1442 } | 1362 } |
1443 | 1363 |
1444 | 1364 |
1445 int Logger::GetActiveProfilerModules() { | 1365 int Logger::GetActiveProfilerModules() { |
1446 int result = PROFILER_MODULE_NONE; | 1366 int result = PROFILER_MODULE_NONE; |
1447 if (profiler_ != NULL && !profiler_->paused()) { | 1367 if (profiler_ != NULL && !profiler_->paused()) { |
1448 result |= PROFILER_MODULE_CPU; | 1368 result |= PROFILER_MODULE_CPU; |
1449 } | 1369 } |
1450 if (FLAG_log_gc) { | |
1451 result |= PROFILER_MODULE_HEAP_STATS | PROFILER_MODULE_JS_CONSTRUCTORS; | |
1452 } | |
1453 return result; | 1370 return result; |
1454 } | 1371 } |
1455 | 1372 |
1456 | 1373 |
1457 void Logger::PauseProfiler(int flags, int tag) { | 1374 void Logger::PauseProfiler(int flags, int tag) { |
1458 if (!log_->IsEnabled()) return; | 1375 if (!log_->IsEnabled()) return; |
1459 if (profiler_ != NULL && (flags & PROFILER_MODULE_CPU)) { | 1376 if (profiler_ != NULL && (flags & PROFILER_MODULE_CPU)) { |
1460 // It is OK to have negative nesting. | 1377 // It is OK to have negative nesting. |
1461 if (--cpu_profiler_nesting_ == 0) { | 1378 if (--cpu_profiler_nesting_ == 0) { |
1462 profiler_->pause(); | 1379 profiler_->pause(); |
1463 if (FLAG_prof_lazy) { | 1380 if (FLAG_prof_lazy) { |
1464 if (!FLAG_sliding_state_window && !RuntimeProfiler::IsEnabled()) { | 1381 if (!FLAG_sliding_state_window && !RuntimeProfiler::IsEnabled()) { |
1465 ticker_->Stop(); | 1382 ticker_->Stop(); |
1466 } | 1383 } |
1467 FLAG_log_code = false; | 1384 FLAG_log_code = false; |
1468 // Must be the same message as Log::kDynamicBufferSeal. | 1385 // Must be the same message as Log::kDynamicBufferSeal. |
1469 LOG(ISOLATE, UncheckedStringEvent("profiler", "pause")); | 1386 LOG(ISOLATE, UncheckedStringEvent("profiler", "pause")); |
1470 } | 1387 } |
1471 --logging_nesting_; | 1388 --logging_nesting_; |
1472 } | 1389 } |
1473 } | 1390 } |
1474 if (flags & | |
1475 (PROFILER_MODULE_HEAP_STATS | PROFILER_MODULE_JS_CONSTRUCTORS)) { | |
1476 if (--heap_profiler_nesting_ == 0) { | |
1477 FLAG_log_gc = false; | |
1478 --logging_nesting_; | |
1479 } | |
1480 } | |
1481 if (tag != 0) { | 1391 if (tag != 0) { |
1482 UncheckedIntEvent("close-tag", tag); | 1392 UncheckedIntEvent("close-tag", tag); |
1483 } | 1393 } |
1484 } | 1394 } |
1485 | 1395 |
1486 | 1396 |
1487 void Logger::ResumeProfiler(int flags, int tag) { | 1397 void Logger::ResumeProfiler(int flags, int tag) { |
1488 if (!log_->IsEnabled()) return; | 1398 if (!log_->IsEnabled()) return; |
1489 if (tag != 0) { | 1399 if (tag != 0) { |
1490 UncheckedIntEvent("open-tag", tag); | 1400 UncheckedIntEvent("open-tag", tag); |
1491 } | 1401 } |
1492 if (profiler_ != NULL && (flags & PROFILER_MODULE_CPU)) { | 1402 if (profiler_ != NULL && (flags & PROFILER_MODULE_CPU)) { |
1493 if (cpu_profiler_nesting_++ == 0) { | 1403 if (cpu_profiler_nesting_++ == 0) { |
1494 ++logging_nesting_; | 1404 ++logging_nesting_; |
1495 if (FLAG_prof_lazy) { | 1405 if (FLAG_prof_lazy) { |
1496 profiler_->Engage(); | 1406 profiler_->Engage(); |
1497 LOG(ISOLATE, UncheckedStringEvent("profiler", "resume")); | 1407 LOG(ISOLATE, UncheckedStringEvent("profiler", "resume")); |
1498 FLAG_log_code = true; | 1408 FLAG_log_code = true; |
1499 LogCompiledFunctions(); | 1409 LogCompiledFunctions(); |
1500 LogAccessorCallbacks(); | 1410 LogAccessorCallbacks(); |
1501 if (!FLAG_sliding_state_window && !ticker_->IsActive()) { | 1411 if (!FLAG_sliding_state_window && !ticker_->IsActive()) { |
1502 ticker_->Start(); | 1412 ticker_->Start(); |
1503 } | 1413 } |
1504 } | 1414 } |
1505 profiler_->resume(); | 1415 profiler_->resume(); |
1506 } | 1416 } |
1507 } | 1417 } |
1508 if (flags & | |
1509 (PROFILER_MODULE_HEAP_STATS | PROFILER_MODULE_JS_CONSTRUCTORS)) { | |
1510 if (heap_profiler_nesting_++ == 0) { | |
1511 ++logging_nesting_; | |
1512 FLAG_log_gc = true; | |
1513 } | |
1514 } | |
1515 } | 1418 } |
1516 | 1419 |
1517 | 1420 |
1518 // This function can be called when Log's mutex is acquired, | 1421 // This function can be called when Log's mutex is acquired, |
1519 // either from main or Profiler's thread. | 1422 // either from main or Profiler's thread. |
1520 void Logger::LogFailure() { | 1423 void Logger::LogFailure() { |
1521 PauseProfiler(PROFILER_MODULE_CPU, 0); | 1424 PauseProfiler(PROFILER_MODULE_CPU, 0); |
1522 } | 1425 } |
1523 | 1426 |
1524 | 1427 |
(...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1993 void SamplerRegistry::RemoveActiveSampler(Sampler* sampler) { | 1896 void SamplerRegistry::RemoveActiveSampler(Sampler* sampler) { |
1994 ASSERT(sampler->IsActive()); | 1897 ASSERT(sampler->IsActive()); |
1995 ScopedLock lock(mutex_); | 1898 ScopedLock lock(mutex_); |
1996 ASSERT(active_samplers_ != NULL); | 1899 ASSERT(active_samplers_ != NULL); |
1997 bool removed = active_samplers_->RemoveElement(sampler); | 1900 bool removed = active_samplers_->RemoveElement(sampler); |
1998 ASSERT(removed); | 1901 ASSERT(removed); |
1999 USE(removed); | 1902 USE(removed); |
2000 } | 1903 } |
2001 | 1904 |
2002 } } // namespace v8::internal | 1905 } } // namespace v8::internal |
OLD | NEW |