OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 620 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
631 void Logger::DeleteEvent(const char* name, void* object) { | 631 void Logger::DeleteEvent(const char* name, void* object) { |
632 #ifdef ENABLE_LOGGING_AND_PROFILING | 632 #ifdef ENABLE_LOGGING_AND_PROFILING |
633 if (!Log::IsEnabled() || !FLAG_log) return; | 633 if (!Log::IsEnabled() || !FLAG_log) return; |
634 LogMessageBuilder msg; | 634 LogMessageBuilder msg; |
635 msg.Append("delete,%s,0x%" V8PRIxPTR "\n", name, object); | 635 msg.Append("delete,%s,0x%" V8PRIxPTR "\n", name, object); |
636 msg.WriteToLogFile(); | 636 msg.WriteToLogFile(); |
637 #endif | 637 #endif |
638 } | 638 } |
639 | 639 |
640 | 640 |
641 void Logger::CallbackEvent(const char* class_name, const char* method_name, | |
642 Address entry_point) { | |
643 #ifdef ENABLE_LOGGING_AND_PROFILING | |
644 if (!Log::IsEnabled() || !FLAG_log_code) return; | |
645 LogMessageBuilder msg; | |
646 msg.Append("%s,%s,", | |
647 log_events_[CODE_CREATION_EVENT], log_events_[CALLBACK_TAG]); | |
648 msg.AppendAddress(entry_point); | |
649 msg.Append(",0,\""); | |
650 if (class_name != NULL) { | |
651 msg.Append("%s.", class_name); | |
652 } | |
653 msg.Append("%s\"\n", method_name); | |
654 msg.WriteToLogFile(); | |
655 #endif | |
656 } | |
657 | |
658 | |
659 #ifdef ENABLE_LOGGING_AND_PROFILING | 641 #ifdef ENABLE_LOGGING_AND_PROFILING |
660 | 642 |
661 // A class that contains all common code dealing with record compression. | 643 // A class that contains all common code dealing with record compression. |
662 class CompressionHelper { | 644 class CompressionHelper { |
663 public: | 645 public: |
664 explicit CompressionHelper(int window_size) | 646 explicit CompressionHelper(int window_size) |
665 : compressor_(window_size), repeat_count_(0) { } | 647 : compressor_(window_size), repeat_count_(0) { } |
666 | 648 |
667 // Handles storing message in compressor, retrieving the previous one and | 649 // Handles storing message in compressor, retrieving the previous one and |
668 // prefixing it with repeat count, if needed. | 650 // prefixing it with repeat count, if needed. |
(...skipping 16 matching lines...) Expand all Loading... |
685 | 667 |
686 private: | 668 private: |
687 LogRecordCompressor compressor_; | 669 LogRecordCompressor compressor_; |
688 int repeat_count_; | 670 int repeat_count_; |
689 EmbeddedVector<char, 20> prefix_; | 671 EmbeddedVector<char, 20> prefix_; |
690 }; | 672 }; |
691 | 673 |
692 #endif // ENABLE_LOGGING_AND_PROFILING | 674 #endif // ENABLE_LOGGING_AND_PROFILING |
693 | 675 |
694 | 676 |
| 677 void Logger::CallbackEvent(String* name, Address entry_point) { |
| 678 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 679 if (!Log::IsEnabled() || !FLAG_log_code) return; |
| 680 LogMessageBuilder msg; |
| 681 msg.Append("%s,%s,", |
| 682 log_events_[CODE_CREATION_EVENT], log_events_[CALLBACK_TAG]); |
| 683 msg.AppendAddress(entry_point); |
| 684 SmartPointer<char> str = |
| 685 name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); |
| 686 msg.Append(",0,\"%s\"", *str); |
| 687 if (FLAG_compress_log) { |
| 688 ASSERT(compression_helper_ != NULL); |
| 689 if (!compression_helper_->HandleMessage(&msg)) return; |
| 690 } |
| 691 msg.Append('\n'); |
| 692 msg.WriteToLogFile(); |
| 693 #endif |
| 694 } |
| 695 |
| 696 |
695 void Logger::CodeCreateEvent(LogEventsAndTags tag, | 697 void Logger::CodeCreateEvent(LogEventsAndTags tag, |
696 Code* code, | 698 Code* code, |
697 const char* comment) { | 699 const char* comment) { |
698 #ifdef ENABLE_LOGGING_AND_PROFILING | 700 #ifdef ENABLE_LOGGING_AND_PROFILING |
699 if (!Log::IsEnabled() || !FLAG_log_code) return; | 701 if (!Log::IsEnabled() || !FLAG_log_code) return; |
700 LogMessageBuilder msg; | 702 LogMessageBuilder msg; |
701 msg.Append("%s,%s,", log_events_[CODE_CREATION_EVENT], log_events_[tag]); | 703 msg.Append("%s,%s,", log_events_[CODE_CREATION_EVENT], log_events_[tag]); |
702 msg.AppendAddress(code->address()); | 704 msg.AppendAddress(code->address()); |
703 msg.Append(",%d,\"", code->ExecutableSize()); | 705 msg.Append(",%d,\"", code->ExecutableSize()); |
704 for (const char* p = comment; *p != '\0'; p++) { | 706 for (const char* p = comment; *p != '\0'; p++) { |
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1083 const int modules_to_enable = ~GetActiveProfilerModules() & flags; | 1085 const int modules_to_enable = ~GetActiveProfilerModules() & flags; |
1084 if (modules_to_enable != PROFILER_MODULE_NONE) { | 1086 if (modules_to_enable != PROFILER_MODULE_NONE) { |
1085 is_logging_ = true; | 1087 is_logging_ = true; |
1086 } | 1088 } |
1087 if (modules_to_enable & PROFILER_MODULE_CPU) { | 1089 if (modules_to_enable & PROFILER_MODULE_CPU) { |
1088 if (FLAG_prof_lazy) { | 1090 if (FLAG_prof_lazy) { |
1089 profiler_->Engage(); | 1091 profiler_->Engage(); |
1090 LOG(UncheckedStringEvent("profiler", "resume")); | 1092 LOG(UncheckedStringEvent("profiler", "resume")); |
1091 FLAG_log_code = true; | 1093 FLAG_log_code = true; |
1092 LogCompiledFunctions(); | 1094 LogCompiledFunctions(); |
1093 LogCallbacks(); | |
1094 if (!FLAG_sliding_state_window) ticker_->Start(); | 1095 if (!FLAG_sliding_state_window) ticker_->Start(); |
1095 } | 1096 } |
1096 profiler_->resume(); | 1097 profiler_->resume(); |
1097 } | 1098 } |
1098 if (modules_to_enable & | 1099 if (modules_to_enable & |
1099 (PROFILER_MODULE_HEAP_STATS | PROFILER_MODULE_JS_CONSTRUCTORS)) { | 1100 (PROFILER_MODULE_HEAP_STATS | PROFILER_MODULE_JS_CONSTRUCTORS)) { |
1100 FLAG_log_gc = true; | 1101 FLAG_log_gc = true; |
1101 } | 1102 } |
1102 } | 1103 } |
1103 | 1104 |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1204 int line_num = GetScriptLineNumber(script, shared->start_position()); | 1205 int line_num = GetScriptLineNumber(script, shared->start_position()); |
1205 if (line_num > 0) { | 1206 if (line_num > 0) { |
1206 LOG(CodeCreateEvent(Logger::LAZY_COMPILE_TAG, | 1207 LOG(CodeCreateEvent(Logger::LAZY_COMPILE_TAG, |
1207 shared->code(), *func_name, | 1208 shared->code(), *func_name, |
1208 *script_name, line_num + 1)); | 1209 *script_name, line_num + 1)); |
1209 } else { | 1210 } else { |
1210 // Can't distinguish enum and script here, so always use Script. | 1211 // Can't distinguish enum and script here, so always use Script. |
1211 LOG(CodeCreateEvent(Logger::SCRIPT_TAG, | 1212 LOG(CodeCreateEvent(Logger::SCRIPT_TAG, |
1212 shared->code(), *script_name)); | 1213 shared->code(), *script_name)); |
1213 } | 1214 } |
1214 continue; | 1215 } else { |
| 1216 LOG(CodeCreateEvent( |
| 1217 Logger::LAZY_COMPILE_TAG, shared->code(), *func_name)); |
1215 } | 1218 } |
| 1219 } else if (shared->function_data()->IsFunctionTemplateInfo()) { |
| 1220 // API function. |
| 1221 FunctionTemplateInfo* fun_data = |
| 1222 FunctionTemplateInfo::cast(shared->function_data()); |
| 1223 Object* raw_call_data = fun_data->call_code(); |
| 1224 if (!raw_call_data->IsUndefined()) { |
| 1225 CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data); |
| 1226 Object* callback_obj = call_data->callback(); |
| 1227 Address entry_point = v8::ToCData<Address>(callback_obj); |
| 1228 LOG(CallbackEvent(*func_name, entry_point)); |
| 1229 } |
| 1230 } else { |
| 1231 LOG(CodeCreateEvent( |
| 1232 Logger::LAZY_COMPILE_TAG, shared->code(), *func_name)); |
1216 } | 1233 } |
1217 // If no script or script has no name. | |
1218 LOG(CodeCreateEvent(Logger::LAZY_COMPILE_TAG, shared->code(), *func_name)); | |
1219 } | 1234 } |
1220 | 1235 |
1221 DeleteArray(sfis); | 1236 DeleteArray(sfis); |
1222 } | 1237 } |
1223 | 1238 |
1224 | |
1225 namespace { | |
1226 | |
1227 class FunctionTemplateInfosVisitor : public ObjectVisitor { | |
1228 public: | |
1229 virtual ~FunctionTemplateInfosVisitor() {} | |
1230 virtual void VisitPointers(Object** start, Object** end) { | |
1231 for (Object** p = start; p < end; ++p) { | |
1232 VisitFTI(*p); | |
1233 } | |
1234 } | |
1235 | |
1236 private: | |
1237 void VisitFTI(Object* o) { | |
1238 // The data about callbacks is in fact dynamically typed | |
1239 // (Object ptrs are used), so we use runtime type checking | |
1240 // to be sure that we retrieve the right thing. | |
1241 if (!o->IsFunctionTemplateInfo()) | |
1242 return; | |
1243 AssertNoAllocation no_alloc; | |
1244 FunctionTemplateInfo* fti = FunctionTemplateInfo::cast(o); | |
1245 if (!fti->prototype_template()->IsObjectTemplateInfo()) | |
1246 return; | |
1247 SmartPointer<char> class_name; | |
1248 if (fti->class_name()->IsString()) { | |
1249 class_name = String::cast(fti->class_name())-> | |
1250 ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); | |
1251 } | |
1252 ObjectTemplateInfo* proto = | |
1253 ObjectTemplateInfo::cast(fti->prototype_template()); | |
1254 NeanderArray props(Handle<Object>(proto->property_list())); | |
1255 // Properties are triples: [property name, entry point, attributes]. | |
1256 // See Template::Set in api.cc. | |
1257 for (int i = 0; i < props.length(); i += 3) { | |
1258 if (!props.get(i)->IsString() | |
1259 || !props.get(i + 1)->IsFunctionTemplateInfo()) | |
1260 continue; | |
1261 FunctionTemplateInfo* native_fti = | |
1262 FunctionTemplateInfo::cast(props.get(i + 1)); | |
1263 Object* raw_call_data = native_fti->call_code(); | |
1264 if (raw_call_data->IsUndefined()) | |
1265 continue; | |
1266 CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data); | |
1267 Object* callback_obj = call_data->callback(); | |
1268 Address entry_point = v8::ToCData<Address>(callback_obj); | |
1269 SmartPointer<char> method_name( | |
1270 String::cast(props.get(i))-> | |
1271 ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL)); | |
1272 LOG(CallbackEvent(*class_name, *method_name, entry_point)); | |
1273 } | |
1274 } | |
1275 }; | |
1276 | |
1277 } // anonymous namespace | |
1278 | |
1279 | |
1280 void Logger::LogCallbacks() { | |
1281 // We are looking for callbacks information exposed via persistent | |
1282 // FunctionTemplate objects. | |
1283 FunctionTemplateInfosVisitor visitor; | |
1284 GlobalHandles::IterateStrongRoots(&visitor); | |
1285 } | |
1286 | |
1287 #endif | 1239 #endif |
1288 | 1240 |
1289 | 1241 |
1290 bool Logger::Setup() { | 1242 bool Logger::Setup() { |
1291 #ifdef ENABLE_LOGGING_AND_PROFILING | 1243 #ifdef ENABLE_LOGGING_AND_PROFILING |
1292 // --log-all enables all the log flags. | 1244 // --log-all enables all the log flags. |
1293 if (FLAG_log_all) { | 1245 if (FLAG_log_all) { |
1294 FLAG_log_runtime = true; | 1246 FLAG_log_runtime = true; |
1295 FLAG_log_api = true; | 1247 FLAG_log_api = true; |
1296 FLAG_log_code = true; | 1248 FLAG_log_code = true; |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1438 // Otherwise, if the sliding state window computation has not been | 1390 // Otherwise, if the sliding state window computation has not been |
1439 // started we do it now. | 1391 // started we do it now. |
1440 if (sliding_state_window_ == NULL) { | 1392 if (sliding_state_window_ == NULL) { |
1441 sliding_state_window_ = new SlidingStateWindow(); | 1393 sliding_state_window_ = new SlidingStateWindow(); |
1442 } | 1394 } |
1443 #endif | 1395 #endif |
1444 } | 1396 } |
1445 | 1397 |
1446 | 1398 |
1447 } } // namespace v8::internal | 1399 } } // namespace v8::internal |
OLD | NEW |