| 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 |