OLD | NEW |
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. |
2 // | 2 // |
3 // Tests of logging functions from log.h | 3 // Tests of logging functions from log.h |
4 | 4 |
5 #ifdef ENABLE_LOGGING_AND_PROFILING | 5 #ifdef ENABLE_LOGGING_AND_PROFILING |
6 | 6 |
7 #ifdef __linux__ | 7 #ifdef __linux__ |
8 #include <math.h> | 8 #include <math.h> |
9 #include <pthread.h> | 9 #include <pthread.h> |
10 #include <signal.h> | 10 #include <signal.h> |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
163 | 163 |
164 static void SigProfSignalHandler(int signal, siginfo_t* info, void* context) { | 164 static void SigProfSignalHandler(int signal, siginfo_t* info, void* context) { |
165 if (signal != SIGPROF || !pthread_equal(pthread_self(), our_thread)) return; | 165 if (signal != SIGPROF || !pthread_equal(pthread_self(), our_thread)) return; |
166 was_sigprof_received = true; | 166 was_sigprof_received = true; |
167 old_sigprof_handler.sa_sigaction(signal, info, context); | 167 old_sigprof_handler.sa_sigaction(signal, info, context); |
168 } | 168 } |
169 | 169 |
170 #endif // __linux__ | 170 #endif // __linux__ |
171 | 171 |
172 | 172 |
173 static int CheckThatProfilerWorks(int log_pos) { | 173 namespace { |
174 Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU); | 174 |
| 175 class ScopedLoggerInitializer { |
| 176 public: |
| 177 explicit ScopedLoggerInitializer(bool log, bool prof_lazy) |
| 178 : saved_log_(i::FLAG_log), |
| 179 saved_prof_lazy_(i::FLAG_prof_lazy), |
| 180 saved_prof_(i::FLAG_prof), |
| 181 saved_prof_auto_(i::FLAG_prof_auto), |
| 182 trick_to_run_init_flags_(init_flags_(log, prof_lazy)), |
| 183 need_to_set_up_logger_(i::V8::IsRunning()), |
| 184 scope_(), |
| 185 env_(v8::Context::New()) { |
| 186 if (need_to_set_up_logger_) Logger::Setup(); |
| 187 env_->Enter(); |
| 188 } |
| 189 |
| 190 ~ScopedLoggerInitializer() { |
| 191 env_->Exit(); |
| 192 Logger::TearDown(); |
| 193 i::FLAG_prof_lazy = saved_prof_lazy_; |
| 194 i::FLAG_prof = saved_prof_; |
| 195 i::FLAG_prof_auto = saved_prof_auto_; |
| 196 i::FLAG_log = saved_log_; |
| 197 } |
| 198 |
| 199 v8::Handle<v8::Context>& env() { return env_; } |
| 200 |
| 201 private: |
| 202 static bool init_flags_(bool log, bool prof_lazy) { |
| 203 i::FLAG_log = log; |
| 204 i::FLAG_prof = true; |
| 205 i::FLAG_prof_lazy = prof_lazy; |
| 206 i::FLAG_prof_auto = false; |
| 207 i::FLAG_logfile = "*"; |
| 208 return prof_lazy; |
| 209 } |
| 210 |
| 211 const bool saved_log_; |
| 212 const bool saved_prof_lazy_; |
| 213 const bool saved_prof_; |
| 214 const bool saved_prof_auto_; |
| 215 const bool trick_to_run_init_flags_; |
| 216 const bool need_to_set_up_logger_; |
| 217 v8::HandleScope scope_; |
| 218 v8::Handle<v8::Context> env_; |
| 219 |
| 220 DISALLOW_COPY_AND_ASSIGN(ScopedLoggerInitializer); |
| 221 }; |
| 222 |
| 223 |
| 224 class LogBufferMatcher { |
| 225 public: |
| 226 LogBufferMatcher() { |
| 227 // Skip all initially logged stuff. |
| 228 log_pos_ = GetLogLines(0, &buffer_); |
| 229 } |
| 230 |
| 231 int log_pos() { return log_pos_; } |
| 232 |
| 233 int GetNextChunk() { |
| 234 int chunk_size = GetLogLines(log_pos_, &buffer_); |
| 235 CHECK_GT(buffer_.length(), chunk_size); |
| 236 buffer_[chunk_size] = '\0'; |
| 237 log_pos_ += chunk_size; |
| 238 return chunk_size; |
| 239 } |
| 240 |
| 241 const char* Find(const char* substr) { |
| 242 return strstr(buffer_.start(), substr); |
| 243 } |
| 244 |
| 245 const char* Find(const i::Vector<char>& substr) { |
| 246 return Find(substr.start()); |
| 247 } |
| 248 |
| 249 bool IsInSequence(const char* s1, const char* s2) { |
| 250 const char* s1_pos = Find(s1); |
| 251 const char* s2_pos = Find(s2); |
| 252 CHECK_NE(NULL, s1_pos); |
| 253 CHECK_NE(NULL, s2_pos); |
| 254 return s1_pos < s2_pos; |
| 255 } |
| 256 |
| 257 void PrintBuffer() { |
| 258 puts(buffer_.start()); |
| 259 } |
| 260 |
| 261 private: |
| 262 EmbeddedVector<char, 102400> buffer_; |
| 263 int log_pos_; |
| 264 }; |
| 265 |
| 266 } // namespace |
| 267 |
| 268 |
| 269 static void CheckThatProfilerWorks(LogBufferMatcher* matcher) { |
| 270 Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 0); |
175 CHECK(LoggerTestHelper::IsSamplerActive()); | 271 CHECK(LoggerTestHelper::IsSamplerActive()); |
176 | 272 |
177 // Verify that the current map of compiled functions has been logged. | 273 // Verify that the current map of compiled functions has been logged. |
178 EmbeddedVector<char, 102400> buffer; | 274 CHECK_GT(matcher->GetNextChunk(), 0); |
179 int map_log_size = GetLogLines(log_pos, &buffer); | |
180 printf("map_log_size: %d\n", map_log_size); | |
181 CHECK_GT(map_log_size, 0); | |
182 CHECK_GT(buffer.length(), map_log_size); | |
183 log_pos += map_log_size; | |
184 // Check buffer contents. | |
185 buffer[map_log_size] = '\0'; | |
186 const char* code_creation = "\ncode-creation,"; // eq. to /^code-creation,/ | 275 const char* code_creation = "\ncode-creation,"; // eq. to /^code-creation,/ |
187 CHECK_NE(NULL, strstr(buffer.start(), code_creation)); | 276 CHECK_NE(NULL, matcher->Find(code_creation)); |
188 | 277 |
189 #ifdef __linux__ | 278 #ifdef __linux__ |
190 // Intercept SIGPROF handler to make sure that the test process | 279 // Intercept SIGPROF handler to make sure that the test process |
191 // had received it. Under load, system can defer it causing test failure. | 280 // had received it. Under load, system can defer it causing test failure. |
192 // It is important to execute this after 'ResumeProfiler'. | 281 // It is important to execute this after 'ResumeProfiler'. |
193 our_thread = pthread_self(); | 282 our_thread = pthread_self(); |
194 was_sigprof_received = false; | 283 was_sigprof_received = false; |
195 struct sigaction sa; | 284 struct sigaction sa; |
196 sa.sa_sigaction = SigProfSignalHandler; | 285 sa.sa_sigaction = SigProfSignalHandler; |
197 sigemptyset(&sa.sa_mask); | 286 sigemptyset(&sa.sa_mask); |
198 sa.sa_flags = SA_SIGINFO; | 287 sa.sa_flags = SA_SIGINFO; |
199 CHECK_EQ(0, sigaction(SIGPROF, &sa, &old_sigprof_handler)); | 288 CHECK_EQ(0, sigaction(SIGPROF, &sa, &old_sigprof_handler)); |
200 #endif // __linux__ | 289 #endif // __linux__ |
201 | 290 |
202 // Force compiler to generate new code by parametrizing source. | 291 // Force compiler to generate new code by parametrizing source. |
203 EmbeddedVector<char, 100> script_src; | 292 EmbeddedVector<char, 100> script_src; |
204 i::OS::SNPrintF(script_src, | 293 i::OS::SNPrintF(script_src, |
205 "function f%d(x) { return %d * x; }" | 294 "function f%d(x) { return %d * x; }" |
206 "for (var i = 0; i < 10000; ++i) { f%d(i); }", | 295 "for (var i = 0; i < 10000; ++i) { f%d(i); }", |
207 log_pos, log_pos, log_pos); | 296 matcher->log_pos(), matcher->log_pos(), matcher->log_pos()); |
208 // Run code for 200 msecs to get some ticks. | 297 // Run code for 200 msecs to get some ticks. |
209 const double end_time = i::OS::TimeCurrentMillis() + 200; | 298 const double end_time = i::OS::TimeCurrentMillis() + 200; |
210 while (i::OS::TimeCurrentMillis() < end_time) { | 299 while (i::OS::TimeCurrentMillis() < end_time) { |
211 CompileAndRunScript(script_src.start()); | 300 CompileAndRunScript(script_src.start()); |
212 // Yield CPU to give Profiler thread a chance to process ticks. | 301 // Yield CPU to give Profiler thread a chance to process ticks. |
213 i::OS::Sleep(1); | 302 i::OS::Sleep(1); |
214 } | 303 } |
215 | 304 |
216 Logger::PauseProfiler(v8::PROFILER_MODULE_CPU); | 305 Logger::PauseProfiler(v8::PROFILER_MODULE_CPU, 0); |
217 CHECK(!LoggerTestHelper::IsSamplerActive()); | 306 CHECK(!LoggerTestHelper::IsSamplerActive()); |
218 | 307 |
219 // Wait 50 msecs to allow Profiler thread to process the last | 308 // Wait 50 msecs to allow Profiler thread to process the last |
220 // tick sample it has got. | 309 // tick sample it has got. |
221 i::OS::Sleep(50); | 310 i::OS::Sleep(50); |
222 | 311 |
223 // Now we must have compiler and tick records. | 312 // Now we must have compiler and tick records. |
224 int log_size = GetLogLines(log_pos, &buffer); | 313 CHECK_GT(matcher->GetNextChunk(), 0); |
225 printf("log_size: %d\n", log_size); | 314 matcher->PrintBuffer(); |
226 CHECK_GT(log_size, 0); | 315 CHECK_NE(NULL, matcher->Find(code_creation)); |
227 CHECK_GT(buffer.length(), log_size); | |
228 log_pos += log_size; | |
229 // Check buffer contents. | |
230 buffer[log_size] = '\0'; | |
231 printf("%s", buffer.start()); | |
232 const char* tick = "\ntick,"; | 316 const char* tick = "\ntick,"; |
233 CHECK_NE(NULL, strstr(buffer.start(), code_creation)); | 317 const bool ticks_found = matcher->Find(tick) != NULL; |
234 const bool ticks_found = strstr(buffer.start(), tick) != NULL; | |
235 CHECK_EQ(was_sigprof_received, ticks_found); | 318 CHECK_EQ(was_sigprof_received, ticks_found); |
236 | |
237 return log_pos; | |
238 } | 319 } |
239 | 320 |
240 | 321 |
241 TEST(ProfLazyMode) { | 322 TEST(ProfLazyMode) { |
242 const bool saved_prof_lazy = i::FLAG_prof_lazy; | 323 ScopedLoggerInitializer initialize_logger(false, true); |
243 const bool saved_prof = i::FLAG_prof; | |
244 const bool saved_prof_auto = i::FLAG_prof_auto; | |
245 i::FLAG_prof = true; | |
246 i::FLAG_prof_lazy = true; | |
247 i::FLAG_prof_auto = false; | |
248 i::FLAG_logfile = "*"; | |
249 | |
250 // If tests are being run manually, V8 will be already initialized | |
251 // by the bottom test. | |
252 const bool need_to_set_up_logger = i::V8::IsRunning(); | |
253 v8::HandleScope scope; | |
254 v8::Handle<v8::Context> env = v8::Context::New(); | |
255 if (need_to_set_up_logger) Logger::Setup(); | |
256 env->Enter(); | |
257 | 324 |
258 // No sampling should happen prior to resuming profiler. | 325 // No sampling should happen prior to resuming profiler. |
259 CHECK(!LoggerTestHelper::IsSamplerActive()); | 326 CHECK(!LoggerTestHelper::IsSamplerActive()); |
260 | 327 |
261 EmbeddedVector<char, 102400> buffer; | 328 LogBufferMatcher matcher; |
262 // Nothing must be logged until profiling is resumed. | 329 // Nothing must be logged until profiling is resumed. |
263 int log_pos = GetLogLines(0, &buffer); | 330 CHECK_EQ(0, matcher.log_pos()); |
264 CHECK_EQ(0, log_pos); | |
265 | 331 |
266 CompileAndRunScript("var a = (function(x) { return x + 1; })(10);"); | 332 CompileAndRunScript("var a = (function(x) { return x + 1; })(10);"); |
267 | 333 |
268 // Nothing must be logged while profiling is suspended. | 334 // Nothing must be logged while profiling is suspended. |
269 CHECK_EQ(0, GetLogLines(log_pos, &buffer)); | 335 CHECK_EQ(0, matcher.GetNextChunk()); |
270 | 336 |
271 log_pos = CheckThatProfilerWorks(log_pos); | 337 CheckThatProfilerWorks(&matcher); |
272 | 338 |
273 CompileAndRunScript("var a = (function(x) { return x + 1; })(10);"); | 339 CompileAndRunScript("var a = (function(x) { return x + 1; })(10);"); |
274 | 340 |
275 // No new data beyond last retrieved position. | 341 // No new data beyond last retrieved position. |
276 CHECK_EQ(0, GetLogLines(log_pos, &buffer)); | 342 CHECK_EQ(0, matcher.GetNextChunk()); |
277 | 343 |
278 // Check that profiling can be resumed again. | 344 // Check that profiling can be resumed again. |
279 CheckThatProfilerWorks(log_pos); | 345 CheckThatProfilerWorks(&matcher); |
280 | |
281 env->Exit(); | |
282 Logger::TearDown(); | |
283 i::FLAG_prof_lazy = saved_prof_lazy; | |
284 i::FLAG_prof = saved_prof; | |
285 i::FLAG_prof_auto = saved_prof_auto; | |
286 } | 346 } |
287 | 347 |
288 | 348 |
289 // Profiling multiple threads that use V8 is currently only available on Linux. | 349 // Profiling multiple threads that use V8 is currently only available on Linux. |
290 #ifdef __linux__ | 350 #ifdef __linux__ |
291 | 351 |
292 namespace { | 352 namespace { |
293 | 353 |
294 class LoopingThread : public v8::internal::Thread { | 354 class LoopingThread : public v8::internal::Thread { |
295 public: | 355 public: |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
473 // Must not crash. | 533 // Must not crash. |
474 i::Logger::LogCompiledFunctions(); | 534 i::Logger::LogCompiledFunctions(); |
475 } | 535 } |
476 | 536 |
477 | 537 |
478 static v8::Handle<v8::Value> ObjMethod1(const v8::Arguments& args) { | 538 static v8::Handle<v8::Value> ObjMethod1(const v8::Arguments& args) { |
479 return v8::Handle<v8::Value>(); | 539 return v8::Handle<v8::Value>(); |
480 } | 540 } |
481 | 541 |
482 TEST(LogCallbacks) { | 542 TEST(LogCallbacks) { |
483 const bool saved_prof_lazy = i::FLAG_prof_lazy; | 543 ScopedLoggerInitializer initialize_logger(false, false); |
484 const bool saved_prof = i::FLAG_prof; | 544 LogBufferMatcher matcher; |
485 const bool saved_prof_auto = i::FLAG_prof_auto; | |
486 i::FLAG_prof = true; | |
487 i::FLAG_prof_lazy = false; | |
488 i::FLAG_prof_auto = false; | |
489 i::FLAG_logfile = "*"; | |
490 | |
491 // If tests are being run manually, V8 will be already initialized | |
492 // by the bottom test. | |
493 const bool need_to_set_up_logger = i::V8::IsRunning(); | |
494 v8::HandleScope scope; | |
495 v8::Handle<v8::Context> env = v8::Context::New(); | |
496 if (need_to_set_up_logger) Logger::Setup(); | |
497 env->Enter(); | |
498 | |
499 // Skip all initially logged stuff. | |
500 EmbeddedVector<char, 102400> buffer; | |
501 int log_pos = GetLogLines(0, &buffer); | |
502 | 545 |
503 v8::Persistent<v8::FunctionTemplate> obj = | 546 v8::Persistent<v8::FunctionTemplate> obj = |
504 v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New()); | 547 v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New()); |
505 obj->SetClassName(v8::String::New("Obj")); | 548 obj->SetClassName(v8::String::New("Obj")); |
506 v8::Handle<v8::ObjectTemplate> proto = obj->PrototypeTemplate(); | 549 v8::Handle<v8::ObjectTemplate> proto = obj->PrototypeTemplate(); |
507 v8::Local<v8::Signature> signature = v8::Signature::New(obj); | 550 v8::Local<v8::Signature> signature = v8::Signature::New(obj); |
508 proto->Set(v8::String::New("method1"), | 551 proto->Set(v8::String::New("method1"), |
509 v8::FunctionTemplate::New(ObjMethod1, | 552 v8::FunctionTemplate::New(ObjMethod1, |
510 v8::Handle<v8::Value>(), | 553 v8::Handle<v8::Value>(), |
511 signature), | 554 signature), |
512 static_cast<v8::PropertyAttribute>(v8::DontDelete)); | 555 static_cast<v8::PropertyAttribute>(v8::DontDelete)); |
513 | 556 |
514 env->Global()->Set(v8_str("Obj"), obj->GetFunction()); | 557 initialize_logger.env()->Global()->Set(v8_str("Obj"), obj->GetFunction()); |
515 CompileAndRunScript("Obj.prototype.method1.toString();"); | 558 CompileAndRunScript("Obj.prototype.method1.toString();"); |
516 | 559 |
517 i::Logger::LogCompiledFunctions(); | 560 i::Logger::LogCompiledFunctions(); |
518 log_pos = GetLogLines(log_pos, &buffer); | 561 CHECK_GT(matcher.GetNextChunk(), 0); |
519 CHECK_GT(log_pos, 0); | |
520 buffer[log_pos] = 0; | |
521 | 562 |
522 const char* callback_rec = "code-creation,Callback,"; | 563 const char* callback_rec = "code-creation,Callback,"; |
523 char* pos = strstr(buffer.start(), callback_rec); | 564 char* pos = const_cast<char*>(matcher.Find(callback_rec)); |
524 CHECK_NE(NULL, pos); | 565 CHECK_NE(NULL, pos); |
525 pos += strlen(callback_rec); | 566 pos += strlen(callback_rec); |
526 EmbeddedVector<char, 100> ref_data; | 567 EmbeddedVector<char, 100> ref_data; |
527 i::OS::SNPrintF(ref_data, | 568 i::OS::SNPrintF(ref_data, |
528 "0x%" V8PRIxPTR ",1,\"method1\"", ObjMethod1); | 569 "0x%" V8PRIxPTR ",1,\"method1\"", ObjMethod1); |
529 *(pos + strlen(ref_data.start())) = '\0'; | 570 *(pos + strlen(ref_data.start())) = '\0'; |
530 CHECK_EQ(ref_data.start(), pos); | 571 CHECK_EQ(ref_data.start(), pos); |
531 | 572 |
532 obj.Dispose(); | 573 obj.Dispose(); |
533 | |
534 env->Exit(); | |
535 Logger::TearDown(); | |
536 i::FLAG_prof_lazy = saved_prof_lazy; | |
537 i::FLAG_prof = saved_prof; | |
538 i::FLAG_prof_auto = saved_prof_auto; | |
539 } | 574 } |
540 | 575 |
541 | 576 |
542 static v8::Handle<v8::Value> Prop1Getter(v8::Local<v8::String> property, | 577 static v8::Handle<v8::Value> Prop1Getter(v8::Local<v8::String> property, |
543 const v8::AccessorInfo& info) { | 578 const v8::AccessorInfo& info) { |
544 return v8::Handle<v8::Value>(); | 579 return v8::Handle<v8::Value>(); |
545 } | 580 } |
546 | 581 |
547 static void Prop1Setter(v8::Local<v8::String> property, | 582 static void Prop1Setter(v8::Local<v8::String> property, |
548 v8::Local<v8::Value> value, | 583 v8::Local<v8::Value> value, |
549 const v8::AccessorInfo& info) { | 584 const v8::AccessorInfo& info) { |
550 } | 585 } |
551 | 586 |
552 static v8::Handle<v8::Value> Prop2Getter(v8::Local<v8::String> property, | 587 static v8::Handle<v8::Value> Prop2Getter(v8::Local<v8::String> property, |
553 const v8::AccessorInfo& info) { | 588 const v8::AccessorInfo& info) { |
554 return v8::Handle<v8::Value>(); | 589 return v8::Handle<v8::Value>(); |
555 } | 590 } |
556 | 591 |
557 TEST(LogAccessorCallbacks) { | 592 TEST(LogAccessorCallbacks) { |
558 const bool saved_prof_lazy = i::FLAG_prof_lazy; | 593 ScopedLoggerInitializer initialize_logger(false, false); |
559 const bool saved_prof = i::FLAG_prof; | 594 LogBufferMatcher matcher; |
560 const bool saved_prof_auto = i::FLAG_prof_auto; | |
561 i::FLAG_prof = true; | |
562 i::FLAG_prof_lazy = false; | |
563 i::FLAG_prof_auto = false; | |
564 i::FLAG_logfile = "*"; | |
565 | |
566 // If tests are being run manually, V8 will be already initialized | |
567 // by the bottom test. | |
568 const bool need_to_set_up_logger = i::V8::IsRunning(); | |
569 v8::HandleScope scope; | |
570 v8::Handle<v8::Context> env = v8::Context::New(); | |
571 if (need_to_set_up_logger) Logger::Setup(); | |
572 env->Enter(); | |
573 | |
574 // Skip all initially logged stuff. | |
575 EmbeddedVector<char, 102400> buffer; | |
576 int log_pos = GetLogLines(0, &buffer); | |
577 | 595 |
578 v8::Persistent<v8::FunctionTemplate> obj = | 596 v8::Persistent<v8::FunctionTemplate> obj = |
579 v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New()); | 597 v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New()); |
580 obj->SetClassName(v8::String::New("Obj")); | 598 obj->SetClassName(v8::String::New("Obj")); |
581 v8::Handle<v8::ObjectTemplate> inst = obj->InstanceTemplate(); | 599 v8::Handle<v8::ObjectTemplate> inst = obj->InstanceTemplate(); |
582 inst->SetAccessor(v8::String::New("prop1"), Prop1Getter, Prop1Setter); | 600 inst->SetAccessor(v8::String::New("prop1"), Prop1Getter, Prop1Setter); |
583 inst->SetAccessor(v8::String::New("prop2"), Prop2Getter); | 601 inst->SetAccessor(v8::String::New("prop2"), Prop2Getter); |
584 | 602 |
585 i::Logger::LogAccessorCallbacks(); | 603 i::Logger::LogAccessorCallbacks(); |
586 log_pos = GetLogLines(log_pos, &buffer); | 604 CHECK_GT(matcher.GetNextChunk(), 0); |
587 CHECK_GT(log_pos, 0); | 605 matcher.PrintBuffer(); |
588 buffer[log_pos] = 0; | |
589 printf("%s", buffer.start()); | |
590 | 606 |
591 EmbeddedVector<char, 100> prop1_getter_record; | 607 EmbeddedVector<char, 100> prop1_getter_record; |
592 i::OS::SNPrintF(prop1_getter_record, | 608 i::OS::SNPrintF(prop1_getter_record, |
593 "code-creation,Callback,0x%" V8PRIxPTR ",1,\"get prop1\"", | 609 "code-creation,Callback,0x%" V8PRIxPTR ",1,\"get prop1\"", |
594 Prop1Getter); | 610 Prop1Getter); |
595 CHECK_NE(NULL, strstr(buffer.start(), prop1_getter_record.start())); | 611 CHECK_NE(NULL, matcher.Find(prop1_getter_record)); |
596 EmbeddedVector<char, 100> prop1_setter_record; | 612 EmbeddedVector<char, 100> prop1_setter_record; |
597 i::OS::SNPrintF(prop1_setter_record, | 613 i::OS::SNPrintF(prop1_setter_record, |
598 "code-creation,Callback,0x%" V8PRIxPTR ",1,\"set prop1\"", | 614 "code-creation,Callback,0x%" V8PRIxPTR ",1,\"set prop1\"", |
599 Prop1Setter); | 615 Prop1Setter); |
600 CHECK_NE(NULL, strstr(buffer.start(), prop1_setter_record.start())); | 616 CHECK_NE(NULL, matcher.Find(prop1_setter_record)); |
601 EmbeddedVector<char, 100> prop2_getter_record; | 617 EmbeddedVector<char, 100> prop2_getter_record; |
602 i::OS::SNPrintF(prop2_getter_record, | 618 i::OS::SNPrintF(prop2_getter_record, |
603 "code-creation,Callback,0x%" V8PRIxPTR ",1,\"get prop2\"", | 619 "code-creation,Callback,0x%" V8PRIxPTR ",1,\"get prop2\"", |
604 Prop2Getter); | 620 Prop2Getter); |
605 CHECK_NE(NULL, strstr(buffer.start(), prop2_getter_record.start())); | 621 CHECK_NE(NULL, matcher.Find(prop2_getter_record)); |
606 | 622 |
607 obj.Dispose(); | 623 obj.Dispose(); |
608 | |
609 env->Exit(); | |
610 Logger::TearDown(); | |
611 i::FLAG_prof_lazy = saved_prof_lazy; | |
612 i::FLAG_prof = saved_prof; | |
613 i::FLAG_prof_auto = saved_prof_auto; | |
614 } | 624 } |
615 | 625 |
616 | 626 |
| 627 TEST(LogTags) { |
| 628 ScopedLoggerInitializer initialize_logger(true, false); |
| 629 LogBufferMatcher matcher; |
| 630 |
| 631 const char* open_tag = "open-tag,"; |
| 632 const char* close_tag = "close-tag,"; |
| 633 |
| 634 // Check compatibility with the old style behavior. |
| 635 CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules()); |
| 636 Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 0); |
| 637 CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules()); |
| 638 Logger::PauseProfiler(v8::PROFILER_MODULE_CPU, 0); |
| 639 CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules()); |
| 640 CHECK_EQ(NULL, matcher.Find(open_tag)); |
| 641 CHECK_EQ(NULL, matcher.Find(close_tag)); |
| 642 |
| 643 const char* open_tag1 = "open-tag,1\n"; |
| 644 const char* close_tag1 = "close-tag,1\n"; |
| 645 |
| 646 // Check non-nested tag case. |
| 647 CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules()); |
| 648 Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 1); |
| 649 CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules()); |
| 650 Logger::PauseProfiler(v8::PROFILER_MODULE_CPU, 1); |
| 651 CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules()); |
| 652 CHECK_GT(matcher.GetNextChunk(), 0); |
| 653 CHECK(matcher.IsInSequence(open_tag1, close_tag1)); |
| 654 |
| 655 const char* open_tag2 = "open-tag,2\n"; |
| 656 const char* close_tag2 = "close-tag,2\n"; |
| 657 |
| 658 // Check nested tags case. |
| 659 CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules()); |
| 660 Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 1); |
| 661 CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules()); |
| 662 Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 2); |
| 663 CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules()); |
| 664 Logger::PauseProfiler(v8::PROFILER_MODULE_CPU, 2); |
| 665 CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules()); |
| 666 Logger::PauseProfiler(v8::PROFILER_MODULE_CPU, 1); |
| 667 CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules()); |
| 668 CHECK_GT(matcher.GetNextChunk(), 0); |
| 669 // open_tag1 < open_tag2 < close_tag2 < close_tag1 |
| 670 CHECK(matcher.IsInSequence(open_tag1, open_tag2)); |
| 671 CHECK(matcher.IsInSequence(open_tag2, close_tag2)); |
| 672 CHECK(matcher.IsInSequence(close_tag2, close_tag1)); |
| 673 |
| 674 // Check overlapped tags case. |
| 675 CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules()); |
| 676 Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 1); |
| 677 CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules()); |
| 678 Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 2); |
| 679 CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules()); |
| 680 Logger::PauseProfiler(v8::PROFILER_MODULE_CPU, 1); |
| 681 CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules()); |
| 682 Logger::PauseProfiler(v8::PROFILER_MODULE_CPU, 2); |
| 683 CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules()); |
| 684 CHECK_GT(matcher.GetNextChunk(), 0); |
| 685 // open_tag1 < open_tag2 < close_tag1 < close_tag2 |
| 686 CHECK(matcher.IsInSequence(open_tag1, open_tag2)); |
| 687 CHECK(matcher.IsInSequence(open_tag2, close_tag1)); |
| 688 CHECK(matcher.IsInSequence(close_tag1, close_tag2)); |
| 689 |
| 690 const char* open_tag3 = "open-tag,3\n"; |
| 691 const char* close_tag3 = "close-tag,3\n"; |
| 692 |
| 693 // Check pausing overflow case. |
| 694 CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules()); |
| 695 Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 1); |
| 696 CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules()); |
| 697 Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 2); |
| 698 CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules()); |
| 699 Logger::PauseProfiler(v8::PROFILER_MODULE_CPU, 2); |
| 700 CHECK_EQ(v8::PROFILER_MODULE_CPU, Logger::GetActiveProfilerModules()); |
| 701 Logger::PauseProfiler(v8::PROFILER_MODULE_CPU, 1); |
| 702 CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules()); |
| 703 Logger::PauseProfiler(v8::PROFILER_MODULE_CPU, 3); |
| 704 CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules()); |
| 705 Logger::ResumeProfiler(v8::PROFILER_MODULE_CPU, 3); |
| 706 CHECK_EQ(v8::PROFILER_MODULE_NONE, Logger::GetActiveProfilerModules()); |
| 707 // Must be no tags, because logging must be disabled. |
| 708 CHECK_EQ(NULL, matcher.Find(open_tag3)); |
| 709 CHECK_EQ(NULL, matcher.Find(close_tag3)); |
| 710 } |
| 711 |
| 712 |
617 static inline bool IsStringEqualTo(const char* r, const char* s) { | 713 static inline bool IsStringEqualTo(const char* r, const char* s) { |
618 return strncmp(r, s, strlen(r)) == 0; | 714 return strncmp(r, s, strlen(r)) == 0; |
619 } | 715 } |
620 | 716 |
621 | 717 |
622 static bool Consume(const char* str, char** buf) { | 718 static bool Consume(const char* str, char** buf) { |
623 if (IsStringEqualTo(str, *buf)) { | 719 if (IsStringEqualTo(str, *buf)) { |
624 *buf += strlen(str); | 720 *buf += strlen(str); |
625 return true; | 721 return true; |
626 } | 722 } |
(...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1073 // Make sure that all log data is written prior crash due to CHECK failure. | 1169 // Make sure that all log data is written prior crash due to CHECK failure. |
1074 fflush(stdout); | 1170 fflush(stdout); |
1075 CHECK(results_equal); | 1171 CHECK(results_equal); |
1076 | 1172 |
1077 env->Exit(); | 1173 env->Exit(); |
1078 Logger::TearDown(); | 1174 Logger::TearDown(); |
1079 i::FLAG_always_compact = saved_always_compact; | 1175 i::FLAG_always_compact = saved_always_compact; |
1080 } | 1176 } |
1081 | 1177 |
1082 #endif // ENABLE_LOGGING_AND_PROFILING | 1178 #endif // ENABLE_LOGGING_AND_PROFILING |
OLD | NEW |